package org.biouno.databasesparql;

import java.io.IOException;
import java.sql.Driver;
import java.sql.DriverPropertyInfo;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.jena.jdbc.tdb.TDBDriver;
import org.jenkinsci.plugins.database.AbstractRemoteDatabase;
import org.jenkinsci.plugins.database.AbstractRemoteDatabaseDescriptor;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;

import hudson.Extension;
import hudson.Util;
import hudson.util.FormValidation;
import hudson.util.Secret;

public class JenaTDBDatabase extends AbstractRemoteDatabase {

    /**
     * Define whether the TDB database must exist beforehand or not. Defaults to
     * {@code false}.
     */
    private final Boolean mustExist;

    private final String location;

    @DataBoundConstructor
    public JenaTDBDatabase(String location, Boolean mustExist) {
        super("", "", "", Secret.fromString(""), "");
        this.location = StringUtils.defaultIfBlank(location, "");
        this.mustExist = BooleanUtils.toBooleanDefaultIfNull(mustExist, Boolean.FALSE);
    }

    @Override
    protected Class<? extends Driver> getDriverClass() {
        return TDBDriver.class;
    }

    @Override
    protected String getJdbcUrl() {
        return String.format("jdbc:jena:tdb:location=%s&must-exist=%s", location, mustExist.toString());
    }

    @Extension
    public static class DescriptorImpl extends AbstractRemoteDatabaseDescriptor {
        @Override
        public String getDisplayName() {
            return "SPARQL TDB";
        }

        public FormValidation doCheckProperties(@QueryParameter String properties) throws IOException {
            try {
                Set<String> validPropertyNames = new HashSet<String>();
                Properties props = Util.loadProperties(properties);
                for (DriverPropertyInfo p : new Driver().getPropertyInfo("jdbc:postgresql://localhost/dummy", props)) {
                    validPropertyNames.add(p.name);
                }

                for (Map.Entry e : props.entrySet()) {
                    String key = e.getKey().toString();
                    if (!validPropertyNames.contains(key))
                        return FormValidation.error("Unrecognized property: " + key);
                }
                return FormValidation.ok();
            } catch (Throwable e) {
                return FormValidation.warning(e, "Failed to validate the connection properties");
            }
        }
    }

}

@@ -45,13 +45,37 @@
 ava.
-io.IO
+lang.reflect.InvocationTarget
 Exce
@@ -97,22 +97,26 @@
 ava.sql.
-Driver
+Connection
 ;%0Aimport
@@ -131,28 +131,16 @@
 l.Driver
-PropertyInfo
 ;%0Aimport
@@ -149,44 +149,27 @@
 ava.
-util.HashSet;%0Aimport java.util.Map
+sql.SQLException
 ;%0A
+%0A
 impo
@@ -179,46 +179,24 @@
 java
-.util.Properties;%0Aimport java.util.Set
+x.sql.DataSource
 ;%0A%0Ai
@@ -458,24 +458,72 @@
 Descriptor;%0A
+import org.jenkinsci.plugins.database.Database;%0A
 import org.k
@@ -632,28 +632,8 @@
 on;%0A
-import hudson.Util;%0A
 impo
@@ -1761,23 +1761,16 @@
 n do
-CheckProperties
+Validate
 (@Qu
@@ -1793,130 +1793,52 @@
 ing 
-properties) throws IOException %7B%0A            try %7B%0A                Set%3CString%3E validPropertyNames = new HashSet%3CString%3E();
+location, @QueryParameter Boolean mustExist)
 %0A   
@@ -1854,231 +1854,130 @@
     
-Properties props = Util.loadProperties(properties);%0A                for (DriverPropertyInfo p : new Driver().getPropertyInfo(%22jdbc:postgresql://localhost/dummy%22, props)) %7B%0A                    validPropertyNames.add(p.name);
+throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,%0A                InstantiationException %7B%0A
 %0A   
@@ -1981,30 +1981,29 @@
             
-    %7D%0A
+try %7B
 %0A           
@@ -2011,46 +2011,104 @@
     
-for (Map.Entry e : props.entrySet()) %7B
+Database db = clazz.getConstructor(String.class, String.class).newInstance(location, mustExist);
 %0A   
@@ -2124,44 +2124,40 @@
     
-    String key = e
+DataSource ds = db
 .get
-Key().toString
+DataSource
 ();%0A
@@ -2176,134 +2176,127 @@
     
-    if (!validPropertyNames.contains(key))%0A                        return FormValidation.error(%22Unrecognized property: %22 + key
+Connection con = ds.getConnection();%0A                con.createStatement().execute(%22SELECT ?a ?b ?c WHERE %7B ?a ?b ?c %7D%22
 );%0A 
@@ -2302,33 +2302,44 @@
                 
-%7D
+con.close();
 %0A               
@@ -2364,16 +2364,20 @@
 tion.ok(
+%22OK%22
 );%0A     
@@ -2396,17 +2396,20 @@
 ch (
-Throwable
+SQLException
  e) 
@@ -2452,15 +2452,13 @@
 ion.
-warning
+error
 (e, 
@@ -2472,43 +2472,39 @@
  to 
-validate the connection properties%22
+connect to %22 + getDisplayName()
 );%0A 
@@ -2512,24 +2512,25 @@
           %7D%0A
+%0A
         %7D%0A  

Fix validate method