0587ec78a8d356d54180b993e55f7d48a790ae39
[yaz4j-moved-to-github.git] / src / main / java / org / yaz4j / Connection.java
1 package org.yaz4j;
2
3 import org.yaz4j.exception.ZoomImplementationException;
4 import org.yaz4j.exception.ConnectionTimeoutException;
5 import org.yaz4j.exception.InitRejectedException;
6 import org.yaz4j.exception.Bib1Exception;
7 import org.yaz4j.exception.InvalidQueryException;
8 import org.yaz4j.exception.Bib1Diagnostic;
9 import org.yaz4j.exception.ConnectionUnavailableException;
10 import org.yaz4j.exception.ZoomException;
11 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_connection_p;
12 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_query_p;
13 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p;
14 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_scanset_p;
15 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_options_p;
16 import org.yaz4j.jni.yaz4jlib;
17 import org.yaz4j.jni.yaz4jlibConstants;
18
19 public class Connection {
20     private String host;
21     private int port;
22     protected SWIGTYPE_p_ZOOM_connection_p zoomConnection;
23     //connection is initially closed
24     protected boolean closed = true;
25     private boolean disposed = false;
26
27     public enum QueryType {
28         CQLQuery, PrefixQuery
29     };
30
31     static {
32         // on Linux   'yaz4j' maps to 'libyaz4j.so' (i.e. 'lib' prefix & '.so'  extension)
33         // on Windows 'yaz4j' maps to 'yaz4j.dll'   (i.e.                '.dll' extension)
34         String libName = "yaz4j";
35         try {
36             // System.err.println( "Loading library '"+ System.mapLibraryName( libName ) + "'" );
37             System.loadLibrary(libName);
38         } catch (AbstractMethodError e) {
39             System.err.println("Fatal Error: Failed to load library '" + System.mapLibraryName(libName) + "'");
40             e.printStackTrace();
41         }
42     }
43
44     public Connection(String host, int port) {
45         this.host = host;
46         this.port = port;
47         zoomConnection = yaz4jlib.ZOOM_connection_create(null);
48     }
49
50     public void finalize() {
51         _dispose();
52     }
53
54     public ResultSet search(String query, QueryType queryType) throws ZoomException {
55       if (closed) throw new IllegalStateException("Connection is closed.");
56         SWIGTYPE_p_ZOOM_query_p yazQuery = yaz4jlib.ZOOM_query_create();
57         ResultSet resultSet = null;
58
59         try {
60             if (queryType == QueryType.CQLQuery) {
61                 yaz4jlib.ZOOM_query_cql(yazQuery, query);
62             } else if (queryType == QueryType.PrefixQuery) {
63                 yaz4jlib.ZOOM_query_prefix(yazQuery, query);
64             } else {
65                 throw new InvalidQueryException("queryType");
66             }
67
68             SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search(zoomConnection, yazQuery);
69
70             int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection);
71             if (errorCode != yaz4jlib.ZOOM_ERROR_NONE) {
72                 yaz4jlib.ZOOM_resultset_destroy(yazResultSet);
73             }
74             checkErrorCodeAndThrow(errorCode);
75
76             resultSet = new ResultSet(yazResultSet, this);
77         } finally {
78             yaz4jlib.ZOOM_query_destroy(yazQuery); // deallocate yazQuery also when exceptions
79             yazQuery = null;
80         }
81         return resultSet;
82     }
83
84     public ScanSet scan(String query) throws ZoomException {
85       if (closed) throw new IllegalStateException("Connection is closed.");
86         SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan(zoomConnection, query);
87
88         int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection);
89         if (errorCode != yaz4jlib.ZOOM_ERROR_NONE) {
90             yaz4jlib.ZOOM_scanset_destroy(yazScanSet);
91         }
92         checkErrorCodeAndThrow(errorCode);
93
94         ScanSet scanSet = new ScanSet(yazScanSet, this);
95         return scanSet;
96     }
97
98     /**
99      * Initiates the connection
100      */
101     public void connect() throws ZoomException {
102       yaz4jlib.ZOOM_connection_connect(zoomConnection, host, port);
103       int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection);
104       checkErrorCodeAndThrow(errorCode);
105       closed = false;
106     }
107
108     /**
109      * Closes the connection.
110      */
111     public void close() {
112       yaz4jlib.ZOOM_connection_close(zoomConnection);
113       closed = true;
114     }
115
116     private void checkErrorCodeAndThrow(int errorCode) throws ZoomException {
117         String message;
118
119         if (errorCode == yaz4jlibConstants.ZOOM_ERROR_NONE) {
120             return;
121         } else if (errorCode == yaz4jlib.ZOOM_ERROR_CONNECT) {
122             message = String.format("Connection could not be made to %s:%d", host, port);
123             throw new ConnectionUnavailableException(message);
124         } else if (errorCode == yaz4jlib.ZOOM_ERROR_INVALID_QUERY) {
125             message = String.format("The query requested is not valid or not supported");
126             throw new InvalidQueryException(message);
127         } else if (errorCode == yaz4jlib.ZOOM_ERROR_INIT) {
128             message = String.format("Server %s:%d rejected our init request", host, port);
129             throw new InitRejectedException(message);
130         } else if (errorCode == yaz4jlib.ZOOM_ERROR_TIMEOUT) {
131             message = String.format("Server %s:%d timed out handling our request", host, port);
132             throw new ConnectionTimeoutException(message);
133         } 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)) {
134             message = yaz4jlib.ZOOM_connection_errmsg(zoomConnection);
135             throw new ZoomImplementationException("A fatal error occurred in Yaz: " + errorCode + " - " + message);
136         } else {
137             String errMsgBib1 = "Bib1Exception: Error Code = " + errorCode + " (" + Bib1Diagnostic.getError(errorCode) + ")";
138             throw new Bib1Exception(errMsgBib1);
139         }
140     }
141
142     /**
143      * Write option with a given name.
144      * @param name option name
145      * @param value option value
146      * @return connection (self) for chainability
147      */
148     public Connection option(String name, String value) {
149       yaz4jlib.ZOOM_connection_option_set(zoomConnection, name, value);
150       return this;
151     }
152
153     /**
154      * Read option with a given name
155      * @param name option name
156      * @return option value
157      */
158     public String option(String name) {
159       return yaz4jlib.ZOOM_connection_option_get(zoomConnection, name);
160     }
161
162     public String getSyntax() {
163         return option("preferredRecordSyntax");
164     }
165
166     public void setSyntax(String value) {
167         option("preferredRecordSyntax", value);
168     }
169
170     public String getDatabaseName() {
171         return option("databaseName");
172     }
173
174     public void setDatabaseName(String value) {
175         option("databaseName", value);
176     }
177
178     public String getUsername() {
179         return option("user");
180     }
181
182     public void setUsername(String value) {
183         option("user", value);
184     }
185
186     public String getPassword() {
187         return option("password");
188     }
189
190     public void setPassword(String value) {
191         option("password", value);
192     }
193
194     /**
195      * INTERNAL, GC-ONLY
196      */
197     void _dispose() {
198         if (!disposed) {
199           yaz4jlib.ZOOM_connection_destroy(zoomConnection);
200           zoomConnection = null;
201           disposed = true;
202         }
203     }
204 }