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/08 23:11:15 UTC
svn commit: r1465789 - in /jena/Experimental/jena-jdbc:
jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/
jena-jdbc-core/src/main/java/org/apache/jena/jdbc/preprocessing/
jena-jdbc-core/src/main/java/org/apache/jena/jdbc/statements/ jena-j...
Author: rvesse
Date: Mon Apr 8 21:11:15 2013
New Revision: 1465789
URL: http://svn.apache.org/r1465789
Log:
Stubs towards a command pre-processor extension mechanism for Jena JDBC
Modified:
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/JenaConnection.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/preprocessing/CommandPreProcessor.java
jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/statements/JenaStatement.java
jena/Experimental/jena-jdbc/jena-jdbc-driver-remote/src/main/java/org/apache/jena/jdbc/remote/connections/RemoteEndpointConnection.java
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java?rev=1465789&r1=1465788&r2=1465789&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/connections/DatasetConnection.java Mon Apr 8 21:11:15 2013
@@ -22,10 +22,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
-import java.sql.Statement;
-
import org.apache.jena.jdbc.JdbcCompatibility;
import org.apache.jena.jdbc.statements.DatasetStatement;
+import org.apache.jena.jdbc.statements.JenaStatement;
import com.hp.hpl.jena.query.Dataset;
@@ -83,12 +82,12 @@ public abstract class DatasetConnection
}
@Override
- protected Statement createStatementInternal(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ protected JenaStatement createStatementInternal(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY)
throw new SQLException("Dataset backed connections currently only supports forward-only result sets");
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY)
- throw new SQLException("Database backed connections currently only supports read-only result sets");
+ throw new SQLException("Database backed connections only supports read-only result sets");
return new DatasetStatement(this, ResultSet.FETCH_FORWARD, 0, resultSetHoldability, this.getAutoCommit(),
this.getTransactionIsolation());
}
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=1465789&r1=1465788&r2=1465789&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 Mon Apr 8 21:11:15 2013
@@ -37,16 +37,41 @@ import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.jena.jdbc.JdbcCompatibility;
import org.apache.jena.jdbc.metadata.JenaMetadata;
+import org.apache.jena.jdbc.preprocessing.CommandPreProcessor;
+import org.apache.jena.jdbc.statements.JenaStatement;
+
+import com.hp.hpl.jena.query.Query;
+import com.hp.hpl.jena.update.UpdateRequest;
/**
* Abstract base implementation of a Jena JDBC connection
- *
+ * <p>
+ * Generally speaking this is a faithful implementation of a JDBC connection but
+ * it also provides a couple of Jena JDBC specific features:
+ * </p>
+ * <ol>
+ * <li>JDBC compatibility level</li>
+ * <li>Command pre-processors</li>
+ * </ol>
+ * <p>
+ * The JDBC compatibility level allows the API to behave slightly differently
+ * depending on how JDBC like you need it to be, see {@link JdbcCompatibility}
+ * for more discussion on this.
+ * </p>
+ * <p>
+ * Command pre-processors are an extension mechanism designed to allow Jena JDBC
+ * connections to cope with the fact that the tools consuming the API may be
+ * completely unaware that we speak SPARQL rather than SQL. They allow for
+ * manipulation of incoming command text as well as manipulation of the parsed
+ * SPARQL queries and updates as desired.
+ * </p>
*/
public abstract class JenaConnection implements Connection {
@@ -71,6 +96,7 @@ public abstract class JenaConnection imp
private int isolationLevel = DEFAULT_ISOLATION_LEVEL;
private int compatibilityLevel = JdbcCompatibility.DEFAULT;
private List<Statement> statements = new ArrayList<Statement>();
+ private List<CommandPreProcessor> preProcessors = new ArrayList<CommandPreProcessor>();
/**
* Creates a new connection
@@ -120,6 +146,112 @@ public abstract class JenaConnection imp
this.compatibilityLevel = JdbcCompatibility.normalizeLevel(level);
}
+ /**
+ * Adds a command pre-processor to the connection
+ *
+ * @param preProcessor
+ * Pre-processor to add
+ */
+ public void addPreProcessor(CommandPreProcessor preProcessor) {
+ if (preProcessor == null)
+ return;
+ this.preProcessors.add(preProcessor);
+ }
+
+ /**
+ * Inserts a command pre-processor for the connection
+ *
+ * @param index
+ * Index to insert at
+ * @param preProcessor
+ * Pre-processor
+ */
+ public void insertPreProcessor(int index, CommandPreProcessor preProcessor) {
+ if (preProcessor == null)
+ return;
+ this.preProcessors.add(index, preProcessor);
+ }
+
+ /**
+ * Removes a command pre-processor from the connection
+ *
+ * @param preProcessor
+ * Pre-processor to remove
+ */
+ public void removePreProcessor(CommandPreProcessor preProcessor) {
+ if (preProcessor == null)
+ return;
+ this.preProcessors.remove(preProcessor);
+ }
+
+ /**
+ * Removes a command pre-processor from the connection
+ *
+ * @param index
+ * Index to remove at
+ */
+ public void removePreProcessor(int index) {
+ this.preProcessors.remove(index);
+ }
+
+ /**
+ * Clears all command pre-processor from the connection
+ */
+ public void clearPreProcessors() {
+ this.preProcessors.clear();
+ }
+
+ /**
+ * Gets the currently registered pre-processors for the connection
+ *
+ * @return Iterator of pre-processors
+ */
+ public Iterator<CommandPreProcessor> getPreProcessors() {
+ return this.preProcessors.iterator();
+ }
+
+ /**
+ * Apply registered pre-processors to the given command text
+ * @param text Command Text
+ * @return Command Text after processing by registered pre-processors
+ * @throws SQLException
+ */
+ public String applyPreProcessors(String text) throws SQLException {
+ for (CommandPreProcessor preProcessor : this.preProcessors) {
+ if (preProcessor == null) continue;
+ text = preProcessor.preProcessCommandText(text);
+ }
+ return text;
+ }
+
+ /**
+ * Applies registered pre-processors to the given query
+ * @param q Query
+ * @return Query after processing by registered pre-processors
+ * @throws SQLException
+ */
+ public Query applyPreProcessors(Query q) throws SQLException {
+ for (CommandPreProcessor preProcessor : this.preProcessors) {
+ if (preProcessor == null) continue;
+ q = preProcessor.preProcessQuery(q);
+ }
+ return q;
+ }
+
+ /**
+ * Applies registered pre-processors to the given update
+ * @param u Update
+ * @return Update after processing by registered pre-processors
+ * @throws SQLException
+ */
+ public UpdateRequest applyPreProcessors(UpdateRequest u) throws SQLException {
+ for (CommandPreProcessor preProcessor : this.preProcessors) {
+ if (preProcessor == null) continue;
+ u = preProcessor.preProcessUpdate(u);
+ }
+ return u;
+ }
+
@Override
public boolean isWrapperFor(Class<?> arg0) throws SQLException {
throw new SQLFeatureNotSupportedException();
@@ -222,12 +354,12 @@ public abstract class JenaConnection imp
throws SQLException {
if (this.isClosed())
throw new SQLException("Cannot create a statement after the connection was closed");
- Statement stmt = this.createStatementInternal(resultSetType, resultSetConcurrency, resultSetHoldability);
+ JenaStatement stmt = this.createStatementInternal(resultSetType, resultSetConcurrency, resultSetHoldability);
this.statements.add(stmt);
return stmt;
}
- protected abstract Statement createStatementInternal(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ protected abstract JenaStatement createStatementInternal(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException;
@Override
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/preprocessing/CommandPreProcessor.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/preprocessing/CommandPreProcessor.java?rev=1465789&r1=1465788&r2=1465789&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/preprocessing/CommandPreProcessor.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/preprocessing/CommandPreProcessor.java Mon Apr 8 21:11:15 2013
@@ -17,6 +17,7 @@
*/
package org.apache.jena.jdbc.preprocessing;
+import java.sql.SQLException;
import java.sql.Statement;
import com.hp.hpl.jena.query.Query;
@@ -39,30 +40,47 @@ public interface CommandPreProcessor {
/**
* Pre-process incoming command text
* <p>
- * This is invoked before Jena JDBC has attempted to determine whether the text is a query/update. This allows an application to do textual clean up/alteration of the incoming command if it so desires.
+ * This is invoked before Jena JDBC has attempted to determine whether the
+ * text is a query/update. This allows an application to do textual clean
+ * up/alteration of the incoming command if it so desires.
* </p>
- * @param text Command Text
+ *
+ * @param text
+ * Command Text
* @return Command Text which may have been altered
+ * @throws SQLException
+ * Thrown if pre-processing encounters an issue
*/
- public String preProcessCommandText(String text);
+ public String preProcessCommandText(String text) throws SQLException;
/**
* Pre-process a query
* <p>
- * This is invoked during query execution prior to Jena JDBC making any of its own manipulations on the query e.g. using {@link Statement#setMaxRows(int)} to add a {@code LIMIT} clause.
+ * This is invoked during query execution prior to Jena JDBC making any of
+ * its own manipulations on the query e.g. using
+ * {@link Statement#setMaxRows(int)} to add a {@code LIMIT} clause.
* </p>
- * @param q Query
+ *
+ * @param q
+ * Query
* @return Query which may have been altered
+ * @throws SQLException
+ * Thrown if pre-processing encounters an issue
*/
- public Query preProcessQuery(Query q);
-
+ public Query preProcessQuery(Query q) throws SQLException;
+
/**
* Pre-process an update
* <p>
- * This is invoked during update execution prior to Jena JDBC making any of its own manipulations on the update.
+ * This is invoked during update execution prior to Jena JDBC making any of
+ * its own manipulations on the update.
* </p>
- * @param u Update
+ *
+ * @param u
+ * Update
* @return Update which may have been altered
+ * @throws SQLException
+ * Thrown if pre-processing encounters an issue
*/
- public UpdateRequest preProcessUpdate(UpdateRequest u);
+ public UpdateRequest preProcessUpdate(UpdateRequest u) throws SQLException;
}
Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/statements/JenaStatement.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/statements/JenaStatement.java?rev=1465789&r1=1465788&r2=1465789&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/statements/JenaStatement.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/statements/JenaStatement.java Mon Apr 8 21:11:15 2013
@@ -186,6 +186,9 @@ public abstract class JenaStatement impl
public final boolean execute(String sql) throws SQLException {
if (this.isClosed())
throw new SQLException("The Statement is closed");
+
+ // Pre-process the command text
+ sql = this.connection.applyPreProcessors(sql);
Query q = null;
UpdateRequest u = null;
@@ -216,7 +219,7 @@ public abstract class JenaStatement impl
private boolean executeQuery(Query q) throws SQLException {
if (this.isClosed())
throw new SQLException("The Statement is closed");
-
+
// Do we need transactions?
boolean needsBegin = (!this.autoCommit && this.transactionLevel != Connection.TRANSACTION_NONE && !this
.hasActiveTransaction());
@@ -229,6 +232,9 @@ public abstract class JenaStatement impl
} else if (needsBegin) {
this.beginTransaction(ReadWrite.WRITE);
}
+
+ // Pre-process the query
+ q = this.connection.applyPreProcessors(q);
// Manipulate the query if appropriate
if (this.maxRows > NO_LIMIT) {
@@ -302,7 +308,11 @@ public abstract class JenaStatement impl
if (needsCommit || needsBegin) {
this.beginTransaction(ReadWrite.WRITE);
}
+
+ // Pre-process the update
+ u = this.connection.applyPreProcessors(u);
+ // Execute updates
UpdateProcessor processor = this.createUpdateProcessor(u);
processor.execute();
commit = true;
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=1465789&r1=1465788&r2=1465789&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 Mon Apr 8 21:11:15 2013
@@ -24,12 +24,11 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
-import java.sql.Statement;
-
import org.apache.jena.jdbc.JdbcCompatibility;
import org.apache.jena.jdbc.connections.JenaConnection;
import org.apache.jena.jdbc.remote.metadata.RemoteEndpointMetadata;
import org.apache.jena.jdbc.remote.statements.RemoteEndpointStatement;
+import org.apache.jena.jdbc.statements.JenaStatement;
/**
* Represents a connection to a remote endpoint
@@ -89,7 +88,7 @@ public class RemoteEndpointConnection ex
}
@Override
- protected Statement createStatementInternal(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ protected JenaStatement createStatementInternal(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
if (this.isClosed())
throw new SQLException("Cannot create a statement after the connection was closed");