You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2013/04/26 02:09:16 UTC

svn commit: r1476003 - in /jena/Experimental/jena-jdbc: ./ jena-jdbc-core/ jena-jdbc-core/src/main/java/ jena-jdbc-core/src/main/java/org/apache/jena/jdbc/ jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/ jena-jdbc-core/src/main/resources...

Author: rvesse
Date: Fri Apr 26 00:09:14 2013
New Revision: 1476003

URL: http://svn.apache.org/r1476003
Log:
More metadata improvements, start to add proper logging support

Added:
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/MethodTraceLogger.aj
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/resources/jena-jdbc-log4j.properties
    jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestMemDriverWithLogging.java
Modified:
    jena/Experimental/jena-jdbc/   (props changed)
    jena/Experimental/jena-jdbc/jena-jdbc-core/   (props changed)
    jena/Experimental/jena-jdbc/jena-jdbc-core/pom.xml
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java
    jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/   (props changed)
    jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/main/java/org/apache/jena/jdbc/mem/connections/MemConnection.java
    jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/RemoteEndpointDriver.java
    jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/connections/RemoteEndpointConnection.java
    jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/metadata/RemoteEndpointMetadata.java
    jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/main/java/org/apache/jena/jdbc/tdb/connections/TDBConnection.java
    jena/Experimental/jena-jdbc/pom.xml

Propchange: jena/Experimental/jena-jdbc/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Apr 26 00:09:14 2013
@@ -1,3 +1,4 @@
 .settings
 .project
 src
+*.log

Propchange: jena/Experimental/jena-jdbc/jena-jdbc-core/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Apr 26 00:09:14 2013
@@ -3,3 +3,4 @@
 .project
 target
 test-output
+*.log

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/pom.xml
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/pom.xml?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/pom.xml (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/pom.xml Fri Apr 26 00:09:14 2013
@@ -39,6 +39,13 @@
 					<include>org/apache/jena/jdbc/jdbc-properties.xml</include>
 				</includes>
 			</resource>
+			<resource>
+				<filtering>false</filtering>
+				<directory>src/main/resources</directory>
+				<excludes>
+					<exclude>org/apache/jena/jdbc/jdbc-properties.xml</exclude>
+				</excludes>
+			</resource>
 		</resources>
 		<plugins>
 			<!-- JAR plugin so we build tests JAR -->

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/MethodTraceLogger.aj
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/MethodTraceLogger.aj?rev=1476003&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/MethodTraceLogger.aj (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/MethodTraceLogger.aj Fri Apr 26 00:09:14 2013
@@ -0,0 +1,90 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This AspectJ aspect is responsible for telling us when our methods are
+ * entered and exit. It is used to log trace level events on method entry and
+ * exit which are useful when debugging JDBC drivers to see why some
+ * functionality does not work as expected
+ * <p>
+ * Importantly this must not be in the affected package
+ * <strong>org.apache.jena.jdbc</strong> as otherwise we will get a nasty
+ * infinite stack recursion with it trying to log its own method entries and
+ * exits.
+ * </p>
+ * 
+ */
+public aspect MethodTraceLogger {
+    private static final Logger LOGGER = LoggerFactory.getLogger(MethodTraceLogger.class);
+
+    private static final int CLIENT_CODE_STACK_INDEX;
+
+    static {
+        // Finds out the index of "this code" in the returned stack trace -
+        // funny but it differs in JDK 1.5 and 1.6
+        int i = 0;
+        for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
+            i++;
+            if (ste.getClassName().equals(MethodTraceLogger.class.getName())) {
+                break;
+            }
+        }
+        CLIENT_CODE_STACK_INDEX = i;
+    }
+
+    /**
+     * Select all packages whose correctness is not impacted by the advice.
+     * Determined empirically
+     */
+    pointcut safePkg() :
+        execution( * org.apache.jena.jdbc..*(..))
+;
+
+    before(): safePkg() {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("Jena JDBC Method Entry: {} ", MethodTraceLogger.fullyQualifiedMethodName());
+    } // end Advice
+
+    after(): safePkg() {
+        if (LOGGER.isTraceEnabled())
+            LOGGER.trace("Jena JDBC Method Exit: {} ", MethodTraceLogger.fullyQualifiedMethodName());
+    }
+
+    /**
+     * Gets the fully qualified method name of the calling method via inspection
+     * of the current threads stack
+     * 
+     * @return Method Name or null if not determinable
+     */
+    public static String fullyQualifiedMethodName() {
+        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
+        if (stack.length <= CLIENT_CODE_STACK_INDEX + 1) {
+            // If the stack is this length then we have been called directly not
+            // from another method so can't return anything
+            return null;
+        }
+        // The current method will be at element 0 so our calling method will be
+        // at element 1
+        StackTraceElement element = stack[CLIENT_CODE_STACK_INDEX + 1];
+        return element.getClassName() + "." + element.getMethodName() + "() from " + element.getFileName() + " Line "
+                + element.getLineNumber();
+    }
+}

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/JenaDriver.java Fri Apr 26 00:09:14 2013
@@ -18,6 +18,9 @@
 
 package org.apache.jena.jdbc;
 
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.sql.Connection;
 import java.sql.Driver;
 import java.sql.DriverPropertyInfo;
@@ -31,6 +34,9 @@ import java.util.Properties;
 import org.apache.jena.atlas.lib.StrUtils;
 import org.apache.jena.jdbc.connections.JenaConnection;
 import org.apache.jena.jdbc.preprocessing.CommandPreProcessor;
+import org.apache.log4j.PropertyConfigurator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * <p>
@@ -106,6 +112,8 @@ import org.apache.jena.jdbc.preprocessin
  * </p>
  */
 public abstract class JenaDriver implements Driver {
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(JenaDriver.class);
 
     /**
      * Constant for the primary Jena JDBC Driver prefix, implementations supply
@@ -145,6 +153,29 @@ public abstract class JenaDriver impleme
      */
     public static final String PARAM_PASSWORD = "password";
 
+    /**
+     * Constant for the connection URL parameter used to set the path to a log4j
+     * properties file used to configure logging. When set to a file the file
+     * system is searched before the class path (since on the class path you are
+     * more likely to have duplicates particularly if using a standard name like
+     * <strong>log4j.properties</strong>).
+     * <p>
+     * When not set this defaults to the special value <strong>no-auto</strong>
+     * provided by the constant {@link #NO_AUTO_LOGGING_CONFIGURATION} that
+     * indicates that the driver should not configure any logging. This is
+     * useful if you want to have your application managed its own
+     * configuration.
+     * </p>
+     */
+    public static final String PARAM_LOGGING = "logging";
+
+    /**
+     * Constant for the special value used with the {@link #PARAM_LOGGING}
+     * parameter to indicate that the user code will manage configuration of
+     * logging.  This is also the default value when that parameter is not set.
+     */
+    public static final String NO_AUTO_LOGGING_CONFIGURATION = "no-auto";
+
     private int majorVer, minorVer;
     private String implPrefix;
 
@@ -192,6 +223,32 @@ public abstract class JenaDriver impleme
         // Compute the effective properties
         Properties ps = this.getEffectiveProperties(url, props);
 
+        // Configure logging appropriately
+        String logConfig = ps.getProperty(PARAM_LOGGING);
+        if (logConfig == null || logConfig.trim().length() == 0) {
+            logConfig = NO_AUTO_LOGGING_CONFIGURATION;
+        }
+        
+        // Unless set to no configuration (which is the default attempt to configure)
+        if (!logConfig.equals(NO_AUTO_LOGGING_CONFIGURATION)) {
+            // Search file system first
+            File logConfigFile = new File(logConfig);
+            if (logConfigFile.exists() && logConfigFile.isFile()) {
+                PropertyConfigurator.configure(logConfig);
+                LOGGER.info("Successfully configured logging using log file " + logConfigFile.getAbsolutePath());
+            } else {
+                // Otherwise try class path
+                URL logURL = this.getClass().getResource(logConfig);
+                if (logURL != null)
+                {
+                    PropertyConfigurator.configure(logURL);
+                    LOGGER.info("Successfully configured logging using class path resource " + logConfig);
+                } else {
+                    throw new SQLException("Unable to locate the specified log4j configuration file on either the file system or the class path");
+                }
+            }
+        }
+
         // Figure out desired JDBC compatibility level
         int compatibilityLevel = JdbcCompatibility.parseLevel(ps.get(PARAM_JDBC_COMPATIBILITY));
 
@@ -481,6 +538,12 @@ public abstract class JenaDriver impleme
         preProcessor.required = false;
         baseProps.add(preProcessor);
 
+        // Logging config
+        DriverPropertyInfo logging = new DriverPropertyInfo(PARAM_LOGGING, ps.getProperty(PARAM_LOGGING));
+        logging.description = "Sets the path to a log4j properties file for configuring logging, the file system is considered first and then the classpath.  If not set defaults to log4j.properties";
+        logging.required = false;
+        baseProps.add(logging);
+
         // Have the derived implementation create the final property information
         return this.getPropertyInfo(ps, baseProps);
     }

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java Fri Apr 26 00:09:14 2013
@@ -46,6 +46,8 @@ import org.apache.jena.jdbc.JdbcCompatib
 import org.apache.jena.jdbc.metadata.JenaMetadata;
 import org.apache.jena.jdbc.preprocessing.CommandPreProcessor;
 import org.apache.jena.jdbc.statements.JenaStatement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.hp.hpl.jena.query.Query;
 import com.hp.hpl.jena.update.UpdateRequest;
@@ -74,6 +76,8 @@ import com.hp.hpl.jena.update.UpdateRequ
  * </p>
  */
 public abstract class JenaConnection implements Connection {
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(JenaConnection.class);
 
     /**
      * Constant for default cursor holdability for Jena JDBC connections
@@ -270,18 +274,21 @@ public abstract class JenaConnection imp
     @Override
     public final void close() throws SQLException {
         try {
+            LOGGER.info("Closing connection...");
             // Close any open statements
             this.closeStatements();
         } finally {
             this.closeInternal();
+            LOGGER.info("Connection was closed");
         }
     }
 
     private void closeStatements() throws SQLException {
-
+        LOGGER.info("Attempting to close " + this.statements.size() + " open statements");
         for (Statement stmt : this.statements) {
             stmt.close();
         }
+        LOGGER.info("All open statements were closed");
         this.statements.clear();
     }
 
@@ -291,12 +298,17 @@ public abstract class JenaConnection imp
     public void commit() throws SQLException {
         if (this.isClosed())
             throw new SQLException("Cannot commit on a closed connection");
-        try {
+        try {            
+            LOGGER.info("Attempting to commit a transaction...");
+            
             // Get the implementation to do the actual commit
             this.commitInternal();
+            
+            LOGGER.info("Transaction was committed");
 
             // If applicable close cursors
             if (this.holdability == ResultSet.CLOSE_CURSORS_AT_COMMIT) {
+                LOGGER.info("Holdability set to CLOSE_CURSORS_AT_COMMIT so closing open statements");
                 this.closeStatements();
             }
         } catch (SQLException e) {
@@ -304,6 +316,7 @@ public abstract class JenaConnection imp
             throw e;
         } catch (Exception e) {
             // Wrap as SQLException
+            LOGGER.error("Unexpected error in transaction commit", e);
             throw new SQLException("Unexpected error committing transaction", e);
         }
     }
@@ -470,11 +483,16 @@ public abstract class JenaConnection imp
         if (this.isClosed())
             throw new SQLException("Cannot rollback on a closed connection");
         try {
+            LOGGER.info("Attempting to rollback a transaction...");
+            
             // Get the implementation to do the actual rollback
             this.rollbackInternal();
+            
+            LOGGER.info("Transaction was rolled back");
 
             // Close any open statements if applicable
             if (this.holdability == ResultSet.CLOSE_CURSORS_AT_COMMIT) {
+                LOGGER.info("Holdability is set to CLOSE_CURSORS_AT_COMMIT so closing open statements");
                 this.closeStatements();
             }
         } catch (SQLException e) {
@@ -580,6 +598,8 @@ public abstract class JenaConnection imp
      *            Warning
      */
     protected void setWarning(SQLWarning warning) {
+        LOGGER.warn(warning.getMessage(), warning);
+        
         if (this.warnings == null) {
             this.warnings = warning;
         } else {

Added: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/resources/jena-jdbc-log4j.properties
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/resources/jena-jdbc-log4j.properties?rev=1476003&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/resources/jena-jdbc-log4j.properties (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/resources/jena-jdbc-log4j.properties Fri Apr 26 00:09:14 2013
@@ -0,0 +1,22 @@
+log4j.rootLogger=ALL,stdlog,jdbc
+
+log4j.appender.stdlog=org.apache.log4j.ConsoleAppender
+log4j.appender.stdlog.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdlog.layout.ConversionPattern=%d{HH:mm:ss} %-5p %-25c{1} :: %m%n
+
+log4j.appender.jdbc=org.apache.log4j.FileAppender
+log4j.appender.jdbc.Threshold=ALL
+log4j.appender.jdbc.File=jena-jdbc.log
+log4j.appender.jdbc.layout=org.apache.log4j.PatternLayout
+log4j.appender.jdbc.layout.ConversionPattern=%d{HH:mm:ss} %-5p %-25c{1} :: %m%n
+
+# Jena Dependency log levels
+log4j.logger.com.hp.hpl.jena.arq.info=INFO
+log4j.logger.com.hp.hpl.jena.arq.exec=INFO
+log4j.logger.com.hp.hpl.jena=WARN
+log4j.logger.org.apache.jena=WARN
+log4j.logger.org.apache.jena.riot=INFO
+
+# Jena JDBC log levels
+log4j.logger.org.apache.jena.jdbc=ALL
+

Propchange: jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Apr 26 00:09:14 2013
@@ -2,3 +2,4 @@
 .settings
 .project
 target
+*.log

Modified: jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/main/java/org/apache/jena/jdbc/mem/connections/MemConnection.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/main/java/org/apache/jena/jdbc/mem/connections/MemConnection.java?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/main/java/org/apache/jena/jdbc/mem/connections/MemConnection.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/main/java/org/apache/jena/jdbc/mem/connections/MemConnection.java Fri Apr 26 00:09:14 2013
@@ -33,6 +33,8 @@ import com.hp.hpl.jena.query.Dataset;
  */
 public class MemConnection extends DatasetConnection {
 
+    private DatabaseMetaData metadata;
+    
     /**
      * Creates a new connection
      * 
@@ -52,10 +54,11 @@ public class MemConnection extends Datas
     public MemConnection(Dataset ds, int holdability, boolean autoCommit, int transactionLevel, int compatibilityLevel)
             throws SQLException {
         super(ds, holdability, autoCommit, transactionLevel, compatibilityLevel);
+        this.metadata = new MemDatasetMetadata(this);
     }
 
     @Override
     public DatabaseMetaData getMetaData() throws SQLException {
-        return new MemDatasetMetadata(this);
+        return this.metadata;
     }
 }

Added: jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestMemDriverWithLogging.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestMemDriverWithLogging.java?rev=1476003&view=auto
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestMemDriverWithLogging.java (added)
+++ jena/Experimental/jena-jdbc/jena-jdbc-driver-mem/src/test/java/org/apache/jena/jdbc/mem/TestMemDriverWithLogging.java Fri Apr 26 00:09:14 2013
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.jdbc.mem;
+
+import org.apache.jena.jdbc.AbstractJenaDriverTests;
+import org.apache.jena.jdbc.JenaDriver;
+import org.apache.log4j.BasicConfigurator;
+import org.junit.AfterClass;
+
+/**
+ * Tests for the {@link MemDriver}
+ *
+ */
+public class TestMemDriverWithLogging extends AbstractJenaDriverTests {
+    
+    /**
+     * Resets logging configuration after these tests
+     */
+    @AfterClass
+    public static void teardown() {
+        BasicConfigurator.resetConfiguration();
+    }
+
+    @Override
+    protected JenaDriver getDriver() {
+        return new MemDriver();
+    }
+
+    @Override
+    protected String getConnectionUrl() {
+        return JenaDriver.DRIVER_PREFIX + MemDriver.MEM_DRIVER_PREFIX + MemDriver.PARAM_EMPTY + "=true&" + JenaDriver.PARAM_LOGGING + "=/jena-jdbc-log4j.properties";
+    }
+
+    @Override
+    protected String getBadConnectionUrl() {
+        return JenaDriver.DRIVER_PREFIX + MemDriver.MEM_DRIVER_PREFIX + MemDriver.PARAM_EMPTY + "=false";
+    }
+}

Modified: jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/RemoteEndpointDriver.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/RemoteEndpointDriver.java?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/RemoteEndpointDriver.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/RemoteEndpointDriver.java Fri Apr 26 00:09:14 2013
@@ -161,7 +161,9 @@ public class RemoteEndpointDriver extend
 
         // Authentication settings
         String user = props.getProperty(PARAM_USERNAME);
+        if (user != null && user.trim().length() == 0) user = null;
         String password = props.getProperty(PARAM_PASSWORD);
+        if (password != null && password.trim().length() == 0) password = null;
 
         // Create connection
         return new RemoteEndpointConnection(queryEndpoint, updateEndpoint, defaultGraphs, namedGraphs, usingGraphs,
@@ -195,15 +197,23 @@ public class RemoteEndpointDriver extend
         
         // Default Graph parameter
         driverProps[2] = new DriverPropertyInfo(PARAM_DEFAULT_GRAPH_URI, null);
+        driverProps[2].required = false;
+        driverProps[2].description = "Sets the URI for a default graph for queries, may be specified multiple times to specify multiple graphs which should form the default graph";
         
         // Named Graph parameter
         driverProps[3] = new DriverPropertyInfo(PARAM_NAMED_GRAPH_URI, null);
+        driverProps[3].required = false;
+        driverProps[3].description = "Sets the URI for a named graph for queries, may be specified multiple times to specify multiple named graphs which should be accessible";
         
         // Using Graph parameter
         driverProps[4] = new DriverPropertyInfo(PARAM_USING_GRAPH_URI, null);
+        driverProps[4].required = false;
+        driverProps[4].description = "Sets the URI for a default graph for updates, may be specified multiple times to specify multiple graphs which should form the default graph";
         
         // Using Named Graph parameter
         driverProps[5] = new DriverPropertyInfo(PARAM_USING_NAMED_GRAPH_URI, null);
+        driverProps[5].required = false;
+        driverProps[5].description = "Sets the URI for a named graph for updates, may be specified multiple times to specify multiple named graph which should be accessible";
         
         // User Name parameter
         driverProps[6] = new DriverPropertyInfo(PARAM_USERNAME, connProps.getProperty(PARAM_USERNAME));

Modified: jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/connections/RemoteEndpointConnection.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/connections/RemoteEndpointConnection.java?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/connections/RemoteEndpointConnection.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/connections/RemoteEndpointConnection.java Fri Apr 26 00:09:14 2013
@@ -47,6 +47,7 @@ public class RemoteEndpointConnection ex
     private List<String> usingNamedGraphUris;
     private String username;
     private char[] password;
+    private DatabaseMetaData metadata;
 
     /**
      * Creates a new dataset connection
@@ -108,6 +109,7 @@ public class RemoteEndpointConnection ex
         this.usingNamedGraphUris = usingNamedGraphUris;
         this.username = username;
         this.password = (password != null) ? password.toCharArray() : null;
+        this.metadata = new RemoteEndpointMetadata(this);
     }
 
     /**
@@ -242,7 +244,7 @@ public class RemoteEndpointConnection ex
 
     @Override
     public DatabaseMetaData getMetaData() throws SQLException {
-        return new RemoteEndpointMetadata(this);
+        return this.metadata;
     }
 
     @Override

Modified: jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/metadata/RemoteEndpointMetadata.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/metadata/RemoteEndpointMetadata.java?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/metadata/RemoteEndpointMetadata.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/metadata/RemoteEndpointMetadata.java Fri Apr 26 00:09:14 2013
@@ -49,9 +49,9 @@ public class RemoteEndpointMetadata exte
     }
 
     @Override
-    public boolean supportsTransactionIsolationLevel(int arg0) throws SQLException {
+    public boolean supportsTransactionIsolationLevel(int isolationLevel) throws SQLException {
         // No transactions supported for remote endpoints
-        switch (arg0) {
+        switch (isolationLevel) {
         case Connection.TRANSACTION_NONE:
             return true;
         default:
@@ -73,13 +73,13 @@ public class RemoteEndpointMetadata exte
 
     @Override
     public String getDatabaseProductName() throws SQLException {
-        return null;
+        return "";
     }
 
     @Override
     public String getDatabaseProductVersion() throws SQLException {
         // Underlying database is unknown
-        return null;
+        return "";
     }
 
     @Override
@@ -110,7 +110,11 @@ public class RemoteEndpointMetadata exte
     
     @Override
     public String getUserName() throws SQLException {
-        return this.remoteConn.getUserName();
+        if (this.remoteConn != null) {
+            return this.remoteConn.getUserName();
+        } else {
+            return null;
+        }
     }
 
     @Override

Modified: jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/main/java/org/apache/jena/jdbc/tdb/connections/TDBConnection.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/main/java/org/apache/jena/jdbc/tdb/connections/TDBConnection.java?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/main/java/org/apache/jena/jdbc/tdb/connections/TDBConnection.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-driver-tdb/src/main/java/org/apache/jena/jdbc/tdb/connections/TDBConnection.java Fri Apr 26 00:09:14 2013
@@ -34,6 +34,8 @@ import com.hp.hpl.jena.query.Dataset;
  */
 public class TDBConnection extends DatasetConnection {
 
+    private DatabaseMetaData metadata;
+    
     /**
      * Creates a new connection
      * @param ds Dataset
@@ -44,11 +46,12 @@ public class TDBConnection extends Datas
      */
     public TDBConnection(Dataset ds, int holdability, boolean autoCommit, int compatibilityLevel) throws SQLException {
         super(ds, holdability, autoCommit, Connection.TRANSACTION_SERIALIZABLE, compatibilityLevel);
+        this.metadata = new TDBDatasetMetadata(this);
     }
 
     @Override
     public DatabaseMetaData getMetaData() throws SQLException {
-        return new TDBDatasetMetadata(this);
+        return this.metadata;
     }
 
 

Modified: jena/Experimental/jena-jdbc/pom.xml
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/pom.xml?rev=1476003&r1=1476002&r2=1476003&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/pom.xml (original)
+++ jena/Experimental/jena-jdbc/pom.xml Fri Apr 26 00:09:14 2013
@@ -59,6 +59,7 @@
 					<aggregate>true</aggregate>
 					<excludes>
 						<exclude>**/*.xml</exclude>
+						<exclude>**/*.properties</exclude>
 					</excludes>
 					<useDefaultMapping>true</useDefaultMapping>
 					<strictCheck>true</strictCheck>