Add initial async support (Search, Record)
[yaz4j-moved-to-github.git] / src / main / java / org / yaz4j / Connection.java
1 package org.yaz4j;
2
3 import java.io.Closeable;
4 import org.yaz4j.exception.ZoomException;
5 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_connection_p;
6 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_query_p;
7 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p;
8 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_scanset_p;
9 import org.yaz4j.jni.yaz4jlib;
10
11 /**
12  * Class representing an on-going communication with an IR server.
13  *
14  * Creating an instance of this class does not automatically connect (e.g open
15  * a socket) to the remote server as the programmer may want to specify options
16  * on the object before establishing the actual connection.
17  *
18  * The work-flow for synchronous (the only addressed) operation when using this
19  * class should be as follows (in pseudocode):
20  *
21  * <blockquote><pre>
22  *
23  * try {
24  *  c = new Connection(...)
25  *  //possibly set some options
26  *  c.connect //establishes connection
27  *  c.search //or other operation
28  *  //possibly retrieve records
29  * catch (ZoomException e) {
30  *  //handle any protocol- or network-level errors
31  * } finally {
32  *  c.close //close the socket
33  * }
34  *
35  * </pre></blockquote>
36  * @see <a href="http://www.indexdata.com/yaz/doc/zoom.html#zoom-connections">YAZ ZOOM Connection</a>
37  * @author jakub
38  */
39 public class Connection implements Closeable {
40   protected final String host;
41   protected final int port;
42   protected SWIGTYPE_p_ZOOM_connection_p zoomConnection;
43   //connection is initially closed
44   protected boolean closed = true;
45   private boolean disposed = false;
46
47   public enum QueryType {
48
49     CQLQuery, PrefixQuery
50   };
51
52   static {
53     // on Linux   'yaz4j' maps to 'libyaz4j.so' (i.e. 'lib' prefix & '.so'  extension)
54     // on Windows 'yaz4j' maps to 'yaz4j.dll'   (i.e.                '.dll' extension)
55     String libName = "yaz4j";
56     System.loadLibrary(libName);
57   }
58
59   /**
60    * Create new connection object without physically opening a connection to the
61    * remote server.
62    * @param host host name of the server
63    * @param port port of the server
64    */
65   public Connection(String host, int port) {
66     if (host == null)
67       throw new NullPointerException("host cannot be null");
68     this.host = host;
69     this.port = port;
70     zoomConnection = yaz4jlib.ZOOM_connection_create(null);
71   }
72
73   public void finalize() {
74     _dispose();
75   }
76
77   /**
78    * Performs a search operation (submits the query to the server, waits for
79    * response and creates a new result set that allows to retrieve particular
80    * results)
81    * @deprecated Does not allow specifying sort criteria prior to search
82    * use {@link #search(org.yaz4j.Query) search(Query)} instead.
83    * @param query search query
84    * @param queryType type of the query (e.g RPN. CQL)
85    * @return result set containing records (hits)
86    * @throws ZoomException protocol or network-level error
87    */
88   @Deprecated
89   public ResultSet search(String query, QueryType queryType) throws
90     ZoomException {
91     if (query == null)
92       throw new NullPointerException("query cannot be null");
93     if (queryType == null)
94       throw new NullPointerException("queryType cannot be null");
95     if (closed)
96       throw new IllegalStateException("Connection is closed.");
97     SWIGTYPE_p_ZOOM_query_p yazQuery = null;
98     if (queryType == QueryType.CQLQuery) {
99       yazQuery = yaz4jlib.ZOOM_query_create();
100       yaz4jlib.ZOOM_query_cql(yazQuery, query);
101     } else if (queryType == QueryType.PrefixQuery) {
102       yazQuery = yaz4jlib.ZOOM_query_create();
103       yaz4jlib.ZOOM_query_prefix(yazQuery, query);
104     }
105     SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search(
106       zoomConnection, yazQuery);
107     yaz4jlib.ZOOM_query_destroy(yazQuery);
108     ZoomException err = ExceptionUtil.getError(zoomConnection, host,
109       port);
110     if (err != null) {
111       yaz4jlib.ZOOM_resultset_destroy(yazResultSet);
112       throw err;
113     }
114     return new ResultSet(yazResultSet, this);
115   }
116   
117     /**
118    * Performs a search operation (submits the query to the server, waits for
119    * response and creates a new result set that allows to retrieve particular
120    * results). Sort criteria may be specified prior to the search, directly
121    * on the query object.
122    * @param query search query of any type supported by YAZ.
123    * @return result set containing records (hits)
124    * @throws ZoomException protocol or network-level error
125    */
126   public ResultSet search(Query query) throws ZoomException {
127     if (query == null)
128       throw new NullPointerException("query cannot be null");
129     if (closed)
130       throw new IllegalStateException("Connection is closed.");
131     SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search(
132       zoomConnection, query.query);
133     ZoomException err = ExceptionUtil.getError(zoomConnection, host,
134       port);
135     if (err != null) {
136       yaz4jlib.ZOOM_resultset_destroy(yazResultSet);
137       throw err;
138     }
139     return new ResultSet(yazResultSet, this);
140   }
141   
142   
143
144   /**
145    * Performs a scan operation (obtains a list of candidate search terms against
146    * a particular access point). 
147    * @deprecated Only allows PQF scan queries, use {@link #scan(org.yaz4j.Query) scan(Query)} instead
148    * @param query query for scanning
149    * @return a scan set with the terms
150    * @throws ZoomException a protocol or network-level error
151    */
152   @Deprecated
153   public ScanSet scan(String query) throws ZoomException {
154     if (query == null)
155       throw new NullPointerException("query cannot be null");
156     if (closed)
157       throw new IllegalStateException("Connection is closed.");
158     SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan(
159       zoomConnection, query);
160     ZoomException err = ExceptionUtil.getError(zoomConnection, host, port);
161     if (err != null) {
162       yaz4jlib.ZOOM_scanset_destroy(yazScanSet);
163       throw err;
164     }
165     ScanSet scanSet = new ScanSet(yazScanSet, this);
166     return scanSet;
167   }
168   
169     /**
170    * Performs a scan operation (obtains a list of candidate search terms against
171    * a particular access point). Allows to use both CQL and PQF for Scan.
172    * @see <a href="http://www.indexdata.com/yaz/doc/zoom.scan.html">ZOOM-API Scan</a>
173    * @param query scan query of type supported by YAZ
174    * @return a scan set with the terms
175    * @throws ZoomException a protocol or network-level error
176    */
177   public ScanSet scan(Query query) throws ZoomException {
178     if (query == null)
179       throw new NullPointerException("query cannot be null");
180     if (closed)
181       throw new IllegalStateException("Connection is closed.");
182     SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan1(
183       zoomConnection, query.query);
184     ZoomException err = ExceptionUtil.getError(zoomConnection, host, port);
185     if (err != null) {
186       yaz4jlib.ZOOM_scanset_destroy(yazScanSet);
187       throw err;
188     }
189     ScanSet scanSet = new ScanSet(yazScanSet, this);
190     return scanSet;
191   }
192
193   /**
194    * Establishes a connection to the remote server.
195    * @throws ZoomException any (possibly network-level) errors that may occurr
196    */
197   public void connect() throws ZoomException {
198     yaz4jlib.ZOOM_connection_connect(zoomConnection, host, port);
199     ZoomException err = ExceptionUtil.getError(zoomConnection, host, port);
200     if (err != null) {
201       throw err;
202     }
203     closed = false;
204   }
205
206   /**
207    * Closes the connection.
208    */
209   @Override
210   public void close() {
211     yaz4jlib.ZOOM_connection_close(zoomConnection);
212     closed = true;
213   }
214   
215   /**
216    * Return exception type from current connection
217    *
218    * @return null if no error
219    */
220   ZoomException getZoomException() {
221     ZoomException err = ExceptionUtil.getError(zoomConnection, host, port);
222     return err;
223   }
224
225   /**
226    * Write option with a given name.
227    * @param name option name
228    * @param value option value
229    * @return connection (self) for chainability
230    */
231   public Connection option(String name, String value) {
232     if (name == null)
233       throw new NullPointerException("option name cannot be null");
234     yaz4jlib.ZOOM_connection_option_set(zoomConnection, name, value);
235     return this;
236   }
237
238   /**
239    * Read option with a given name
240    * @param name option name
241    * @return option value
242    */
243   public String option(String name) {
244     if (name == null)
245       throw new NullPointerException("option name cannot be null");
246     return yaz4jlib.ZOOM_connection_option_get(zoomConnection, name);
247   }
248
249   /**
250    * Same as option("preferredRecordSyntax")
251    * @return value of preferred record syntax
252    */
253   public String getSyntax() {
254     return option("preferredRecordSyntax");
255   }
256
257   /**
258    * Same as option("preferredRecordSyntax", value)
259    * @param value value of preferred record syntax
260    */
261   public void setSyntax(String value) {
262     option("preferredRecordSyntax", value);
263   }
264
265   /**
266    * Same as option("databaseName")
267    * @return value of databaseName
268    */
269   public String getDatabaseName() {
270     return option("databaseName");
271   }
272
273   /**
274    * Same as option("databaseName", value)
275    * @param value value of databaseName
276    */
277   public void setDatabaseName(String value) {
278     option("databaseName", value);
279   }
280
281   /**
282    * Same as option("user")
283    * @return value of user
284    */
285   public String getUsername() {
286     return option("user");
287   }
288
289   /**
290    * Same as option("user", value)
291    * @param value value of user
292    */
293   public void setUsername(String value) {
294     option("user", value);
295   }
296
297   /**
298    * Same as option("password")
299    * @return value of password
300    */
301   public String getPassword() {
302     return option("password");
303   }
304
305   /**
306    * Same as option("password", value)
307    * @param value
308    */
309   public void setPassword(String value) {
310     option("password", value);
311   }
312
313   /**
314    * INTERNAL, GC-ONLY
315    */
316   void _dispose() {
317     if (!disposed) {
318       yaz4jlib.ZOOM_connection_destroy(zoomConnection);
319       zoomConnection = null;
320       disposed = true;
321     }
322   }
323 }