X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fyaz4j%2FConnection.java;h=6a173f9a4598f37090d6affef58f9fa2bfee60b5;hb=a2a53e742c9f927aad2a45a19e4796ef26e8ad0b;hp=2c5fcf2872f58c7d1f705756ca8ea718da96cc15;hpb=428d895d6dc31b784e953ea935d662cfc4a4bd43;p=yaz4j-moved-to-github.git diff --git a/src/main/java/org/yaz4j/Connection.java b/src/main/java/org/yaz4j/Connection.java index 2c5fcf2..6a173f9 100644 --- a/src/main/java/org/yaz4j/Connection.java +++ b/src/main/java/org/yaz4j/Connection.java @@ -1,235 +1,321 @@ package org.yaz4j; +import java.io.Closeable; +import org.yaz4j.exception.ZoomException; import org.yaz4j.jni.SWIGTYPE_p_ZOOM_connection_p; import org.yaz4j.jni.SWIGTYPE_p_ZOOM_query_p; import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p; import org.yaz4j.jni.SWIGTYPE_p_ZOOM_scanset_p; -import org.yaz4j.jni.SWIGTYPE_p_p_char; import org.yaz4j.jni.yaz4jlib; -import org.yaz4j.jni.yaz4jlibConstants; - -import sun.reflect.generics.reflectiveObjects.NotImplementedException; - -public class Connection -{ - private String host ; - private int port ; - private ConnectionOptionsCollection options = null ; - protected SWIGTYPE_p_ZOOM_connection_p zoomConnection = null ; - private boolean connected = false; - private boolean disposed = false; - - static - { - // on Linux 'yaz4j' maps to 'libyaz4j.so' (i.e. 'lib' prefix & '.so' extension) - // on Windows 'yaz4j' maps to 'yaz4j.dll' (i.e. '.dll' extension) - String libName = "yaz4j" ; - try - { - // System.err.println( "Loading library '"+ System.mapLibraryName( libName ) + "'" ); - System.loadLibrary( libName ); - } - catch( Throwable e ) - { - System.err.println( "Fatal Error: Failed to load library '" + System.mapLibraryName( libName ) + "'"); - e.printStackTrace(); - } - } - - public Connection(String host, int port) - { - this.host = host ; - this.port = port ; - - options = new ConnectionOptionsCollection(); - zoomConnection = yaz4jlib.ZOOM_connection_create(options.zoomOptions); - - SWIGTYPE_p_p_char cp = null; - SWIGTYPE_p_p_char addinfo = null ; - int errorCode = yaz4jlib.ZOOM_connection_error(zoomConnection, cp, addinfo); - CheckErrorCodeAndThrow(errorCode); - } - - public void finalize() - { - Dispose(); - } - - private void CheckErrorCodeAndThrow(int errorCode) - { - String message; - - if( errorCode == yaz4jlibConstants.ZOOM_ERROR_NONE ) - { - return ; - } - else if( errorCode == yaz4jlib.ZOOM_ERROR_CONNECT ) - { - message = String.format("Connection could not be made to %s:%d", host, port); - throw new ConnectionUnavailableException(message); - } - else if( errorCode == yaz4jlib.ZOOM_ERROR_INVALID_QUERY ) - { - message = String.format("The query requested is not valid or not supported"); - throw new InvalidQueryException(message); - } - else if( errorCode == yaz4jlib.ZOOM_ERROR_INIT ) - { - message = String.format("Server %s:%d rejected our init request", host, port); - throw new InitRejectedException(message); - } - else if( errorCode == yaz4jlib.ZOOM_ERROR_TIMEOUT ) - { - message = String.format("Server %s:%d timed out handling our request", host, port); - throw new ConnectionTimeoutException(message); - } - else if( ( errorCode == yaz4jlib.ZOOM_ERROR_MEMORY ) - || ( errorCode == yaz4jlib.ZOOM_ERROR_ENCODE ) - || ( errorCode == yaz4jlib.ZOOM_ERROR_DECODE ) - || ( errorCode == yaz4jlib.ZOOM_ERROR_CONNECTION_LOST ) - || ( errorCode == yaz4jlib.ZOOM_ERROR_INTERNAL ) - || ( errorCode == yaz4jlib.ZOOM_ERROR_UNSUPPORTED_PROTOCOL ) - || ( errorCode == yaz4jlib.ZOOM_ERROR_UNSUPPORTED_QUERY ) ) - { - message = yaz4jlib.ZOOM_connection_errmsg(zoomConnection); - throw new ZoomImplementationException("A fatal error occurred in Yaz: " + errorCode + " - " + message); - } - else - { - String errMsgBib1 = "Bib1Exception: Error Code = " + errorCode + " (" + Bib1Diagnostic.GetError(errorCode) + ")" ; - throw new Bib1Exception( errMsgBib1 ); - } - } - - private enum QueryType { CQLQuery, PrefixQuery }; - - public ResultSet Search(PrefixQuery query) - { - return Search( query.getQueryString(), QueryType.PrefixQuery); - } - - public ResultSet Search(CQLQuery query) - { - return Search( query.getQueryString(), QueryType.CQLQuery); - } - - private ResultSet Search(String query, QueryType queryType) - { - EnsureConnected(); - - SWIGTYPE_p_ZOOM_query_p yazQuery = yaz4jlib.ZOOM_query_create(); - ResultSet resultSet = null; - - try - { - if( queryType == QueryType.CQLQuery ) - yaz4jlib.ZOOM_query_cql(yazQuery, query); - else if( queryType == QueryType.PrefixQuery ) - yaz4jlib.ZOOM_query_prefix(yazQuery, query); - else - throw new NotImplementedException(); - - SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search(zoomConnection, yazQuery); - - int errorCode = yaz4jlib.ZOOM_connection_errcode( zoomConnection ); - if (errorCode != yaz4jlib.ZOOM_ERROR_NONE) - { - yaz4jlib.ZOOM_resultset_destroy(yazResultSet); - } - CheckErrorCodeAndThrow(errorCode); - - resultSet = new ResultSet(yazResultSet, zoomConnection); - } - finally - { - yaz4jlib.ZOOM_query_destroy(yazQuery); // deallocate yazQuery also when exceptions - yazQuery = null; - } - return resultSet; - } - - public ScanSet Scan(String query) - { - EnsureConnected(); - SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan(zoomConnection, query); - - int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); - if( errorCode != yaz4jlib.ZOOM_ERROR_NONE ) - { - yaz4jlib.ZOOM_scanset_destroy(yazScanSet); - } - CheckErrorCodeAndThrow(errorCode); - - ScanSet scanSet = new ScanSet(yazScanSet, this); - return scanSet; - } - - public ConnectionOptionsCollection getOptions() - { - return options; - } - - protected void EnsureConnected() - { - if (! connected ) - Connect(); - } - - public void Connect() - { - yaz4jlib.ZOOM_connection_connect( zoomConnection, host, port); - int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); - CheckErrorCodeAndThrow(errorCode); - connected = true; - } - - public void Dispose() - { - if (! disposed ) - { - yaz4jlib.ZOOM_connection_destroy(zoomConnection); - zoomConnection = null; - disposed = true; - } - } - - public String getSyntax() - { - return options.get("preferredRecordSyntax"); - } - - public void setSyntax( String value) - { - options.set("preferredRecordSyntax", value ) ; - } - - public String getDatabaseName() - { - return options.get("databaseName"); - } - - public void setDatabaseName( String value ) - { - options.set("databaseName", value); - } - - public String getUsername() - { - return options.get("user"); - } - - public void setUsername( String value ) - { - options.set("user", value); - } - - public String getPassword() - { - return options.get("password"); - } - - public void setPassword( String value ) - { - options.set("password", value); - } + +/** + * Class representing an on-going communication with an IR server. + * + * Creating an instance of this class does not automatically connect (e.g open + * a socket) to the remote server as the programmer may want to specify options + * on the object before establishing the actual connection. + * + * The work-flow for synchronous (the only addressed) operation when using this + * class should be as follows (in pseudocode): + * + *
+ *
+ * try {
+ *  c = new Connection(...)
+ *  //possibly set some options
+ *  c.connect //establishes connection
+ *  c.search //or other operation
+ *  //possibly retrieve records
+ * catch (ZoomException e) {
+ *  //handle any protocol- or network-level errors
+ * } finally {
+ *  c.close //close the socket
+ * }
+ *
+ * 
+ * @see YAZ ZOOM Connection + * @author jakub + */ +public class Connection implements Closeable { + private final String host; + private final int port; + protected SWIGTYPE_p_ZOOM_connection_p zoomConnection; + //connection is initially closed + protected boolean closed = true; + private boolean disposed = false; + + public enum QueryType { + + CQLQuery, PrefixQuery + }; + + static { + // on Linux 'yaz4j' maps to 'libyaz4j.so' (i.e. 'lib' prefix & '.so' extension) + // on Windows 'yaz4j' maps to 'yaz4j.dll' (i.e. '.dll' extension) + String libName = "yaz4j"; + System.loadLibrary(libName); + } + + /** + * Create new connection object without physically opening a connection to the + * remote server. + * @param host host name of the server + * @param port port of the server + */ + public Connection(String host, int port) { + if (host == null) + throw new NullPointerException("host cannot be null"); + this.host = host; + this.port = port; + zoomConnection = yaz4jlib.ZOOM_connection_create(null); + } + + public void finalize() { + _dispose(); + } + + /** + * Performs a search operation (submits the query to the server, waits for + * response and creates a new result set that allows to retrieve particular + * results) + * @deprecated Does not allow specifying sort criteria prior to search + * use {@link #search(org.yaz4j.Query) search(Query)} instead. + * @param query search query + * @param queryType type of the query (e.g RPN. CQL) + * @return result set containing records (hits) + * @throws ZoomException protocol or network-level error + */ + @Deprecated + public ResultSet search(String query, QueryType queryType) throws + ZoomException { + if (query == null) + throw new NullPointerException("query cannot be null"); + if (queryType == null) + throw new NullPointerException("queryType cannot be null"); + if (closed) + throw new IllegalStateException("Connection is closed."); + SWIGTYPE_p_ZOOM_query_p yazQuery = null; + if (queryType == QueryType.CQLQuery) { + yazQuery = yaz4jlib.ZOOM_query_create(); + yaz4jlib.ZOOM_query_cql(yazQuery, query); + } else if (queryType == QueryType.PrefixQuery) { + yazQuery = yaz4jlib.ZOOM_query_create(); + yaz4jlib.ZOOM_query_prefix(yazQuery, query); + } + SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search( + zoomConnection, yazQuery); + yaz4jlib.ZOOM_query_destroy(yazQuery); + ZoomException err = ExceptionUtil.getError(zoomConnection, host, + port); + if (err != null) { + yaz4jlib.ZOOM_resultset_destroy(yazResultSet); + throw err; + } + return new ResultSet(yazResultSet, this); + } + + /** + * Performs a search operation (submits the query to the server, waits for + * response and creates a new result set that allows to retrieve particular + * results). Sort criteria may be specified prior to the search, directly + * on the query object. + * @param query search query of any type supported by YAZ. + * @return result set containing records (hits) + * @throws ZoomException protocol or network-level error + */ + public ResultSet search(Query query) throws ZoomException { + if (query == null) + throw new NullPointerException("query cannot be null"); + if (closed) + throw new IllegalStateException("Connection is closed."); + SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search( + zoomConnection, query.query); + ZoomException err = ExceptionUtil.getError(zoomConnection, host, + port); + if (err != null) { + yaz4jlib.ZOOM_resultset_destroy(yazResultSet); + throw err; + } + return new ResultSet(yazResultSet, this); + } + + /** + * Performs a scan operation (obtains a list of candidate search terms against + * a particular access point). + * @deprecated Only allows PQF scan queries, use {@link #scan(org.yaz4j.Query) scan(Query)} instead + * @param query query for scanning + * @return a scan set with the terms + * @throws ZoomException a protocol or network-level error + */ + @Deprecated + public ScanSet scan(String query) throws ZoomException { + if (query == null) + throw new NullPointerException("query cannot be null"); + if (closed) + throw new IllegalStateException("Connection is closed."); + SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan( + zoomConnection, query); + ZoomException err = ExceptionUtil.getError(zoomConnection, host, port); + if (err != null) { + yaz4jlib.ZOOM_scanset_destroy(yazScanSet); + throw err; + } + ScanSet scanSet = new ScanSet(yazScanSet, this); + return scanSet; + } + + /** + * Performs a scan operation (obtains a list of candidate search terms against + * a particular access point). Allows to use both CQL and PQF for Scan. + * @see ZOOM-API Scan + * @param query scan query of type supported by YAZ + * @return a scan set with the terms + * @throws ZoomException a protocol or network-level error + */ + public ScanSet scan(Query query) throws ZoomException { + if (query == null) + throw new NullPointerException("query cannot be null"); + if (closed) + throw new IllegalStateException("Connection is closed."); + SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan1( + zoomConnection, query.query); + ZoomException err = ExceptionUtil.getError(zoomConnection, host, port); + if (err != null) { + yaz4jlib.ZOOM_scanset_destroy(yazScanSet); + throw err; + } + ScanSet scanSet = new ScanSet(yazScanSet, this); + return scanSet; + } + + /** + * Establishes a connection to the remote server. + * @throws ZoomException any (possibly network-level) errors that may occurr + */ + public void connect() throws ZoomException { + yaz4jlib.ZOOM_connection_connect(zoomConnection, host, port); + ZoomException err = ExceptionUtil.getError(zoomConnection, host, port); + if (err != null) { + throw err; + } + closed = false; + } + + /** + * Closes the connection. + */ + @Override + public void close() { + yaz4jlib.ZOOM_connection_close(zoomConnection); + closed = true; + } + + /** + * Return exception type from current connection + * + * @return null if no error + */ + ZoomException getZoomException() { + ZoomException err = ExceptionUtil.getError(zoomConnection, host, port); + return err; + } + + /** + * Write option with a given name. + * @param name option name + * @param value option value + * @return connection (self) for chainability + */ + public Connection option(String name, String value) { + if (name == null) + throw new NullPointerException("option name cannot be null"); + yaz4jlib.ZOOM_connection_option_set(zoomConnection, name, value); + return this; + } + + /** + * Read option with a given name + * @param name option name + * @return option value + */ + public String option(String name) { + if (name == null) + throw new NullPointerException("option name cannot be null"); + return yaz4jlib.ZOOM_connection_option_get(zoomConnection, name); + } + + /** + * Same as option("preferredRecordSyntax") + * @return value of preferred record syntax + */ + public String getSyntax() { + return option("preferredRecordSyntax"); + } + + /** + * Same as option("preferredRecordSyntax", value) + * @param value value of preferred record syntax + */ + public void setSyntax(String value) { + option("preferredRecordSyntax", value); + } + + /** + * Same as option("databaseName") + * @return value of databaseName + */ + public String getDatabaseName() { + return option("databaseName"); + } + + /** + * Same as option("databaseName", value) + * @param value value of databaseName + */ + public void setDatabaseName(String value) { + option("databaseName", value); + } + + /** + * Same as option("user") + * @return value of user + */ + public String getUsername() { + return option("user"); + } + + /** + * Same as option("user", value) + * @param value value of user + */ + public void setUsername(String value) { + option("user", value); + } + + /** + * Same as option("password") + * @return value of password + */ + public String getPassword() { + return option("password"); + } + + /** + * Same as option("password", value) + * @param value + */ + public void setPassword(String value) { + option("password", value); + } + + /** + * INTERNAL, GC-ONLY + */ + void _dispose() { + if (!disposed) { + yaz4jlib.ZOOM_connection_destroy(zoomConnection); + zoomConnection = null; + disposed = true; + } + } }