49d5aea19e574cc6f7569e024224d3e76e5f33d3
[yaz4j-moved-to-github.git] / src / main / java / org / yaz4j / Connection.java
1 package org.yaz4j;
2
3 import org.yaz4j.exception.ZoomException;
4 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_connection_p;
5 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_query_p;
6 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p;
7 import org.yaz4j.jni.SWIGTYPE_p_ZOOM_scanset_p;
8 import org.yaz4j.jni.yaz4jlib;
9
10 /**
11  * Class representing an on-going communication with an IR server.
12  *
13  * Creating an instance of this class does not automatically connect (e.g open
14  * a socket) to the remote server as the programmer may want to specify options
15  * on the object before establishing the actual connection.
16  *
17  * The work-flow for synchronous (the only addressed) operation when using this
18  * class should be as follows (in pseudocode):
19  *
20  * <blockquote><pre>
21  *
22  * try {
23  *  c = new Connection(...)
24  *  //possibly set some options
25  *  c.connect //establishes connection
26  *  c.search //or other operation
27  *  //possibly retrieve records
28  * catch (ZoomException e) {
29  *  //handle any protocol- or network-level errors
30  * } finally {
31  *  c.close //close the socket
32  * }
33  *
34  * </pre></blockquote>
35  * @author jakub
36  */
37 public class Connection {
38
39   private String host;
40   private int port;
41   protected SWIGTYPE_p_ZOOM_connection_p zoomConnection;
42   //connection is initially closed
43   protected boolean closed = true;
44   private boolean disposed = false;
45
46   public enum QueryType {
47
48     CQLQuery, PrefixQuery
49   };
50
51   static {
52     // on Linux   'yaz4j' maps to 'libyaz4j.so' (i.e. 'lib' prefix & '.so'  extension)
53     // on Windows 'yaz4j' maps to 'yaz4j.dll'   (i.e.                '.dll' extension)
54     String libName = "yaz4j";
55     System.loadLibrary(libName);
56   }
57
58   /**
59    * Create new connection object without physically opening a connection to the
60    * remote server.
61    * @param host host name of the server
62    * @param port port of the server
63    */
64   public Connection(String host, int port) {
65     this.host = host;
66     this.port = port;
67     zoomConnection = yaz4jlib.ZOOM_connection_create(null);
68   }
69
70   public void finalize() {
71     _dispose();
72   }
73
74   /**
75    * Performs a search operation (submits the query to the server, waits for
76    * response and creates a new result set that allows to retrieve particular
77    * results)
78    * @param query search query
79    * @param queryType type of the query (e.g RPN. CQL)
80    * @return result set containing records (hits)
81    * @throws ZoomException protocol or network-level error
82    */
83   public ResultSet search(String query, QueryType queryType) throws
84     ZoomException {
85     if (closed) {
86       throw new IllegalStateException("Connection is closed.");
87     }
88     SWIGTYPE_p_ZOOM_query_p yazQuery = null;
89     if (queryType == QueryType.CQLQuery) {
90       yazQuery = yaz4jlib.ZOOM_query_create();
91       yaz4jlib.ZOOM_query_cql(yazQuery, query);
92     } else if (queryType == QueryType.PrefixQuery) {
93       yazQuery = yaz4jlib.ZOOM_query_create();
94       yaz4jlib.ZOOM_query_prefix(yazQuery, query);
95     }
96     SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search(
97       zoomConnection, yazQuery);
98     ZoomException err = ExceptionUtil.getError(zoomConnection, host,
99       port);
100     if (err != null) {
101       yaz4jlib.ZOOM_resultset_destroy(yazResultSet);
102       yaz4jlib.ZOOM_query_destroy(yazQuery);
103       throw err;
104     }
105     return new ResultSet(yazResultSet, this);
106   }
107
108   /**
109    * Performs a scan operation (obtains a list of candidate search terms against
110    * a particular access point)
111    * @see <a href="http://zoom.z3950.org/api/zoom-1.4.html#3.2.7">ZOOM-API Scan</a>
112    * @param query query for scanning
113    * @return a scan set with the terms
114    * @throws ZoomException a protocol or network-level error
115    */
116   public ScanSet scan(String query) throws ZoomException {
117     if (closed) {
118       throw new IllegalStateException("Connection is closed.");
119     }
120     SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan(
121       zoomConnection, query);
122     ZoomException err = ExceptionUtil.getError(zoomConnection, host, port);
123     if (err != null) {
124       yaz4jlib.ZOOM_scanset_destroy(yazScanSet);
125       throw err;
126     }
127     ScanSet scanSet = new ScanSet(yazScanSet, this);
128     return scanSet;
129   }
130
131   /**
132    * Establishes a connection to the remote server.
133    * @throws ZoomException any (possibly network-level) errors that may occurr
134    */
135   public void connect() throws ZoomException {
136     yaz4jlib.ZOOM_connection_connect(zoomConnection, host, port);
137     ZoomException err = ExceptionUtil.getError(zoomConnection, host, port);
138     if (err != null) {
139       throw err;
140     }
141     closed = false;
142   }
143
144   /**
145    * Closes the connection.
146    */
147   public void close() {
148     yaz4jlib.ZOOM_connection_close(zoomConnection);
149     closed = true;
150   }
151
152   /**
153    * Write option with a given name.
154    * @param name option name
155    * @param value option value
156    * @return connection (self) for chainability
157    */
158   public Connection option(String name, String value) {
159     yaz4jlib.ZOOM_connection_option_set(zoomConnection, name, value);
160     return this;
161   }
162
163   /**
164    * Read option with a given name
165    * @param name option name
166    * @return option value
167    */
168   public String option(String name) {
169     return yaz4jlib.ZOOM_connection_option_get(zoomConnection, name);
170   }
171
172   /**
173    * Same as option("preferredRecordSyntax")
174    * @return value of preferred record syntax
175    */
176   public String getSyntax() {
177     return option("preferredRecordSyntax");
178   }
179
180   /**
181    * Same as option("preferredRecordSyntax", value)
182    * @param value value of preferred record syntax
183    */
184   public void setSyntax(String value) {
185     option("preferredRecordSyntax", value);
186   }
187
188   /**
189    * Same as option("databaseName")
190    * @return value of databaseName
191    */
192   public String getDatabaseName() {
193     return option("databaseName");
194   }
195
196   /**
197    * Same as option("databaseName", value)
198    * @param value value of databaseName
199    */
200   public void setDatabaseName(String value) {
201     option("databaseName", value);
202   }
203
204   /**
205    * Same as option("user")
206    * @return value of user
207    */
208   public String getUsername() {
209     return option("user");
210   }
211
212   /**
213    * Same as option("user", value)
214    * @param value value of user
215    */
216   public void setUsername(String value) {
217     option("user", value);
218   }
219
220   /**
221    * Same as option("password")
222    * @return value of password
223    */
224   public String getPassword() {
225     return option("password");
226   }
227
228   /**
229    * Same as option("password", value)
230    * @param value
231    */
232   public void setPassword(String value) {
233     option("password", value);
234   }
235
236   /**
237    * INTERNAL, GC-ONLY
238    */
239   void _dispose() {
240     if (!disposed) {
241       yaz4jlib.ZOOM_connection_destroy(zoomConnection);
242       zoomConnection = null;
243       disposed = true;
244     }
245   }
246 }