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