From: Jakub Skoczen Date: Wed, 17 Feb 2010 13:28:20 +0000 (+0100) Subject: Refactor. X-Git-Tag: v1.1~9 X-Git-Url: http://git.indexdata.com/?p=yaz4j-moved-to-github.git;a=commitdiff_plain;h=51cc88d374e72f4c93a4721c2094e028a6ffae85 Refactor. Simplify the API. --- diff --git a/src/main/java/org/yaz4j/Bib1Diagnostic.java b/src/main/java/org/yaz4j/Bib1Diagnostic.java deleted file mode 100644 index ad08aef..0000000 --- a/src/main/java/org/yaz4j/Bib1Diagnostic.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.yaz4j; - -import java.util.Hashtable; - -class Bib1Diagnostic { - - private static Hashtable errorCodes = new Hashtable(); - - static { - errorCodes.put(1, "PermanentSystemError"); - errorCodes.put(2, "TemporarySystemError"); - errorCodes.put(3, "UnsupportedSearch"); - errorCodes.put(4, "TermsOnlyIncludesExclusionOrStopWords"); - errorCodes.put(5, "TooManyArgumentWords"); - errorCodes.put(6, "TooManyBooleanOperators"); - errorCodes.put(7, "TooManyTruncatedWords"); - errorCodes.put(8, "TooManyIncompleteSubfields"); - errorCodes.put(9, "TruncatedWordsTooShort"); - errorCodes.put(10, "InvalidFormatForRecordNumberInSearchTerm"); - errorCodes.put(11, "TooManyCharactersInSearchStatement"); - errorCodes.put(12, "TooManyRecordsRetrieved"); - errorCodes.put(13, "PresentRequestOutOfRange"); - errorCodes.put(14, "SystemErrorInPresentingRecords"); - errorCodes.put(15, "RecordNotAuthorizedToBeSentIntersystem"); - errorCodes.put(16, "RecordExceedsPreferredMessageSize"); - errorCodes.put(17, "RecordExceedsExceptionalRecordSize"); - errorCodes.put(18, "ResultSetNotSupportedAsASearchTerm"); - errorCodes.put(19, "OnlySingleResultSetAsSearchTermSupported"); - errorCodes.put(20, "OnlyAndingOfASingleResultSetAsSearchTerm"); - errorCodes.put(21, "ResultSetExistsAndReplaceIndicatorOff"); - errorCodes.put(22, "ResultSetNamingNotSupported"); - errorCodes.put(23, "SpecifiedCombinationOfDatabasesNotSupported"); - errorCodes.put(24, "ElementSetNamesNotSupported"); - errorCodes.put(25, "SpecifiedElementSetNameNotValidForSpecifiedDatabase"); - errorCodes.put(26, "OnlyGenericFormOfElementSetNameSupported"); - errorCodes.put(27, "ResultSetNoLongerExistsUnilaterallyDeletedByTarget"); - errorCodes.put(28, "ResultSetIsInUse"); - errorCodes.put(29, "OneOfTheSpecifiedDatabasesIsLocked"); - errorCodes.put(30, "SpecifiedResultSetDoesNotExist"); - errorCodes.put(31, "ResourcesExhaustedNoResultsAvailable"); - errorCodes.put(32, "ResourcesExhaustedUnpredictablePartialResultsAvailable"); - errorCodes.put(33, "ResourcesExhaustedValidSubsetOfResultsAvailable"); - errorCodes.put(100, "UnspecifiedError"); - errorCodes.put(101, "AccessControlFailure"); - errorCodes.put(102, "ChallengeRequiredCouldNotBeIssuedOperationTerminated"); - errorCodes.put(103, "ChallengeRequiredCouldNotBeIssuedRecordNotIncluded"); - errorCodes.put(104, "ChallengeFailedRecordNotIncluded"); - errorCodes.put(105, "TerminatedAtOriginRequest"); - errorCodes.put(106, "NoAbstractSyntaxesAgreedToForThisRecord"); - errorCodes.put(107, "QueryTypeNotSupported"); - errorCodes.put(108, "MalformedQuery"); - errorCodes.put(109, "DatabaseUnavailable"); - errorCodes.put(110, "OperatorUnsupported"); - errorCodes.put(111, "TooManyDatabasesSpecified"); - errorCodes.put(112, "TooManyResultSetsCreated"); - errorCodes.put(113, "UnsupportedAttributeType"); - errorCodes.put(114, "UnsupportedUseAttribute"); - errorCodes.put(115, "UnsupportedTermValueForUseAttribute"); - errorCodes.put(116, "UseAttributeRequiredButNotSupplied"); - errorCodes.put(117, "UnsupportedRelationAttribute"); - errorCodes.put(118, "UnsupportedStructureAttribute"); - errorCodes.put(119, "UnsupportedPositionAttribute"); - errorCodes.put(120, "UnsupportedTruncationAttribute"); - errorCodes.put(121, "UnsupportedAttributeSet"); - errorCodes.put(122, "UnsupportedCompletenessAttribute"); - errorCodes.put(123, "UnsupportedAttributeCombination"); - errorCodes.put(124, "UnsupportedCodedValueForTerm"); - errorCodes.put(125, "MalformedSearchTerm"); - errorCodes.put(126, "IllegalTermValueForAttribute"); - errorCodes.put(127, "UnparsableFormatForUnNormalizedValue"); - errorCodes.put(128, "IllegalResultSetName"); - errorCodes.put(129, "ProximitySearchOfSetsNotSupported"); - errorCodes.put(130, "IllegalResultSetInProximitySearch"); - errorCodes.put(131, "UnsupportedProximityRelation"); - errorCodes.put(132, "UnsupportedProximityUnitCode"); - errorCodes.put(201, "ProximityNotSupportedWithThisAttributeCombinationAttribute"); - errorCodes.put(202, "UnsupportedDistanceForProximity"); - errorCodes.put(203, "OrderedFlagNotSupportedForProximity"); - errorCodes.put(205, "OnlyZeroStepSizeSupportedForScan"); - errorCodes.put(206, "SpecifiedStepSizeNotSupportedForScanStep"); - errorCodes.put(207, "CannotSortAccordingToSequence"); - errorCodes.put(208, "NoResultSetNameSuppliedOnSort"); - errorCodes.put(209, "GenericSortNotSupported"); - errorCodes.put(210, "DatabaseSpecificSortNotSupported"); - errorCodes.put(211, "TooManySortKeys"); - errorCodes.put(212, "DuplicateSortKeys"); - errorCodes.put(213, "UnsupportedMissingDataAction"); - errorCodes.put(214, "IllegalSortRelation"); - errorCodes.put(215, "IllegalCaseValue"); - errorCodes.put(216, "IllegalMissingDataAction"); - errorCodes.put(217, "SegmentationCannotGuaranteeRecordsWillFitInSpecifiedSegments"); - errorCodes.put(218, "EsPackageNameAlreadyInUse"); - errorCodes.put(219, "EsNoSuchPackageOnModifyDelete"); - errorCodes.put(220, "EsQuotaExceeded"); - errorCodes.put(221, "EsExtendedServiceTypeNotSupported"); - errorCodes.put(222, "EsPermissionDeniedOnEsIdNotAuthorized"); - errorCodes.put(223, "EsPermissionDeniedOnEsCannotModifyOrDelete"); - errorCodes.put(224, "EsImmediateExecutionFailed"); - errorCodes.put(225, "EsImmediateExecutionNotSupportedForThisService"); - errorCodes.put(226, "EsImmediateExecutionNotSupportedForTheseParameters"); - errorCodes.put(227, "NoDataAvailableInRequestedRecordSyntax"); - errorCodes.put(228, "ScanMalformedScan"); - errorCodes.put(229, "TermTypeNotSupported"); - errorCodes.put(230, "SortTooManyInputResults"); - errorCodes.put(231, "SortIncompatibleRecordFormats"); - errorCodes.put(232, "ScanTermListNotSupported"); - errorCodes.put(233, "ScanUnsupportedValueOfPositionInResponse"); - errorCodes.put(234, "TooManyIndexTermsProcessed"); - errorCodes.put(235, "DatabaseDoesNotExist"); - errorCodes.put(236, "AccessToSpecifiedDatabaseDenied"); - errorCodes.put(237, "SortIllegalSort"); - errorCodes.put(238, "RecordNotAvailableInRequestedSyntax"); - errorCodes.put(239, "RecordSyntaxNotSupported"); - errorCodes.put(240, "ScanResourcesExhaustedLookingForSatisfyingTerms"); - errorCodes.put(241, "ScanBeginningOrEndOfTermList"); - errorCodes.put(242, "SegmentationMaxSegmentSizeTooSmallToSegmentRecord"); - errorCodes.put(243, "PresentAdditionalRangesParameterNotSupported"); - errorCodes.put(244, "PresentCompSpecParameterNotSupported"); - errorCodes.put(245, "Type1QueryRestrictionOperandNotSupported"); - errorCodes.put(246, "Type1QueryComplexAttributevalueNotSupported"); - errorCodes.put(247, "Type1QueryAttributesetAsPartOfAttributeelementNotSupported"); - } - - public static String getError(int errorCode) { - String errorText = "Unknown Error"; - - if (errorCodes.containsKey(errorCode)) { - errorText = errorCodes.get(errorCode); - } - - return errorText; - } -} diff --git a/src/main/java/org/yaz4j/Bib1Exception.java b/src/main/java/org/yaz4j/Bib1Exception.java deleted file mode 100644 index 86d2877..0000000 --- a/src/main/java/org/yaz4j/Bib1Exception.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.yaz4j; - -public class Bib1Exception extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public Bib1Exception() { - super(); - } - - public Bib1Exception(String message) { - super(message); - } -} diff --git a/src/main/java/org/yaz4j/CQLQuery.java b/src/main/java/org/yaz4j/CQLQuery.java deleted file mode 100644 index b854a47..0000000 --- a/src/main/java/org/yaz4j/CQLQuery.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.yaz4j; - -public class CQLQuery { - - private String query = null; - - public CQLQuery(String query) { - this.query = query; - } - - public String getQueryString() { - return query; - } - - public void setQueryString(String query) { - this.query = query; - } -} diff --git a/src/main/java/org/yaz4j/Connection.java b/src/main/java/org/yaz4j/Connection.java index 537a4c9..1bd52fc 100644 --- a/src/main/java/org/yaz4j/Connection.java +++ b/src/main/java/org/yaz4j/Connection.java @@ -1,22 +1,34 @@ package org.yaz4j; +import org.yaz4j.exception.ZoomImplementationException; +import org.yaz4j.exception.ConnectionTimeoutException; +import org.yaz4j.exception.InitRejectedException; +import org.yaz4j.exception.Bib1Exception; +import org.yaz4j.exception.InvalidQueryException; +import org.yaz4j.exception.Bib1Diagnostic; +import org.yaz4j.exception.ConnectionUnavailableException; +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.SWIGTYPE_p_ZOOM_options_p; import org.yaz4j.jni.yaz4jlib; import org.yaz4j.jni.yaz4jlibConstants; 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; + final private SWIGTYPE_p_ZOOM_options_p options; + 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) @@ -24,7 +36,7 @@ public class Connection { try { // System.err.println( "Loading library '"+ System.mapLibraryName( libName ) + "'" ); System.loadLibrary(libName); - } catch (Throwable e) { + } catch (AbstractMethodError e) { System.err.println("Fatal Error: Failed to load library '" + System.mapLibraryName(libName) + "'"); e.printStackTrace(); } @@ -33,63 +45,15 @@ public class Connection { public Connection(String host, int port) { this.host = host; this.port = port; - - options = new ConnectionOptionsCollection(); - zoomConnection = yaz4jlib.ZOOM_connection_create(options.zoomOptions); - - //remove - SWIGTYPE_p_p_char cp = null; - SWIGTYPE_p_p_char addinfo = null; - int errorCode = yaz4jlib.ZOOM_connection_error(zoomConnection, cp, addinfo); - checkErrorCodeAndThrow(errorCode); + options = yaz4jlib.ZOOM_options_create(); } 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); - } + _dispose(); } - 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(); - + public ResultSet search(String query, QueryType queryType) throws ZoomException { + if (closed) throw new IllegalStateException("Connection is closed."); SWIGTYPE_p_ZOOM_query_p yazQuery = yaz4jlib.ZOOM_query_create(); ResultSet resultSet = null; @@ -118,8 +82,8 @@ public class Connection { return resultSet; } - public ScanSet scan(String query) { - ensureConnected(); + public ScanSet scan(String query) throws ZoomException { + if (closed) throw new IllegalStateException("Connection is closed."); SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan(zoomConnection, query); int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); @@ -132,60 +96,116 @@ public class Connection { return scanSet; } - public ConnectionOptionsCollection getOptions() { - return options; - } + /** + * Initiates the connection + */ + public void connect() throws ZoomException { + //this is temporary before ZOOM-C has proper close method, right now + // simply recreate connection + if (closed) + zoomConnection = yaz4jlib.ZOOM_connection_create(options); + yaz4jlib.ZOOM_connection_connect(zoomConnection, host, port); + int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); + checkErrorCodeAndThrow(errorCode); + closed = false; + } + + /** + * Closes the connection. + */ + public void close() { + if (!closed) { + yaz4jlib.ZOOM_connection_destroy(zoomConnection); + zoomConnection = null; + closed = true; + } + } + + private void checkErrorCodeAndThrow(int errorCode) throws ZoomException { + String message; - protected void ensureConnected() { - if (!connected) { - connect(); + 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); } } - public void connect() { - yaz4jlib.ZOOM_connection_connect(zoomConnection, host, port); - int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); - checkErrorCodeAndThrow(errorCode); - connected = true; + /** + * 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) { + yaz4jlib.ZOOM_options_set(options, name, value); + return this; } - public void dispose() { - if (!disposed) { - yaz4jlib.ZOOM_connection_destroy(zoomConnection); - zoomConnection = null; - disposed = true; - } + /** + * Read option with a given name + * @param name option name + * @return option value + */ + public String option(String name) { + return yaz4jlib.ZOOM_options_get(options, name); } public String getSyntax() { - return options.get("preferredRecordSyntax"); + return option("preferredRecordSyntax"); } public void setSyntax(String value) { - options.set("preferredRecordSyntax", value); + option("preferredRecordSyntax", value); } public String getDatabaseName() { - return options.get("databaseName"); + return option("databaseName"); } public void setDatabaseName(String value) { - options.set("databaseName", value); + option("databaseName", value); } public String getUsername() { - return options.get("user"); + return option("user"); } public void setUsername(String value) { - options.set("user", value); + option("user", value); } public String getPassword() { - return options.get("password"); + return option("password"); } public void setPassword(String value) { - options.set("password", value); + option("password", value); + } + + /** + * INTERNAL, GC-ONLY + */ + void _dispose() { + if (!disposed) { + close(); + disposed = true; + } } } diff --git a/src/main/java/org/yaz4j/ConnectionExtended.java b/src/main/java/org/yaz4j/ConnectionExtended.java index a617f0d..095d9ce 100644 --- a/src/main/java/org/yaz4j/ConnectionExtended.java +++ b/src/main/java/org/yaz4j/ConnectionExtended.java @@ -11,11 +11,9 @@ public class ConnectionExtended extends Connection { } public Package getPackage(String type) { - ensureConnected(); + if (closed) throw new IllegalStateException("Connection is closed."); Package pack = null; - SWIGTYPE_p_ZOOM_options_p options = yaz4jlib.ZOOM_options_create(); - SWIGTYPE_p_ZOOM_package_p yazPackage = yaz4jlib.ZOOM_connection_package(zoomConnection, options); pack = new Package(yazPackage, this, type); return pack; diff --git a/src/main/java/org/yaz4j/ConnectionOptionsCollection.java b/src/main/java/org/yaz4j/ConnectionOptionsCollection.java deleted file mode 100644 index 0f4e449..0000000 --- a/src/main/java/org/yaz4j/ConnectionOptionsCollection.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.yaz4j; - -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_connection_p; -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_options_p; -import org.yaz4j.jni.yaz4jlib; - -public class ConnectionOptionsCollection { - - SWIGTYPE_p_ZOOM_options_p zoomOptions = null; - - ConnectionOptionsCollection() { - zoomOptions = yaz4jlib.ZOOM_options_create(); - } - - public void finalize() { - dispose(); - } - - public void dispose() { - yaz4jlib.ZOOM_options_destroy(zoomOptions); - zoomOptions = null; - } - - SWIGTYPE_p_ZOOM_connection_p createConnection() { - return yaz4jlib.ZOOM_connection_create(zoomOptions); - } - - public String get(String key) { - return yaz4jlib.ZOOM_options_get(zoomOptions, key); - } - - public void set(String key, String value) { - yaz4jlib.ZOOM_options_set(zoomOptions, key, value); - } -} diff --git a/src/main/java/org/yaz4j/ConnectionTimeoutException.java b/src/main/java/org/yaz4j/ConnectionTimeoutException.java deleted file mode 100644 index 7cf88ec..0000000 --- a/src/main/java/org/yaz4j/ConnectionTimeoutException.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.yaz4j; - -public class ConnectionTimeoutException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public ConnectionTimeoutException() { - super(); - } - - public ConnectionTimeoutException(String message) { - super(message); - } -} diff --git a/src/main/java/org/yaz4j/ConnectionUnavailableException.java b/src/main/java/org/yaz4j/ConnectionUnavailableException.java deleted file mode 100644 index 283ec30..0000000 --- a/src/main/java/org/yaz4j/ConnectionUnavailableException.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.yaz4j; - -public class ConnectionUnavailableException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public ConnectionUnavailableException() { - super(); - } - - public ConnectionUnavailableException(String message) { - super(message); - } -} diff --git a/src/main/java/org/yaz4j/InitRejectedException.java b/src/main/java/org/yaz4j/InitRejectedException.java deleted file mode 100644 index 3cd9893..0000000 --- a/src/main/java/org/yaz4j/InitRejectedException.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.yaz4j; - -public class InitRejectedException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public InitRejectedException() { - super(); - } - - public InitRejectedException(String message) { - super(message); - } -} diff --git a/src/main/java/org/yaz4j/InvalidQueryException.java b/src/main/java/org/yaz4j/InvalidQueryException.java deleted file mode 100644 index 23edfae..0000000 --- a/src/main/java/org/yaz4j/InvalidQueryException.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.yaz4j; - -public class InvalidQueryException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public InvalidQueryException() { - super(); - } - - public InvalidQueryException(String message) { - super(message); - } -} diff --git a/src/main/java/org/yaz4j/Package.java b/src/main/java/org/yaz4j/Package.java index 5bd6461..c5671b3 100644 --- a/src/main/java/org/yaz4j/Package.java +++ b/src/main/java/org/yaz4j/Package.java @@ -4,9 +4,8 @@ import org.yaz4j.jni.SWIGTYPE_p_ZOOM_package_p; import org.yaz4j.jni.yaz4jlib; public class Package { - - private SWIGTYPE_p_ZOOM_package_p pack = null; - private ConnectionExtended connection = null; + private SWIGTYPE_p_ZOOM_package_p pack; + private ConnectionExtended connection; private String type; Package(SWIGTYPE_p_ZOOM_package_p pack, ConnectionExtended connection, String type) { @@ -16,18 +15,37 @@ public class Package { } public void finalize() { - dispose(); + _dispose(); + } + + /** + * Write option for a specified key + * @param key option name + * @param value option value + * @return package (self) for chainability + */ + public Package option(String key, String value) { + yaz4jlib.ZOOM_package_option_set(pack, key, value); + return this; } - public PackageOptionsCollection getPackageOptions() { - return new PackageOptionsCollection(pack); + /** + * Read option for a specified key. + * @param key option name + * @return option value + */ + public String option(String key) { + return yaz4jlib.ZOOM_package_option_get(pack, key); } + /** + * Send the package. + */ public void send() { yaz4jlib.ZOOM_package_send(pack, type); } - public void dispose() { + void _dispose() { if (pack != null) { yaz4jlib.ZOOM_package_destroy(pack); connection = null; diff --git a/src/main/java/org/yaz4j/PackageOptionsCollection.java b/src/main/java/org/yaz4j/PackageOptionsCollection.java deleted file mode 100644 index bb4d0f2..0000000 --- a/src/main/java/org/yaz4j/PackageOptionsCollection.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.yaz4j; - -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_package_p; -import org.yaz4j.jni.yaz4jlib; - -public class PackageOptionsCollection { - - private SWIGTYPE_p_ZOOM_package_p pack = null; - - PackageOptionsCollection(SWIGTYPE_p_ZOOM_package_p pack) { - this.pack = pack; - } - - public void dispose() { - pack = null; - } - - public String get(String key) { - return yaz4jlib.ZOOM_package_option_get(pack, key); - } - - public void set(String key, String value) { - yaz4jlib.ZOOM_package_option_set(pack, key, value); - } -} diff --git a/src/main/java/org/yaz4j/PrefixQuery.java b/src/main/java/org/yaz4j/PrefixQuery.java deleted file mode 100644 index 54f144b..0000000 --- a/src/main/java/org/yaz4j/PrefixQuery.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.yaz4j; - -public class PrefixQuery { - - private String query = null; - - public PrefixQuery(String query) { - this.query = query; - } - - public String getQueryString() { - return query; - } - - public void setQueryString(String query) { - this.query = query; - } -} diff --git a/src/main/java/org/yaz4j/Record.java b/src/main/java/org/yaz4j/Record.java index b1a93ca..50fa381 100644 --- a/src/main/java/org/yaz4j/Record.java +++ b/src/main/java/org/yaz4j/Record.java @@ -16,7 +16,7 @@ public class Record { } public void finalize() { - dispose(); + _dispose(); } public byte[] get(String type) { @@ -40,7 +40,7 @@ public class Record { return new String(get("database")); } - public void dispose() { + void _dispose() { if (!disposed) { resultSet = null; record = null; diff --git a/src/main/java/org/yaz4j/ResultSet.java b/src/main/java/org/yaz4j/ResultSet.java index 74903c9..74275a1 100644 --- a/src/main/java/org/yaz4j/ResultSet.java +++ b/src/main/java/org/yaz4j/ResultSet.java @@ -23,8 +23,24 @@ public class ResultSet { this._dispose(); } - ResultSetOptionsCollection getResultSetOptions() { - return new ResultSetOptionsCollection(resultSet); + /** + * Read option by name. + * @param name option name + * @return option value + */ + public String option(String name) { + return yaz4jlib.ZOOM_resultset_option_get(resultSet, name); + } + + /** + * Write option with a given name. + * @param name option name + * @param value option value + * @return result set (self) for chainability + */ + public ResultSet option(String name, String value) { + yaz4jlib.ZOOM_resultset_option_set(resultSet, name, value); + return this; } public Record getRecord(int index) { @@ -44,4 +60,4 @@ public class ResultSet { disposed = true; } } -} +} \ No newline at end of file diff --git a/src/main/java/org/yaz4j/ResultSetOptionsCollection.java b/src/main/java/org/yaz4j/ResultSetOptionsCollection.java deleted file mode 100644 index 7125a67..0000000 --- a/src/main/java/org/yaz4j/ResultSetOptionsCollection.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.yaz4j; - -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p; -import org.yaz4j.jni.yaz4jlib; - -public class ResultSetOptionsCollection { - - private SWIGTYPE_p_ZOOM_resultset_p resultSet = null; - - ResultSetOptionsCollection(SWIGTYPE_p_ZOOM_resultset_p resultSet) { - this.resultSet = resultSet; - } - - public void finalize() { - resultSet = null; - } - - public String get(String key) { - return yaz4jlib.ZOOM_resultset_option_get(resultSet, key); - } - - public void set(String key, String value) { - yaz4jlib.ZOOM_resultset_option_set(resultSet, key, value); - } -} diff --git a/src/main/java/org/yaz4j/ScanSet.java b/src/main/java/org/yaz4j/ScanSet.java index 2140cc5..e34cebf 100644 --- a/src/main/java/org/yaz4j/ScanSet.java +++ b/src/main/java/org/yaz4j/ScanSet.java @@ -17,7 +17,7 @@ public class ScanSet { } public void finalize() { - dispose(); + _dispose(); } public ScanTerm get(long index) { @@ -34,7 +34,7 @@ public class ScanSet { return yaz4jlib.ZOOM_scanset_size(scanSet); } - public void dispose() { + void _dispose() { if (!disposed) { yaz4jlib.ZOOM_scanset_destroy(scanSet); connection = null; diff --git a/src/main/java/org/yaz4j/Yaz4jMain.java b/src/main/java/org/yaz4j/Yaz4jMain.java index 3964682..dbe711c 100644 --- a/src/main/java/org/yaz4j/Yaz4jMain.java +++ b/src/main/java/org/yaz4j/Yaz4jMain.java @@ -2,19 +2,20 @@ package org.yaz4j; import java.io.UnsupportedEncodingException; import java.io.IOException; +import org.yaz4j.exception.ZoomException; public class Yaz4jMain { // java -cp ./bin: -Djava.library.path=./libyaz4j org.yaz4j.Yaz4jMain public static void main(String[] args) throws UnsupportedEncodingException, IOException { - Connection conn = new Connection("talisbase.talis.com", 210); + Connection conn = new Connection("talisbase.talis.com", 210); + try { conn.setDatabaseName("unionm21"); conn.setUsername("fred"); conn.setPassword("apple"); conn.setSyntax("USMarc"); // USMarc, Sutrs, XML, opac, UKMarc - PrefixQuery query = new PrefixQuery("@attr 1=4 \"pottering\""); - ResultSet results = conn.search(query); + ResultSet results = conn.search("@attr 1=4 \"pottering\"", Connection.QueryType.PrefixQuery); long resultsSize = results.getSize(); System.out.println("Found " + resultsSize + " records"); @@ -23,6 +24,11 @@ public class Yaz4jMain { Record record = results.getRecord(i); System.out.write(record.getContent()); } - conn.dispose(); + } catch (ZoomException ze) { + System.out.println(ze.getMessage()); + ze.printStackTrace(); + } finally { + conn.close(); + } } } diff --git a/src/main/java/org/yaz4j/ZoomImplementationException.java b/src/main/java/org/yaz4j/ZoomImplementationException.java deleted file mode 100644 index 9b92203..0000000 --- a/src/main/java/org/yaz4j/ZoomImplementationException.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.yaz4j; - -public class ZoomImplementationException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public ZoomImplementationException() { - super(); - } - - public ZoomImplementationException(String message) { - super(message); - } -} diff --git a/src/main/java/org/yaz4j/exception/Bib1Diagnostic.java b/src/main/java/org/yaz4j/exception/Bib1Diagnostic.java new file mode 100644 index 0000000..4b3d190 --- /dev/null +++ b/src/main/java/org/yaz4j/exception/Bib1Diagnostic.java @@ -0,0 +1,133 @@ +package org.yaz4j.exception; + +import java.util.Hashtable; + +public class Bib1Diagnostic { + + private final static Hashtable errorCodes = new Hashtable(); + + static { + errorCodes.put(1, "PermanentSystemError"); + errorCodes.put(2, "TemporarySystemError"); + errorCodes.put(3, "UnsupportedSearch"); + errorCodes.put(4, "TermsOnlyIncludesExclusionOrStopWords"); + errorCodes.put(5, "TooManyArgumentWords"); + errorCodes.put(6, "TooManyBooleanOperators"); + errorCodes.put(7, "TooManyTruncatedWords"); + errorCodes.put(8, "TooManyIncompleteSubfields"); + errorCodes.put(9, "TruncatedWordsTooShort"); + errorCodes.put(10, "InvalidFormatForRecordNumberInSearchTerm"); + errorCodes.put(11, "TooManyCharactersInSearchStatement"); + errorCodes.put(12, "TooManyRecordsRetrieved"); + errorCodes.put(13, "PresentRequestOutOfRange"); + errorCodes.put(14, "SystemErrorInPresentingRecords"); + errorCodes.put(15, "RecordNotAuthorizedToBeSentIntersystem"); + errorCodes.put(16, "RecordExceedsPreferredMessageSize"); + errorCodes.put(17, "RecordExceedsExceptionalRecordSize"); + errorCodes.put(18, "ResultSetNotSupportedAsASearchTerm"); + errorCodes.put(19, "OnlySingleResultSetAsSearchTermSupported"); + errorCodes.put(20, "OnlyAndingOfASingleResultSetAsSearchTerm"); + errorCodes.put(21, "ResultSetExistsAndReplaceIndicatorOff"); + errorCodes.put(22, "ResultSetNamingNotSupported"); + errorCodes.put(23, "SpecifiedCombinationOfDatabasesNotSupported"); + errorCodes.put(24, "ElementSetNamesNotSupported"); + errorCodes.put(25, "SpecifiedElementSetNameNotValidForSpecifiedDatabase"); + errorCodes.put(26, "OnlyGenericFormOfElementSetNameSupported"); + errorCodes.put(27, "ResultSetNoLongerExistsUnilaterallyDeletedByTarget"); + errorCodes.put(28, "ResultSetIsInUse"); + errorCodes.put(29, "OneOfTheSpecifiedDatabasesIsLocked"); + errorCodes.put(30, "SpecifiedResultSetDoesNotExist"); + errorCodes.put(31, "ResourcesExhaustedNoResultsAvailable"); + errorCodes.put(32, "ResourcesExhaustedUnpredictablePartialResultsAvailable"); + errorCodes.put(33, "ResourcesExhaustedValidSubsetOfResultsAvailable"); + errorCodes.put(100, "UnspecifiedError"); + errorCodes.put(101, "AccessControlFailure"); + errorCodes.put(102, "ChallengeRequiredCouldNotBeIssuedOperationTerminated"); + errorCodes.put(103, "ChallengeRequiredCouldNotBeIssuedRecordNotIncluded"); + errorCodes.put(104, "ChallengeFailedRecordNotIncluded"); + errorCodes.put(105, "TerminatedAtOriginRequest"); + errorCodes.put(106, "NoAbstractSyntaxesAgreedToForThisRecord"); + errorCodes.put(107, "QueryTypeNotSupported"); + errorCodes.put(108, "MalformedQuery"); + errorCodes.put(109, "DatabaseUnavailable"); + errorCodes.put(110, "OperatorUnsupported"); + errorCodes.put(111, "TooManyDatabasesSpecified"); + errorCodes.put(112, "TooManyResultSetsCreated"); + errorCodes.put(113, "UnsupportedAttributeType"); + errorCodes.put(114, "UnsupportedUseAttribute"); + errorCodes.put(115, "UnsupportedTermValueForUseAttribute"); + errorCodes.put(116, "UseAttributeRequiredButNotSupplied"); + errorCodes.put(117, "UnsupportedRelationAttribute"); + errorCodes.put(118, "UnsupportedStructureAttribute"); + errorCodes.put(119, "UnsupportedPositionAttribute"); + errorCodes.put(120, "UnsupportedTruncationAttribute"); + errorCodes.put(121, "UnsupportedAttributeSet"); + errorCodes.put(122, "UnsupportedCompletenessAttribute"); + errorCodes.put(123, "UnsupportedAttributeCombination"); + errorCodes.put(124, "UnsupportedCodedValueForTerm"); + errorCodes.put(125, "MalformedSearchTerm"); + errorCodes.put(126, "IllegalTermValueForAttribute"); + errorCodes.put(127, "UnparsableFormatForUnNormalizedValue"); + errorCodes.put(128, "IllegalResultSetName"); + errorCodes.put(129, "ProximitySearchOfSetsNotSupported"); + errorCodes.put(130, "IllegalResultSetInProximitySearch"); + errorCodes.put(131, "UnsupportedProximityRelation"); + errorCodes.put(132, "UnsupportedProximityUnitCode"); + errorCodes.put(201, "ProximityNotSupportedWithThisAttributeCombinationAttribute"); + errorCodes.put(202, "UnsupportedDistanceForProximity"); + errorCodes.put(203, "OrderedFlagNotSupportedForProximity"); + errorCodes.put(205, "OnlyZeroStepSizeSupportedForScan"); + errorCodes.put(206, "SpecifiedStepSizeNotSupportedForScanStep"); + errorCodes.put(207, "CannotSortAccordingToSequence"); + errorCodes.put(208, "NoResultSetNameSuppliedOnSort"); + errorCodes.put(209, "GenericSortNotSupported"); + errorCodes.put(210, "DatabaseSpecificSortNotSupported"); + errorCodes.put(211, "TooManySortKeys"); + errorCodes.put(212, "DuplicateSortKeys"); + errorCodes.put(213, "UnsupportedMissingDataAction"); + errorCodes.put(214, "IllegalSortRelation"); + errorCodes.put(215, "IllegalCaseValue"); + errorCodes.put(216, "IllegalMissingDataAction"); + errorCodes.put(217, "SegmentationCannotGuaranteeRecordsWillFitInSpecifiedSegments"); + errorCodes.put(218, "EsPackageNameAlreadyInUse"); + errorCodes.put(219, "EsNoSuchPackageOnModifyDelete"); + errorCodes.put(220, "EsQuotaExceeded"); + errorCodes.put(221, "EsExtendedServiceTypeNotSupported"); + errorCodes.put(222, "EsPermissionDeniedOnEsIdNotAuthorized"); + errorCodes.put(223, "EsPermissionDeniedOnEsCannotModifyOrDelete"); + errorCodes.put(224, "EsImmediateExecutionFailed"); + errorCodes.put(225, "EsImmediateExecutionNotSupportedForThisService"); + errorCodes.put(226, "EsImmediateExecutionNotSupportedForTheseParameters"); + errorCodes.put(227, "NoDataAvailableInRequestedRecordSyntax"); + errorCodes.put(228, "ScanMalformedScan"); + errorCodes.put(229, "TermTypeNotSupported"); + errorCodes.put(230, "SortTooManyInputResults"); + errorCodes.put(231, "SortIncompatibleRecordFormats"); + errorCodes.put(232, "ScanTermListNotSupported"); + errorCodes.put(233, "ScanUnsupportedValueOfPositionInResponse"); + errorCodes.put(234, "TooManyIndexTermsProcessed"); + errorCodes.put(235, "DatabaseDoesNotExist"); + errorCodes.put(236, "AccessToSpecifiedDatabaseDenied"); + errorCodes.put(237, "SortIllegalSort"); + errorCodes.put(238, "RecordNotAvailableInRequestedSyntax"); + errorCodes.put(239, "RecordSyntaxNotSupported"); + errorCodes.put(240, "ScanResourcesExhaustedLookingForSatisfyingTerms"); + errorCodes.put(241, "ScanBeginningOrEndOfTermList"); + errorCodes.put(242, "SegmentationMaxSegmentSizeTooSmallToSegmentRecord"); + errorCodes.put(243, "PresentAdditionalRangesParameterNotSupported"); + errorCodes.put(244, "PresentCompSpecParameterNotSupported"); + errorCodes.put(245, "Type1QueryRestrictionOperandNotSupported"); + errorCodes.put(246, "Type1QueryComplexAttributevalueNotSupported"); + errorCodes.put(247, "Type1QueryAttributesetAsPartOfAttributeelementNotSupported"); + } + + public static String getError(int errorCode) { + String errorText = "Unknown Error"; + + if (errorCodes.containsKey(errorCode)) { + errorText = errorCodes.get(errorCode); + } + + return errorText; + } +} diff --git a/src/main/java/org/yaz4j/exception/Bib1Exception.java b/src/main/java/org/yaz4j/exception/Bib1Exception.java new file mode 100644 index 0000000..3ead83d --- /dev/null +++ b/src/main/java/org/yaz4j/exception/Bib1Exception.java @@ -0,0 +1,14 @@ +package org.yaz4j.exception; + +public class Bib1Exception extends ZoomException { + + private static final long serialVersionUID = 1L; + + public Bib1Exception() { + super(); + } + + public Bib1Exception(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/org/yaz4j/exception/ConnectionTimeoutException.java b/src/main/java/org/yaz4j/exception/ConnectionTimeoutException.java new file mode 100644 index 0000000..73b7fe1 --- /dev/null +++ b/src/main/java/org/yaz4j/exception/ConnectionTimeoutException.java @@ -0,0 +1,14 @@ +package org.yaz4j.exception; + +public class ConnectionTimeoutException extends ZoomException { + + private static final long serialVersionUID = 1L; + + public ConnectionTimeoutException() { + super(); + } + + public ConnectionTimeoutException(String message) { + super(message); + } +} diff --git a/src/main/java/org/yaz4j/exception/ConnectionUnavailableException.java b/src/main/java/org/yaz4j/exception/ConnectionUnavailableException.java new file mode 100644 index 0000000..1d14e45 --- /dev/null +++ b/src/main/java/org/yaz4j/exception/ConnectionUnavailableException.java @@ -0,0 +1,14 @@ +package org.yaz4j.exception; + +public class ConnectionUnavailableException extends ZoomException { + + private static final long serialVersionUID = 1L; + + public ConnectionUnavailableException() { + super(); + } + + public ConnectionUnavailableException(String message) { + super(message); + } +} diff --git a/src/main/java/org/yaz4j/exception/InitRejectedException.java b/src/main/java/org/yaz4j/exception/InitRejectedException.java new file mode 100644 index 0000000..38fb09f --- /dev/null +++ b/src/main/java/org/yaz4j/exception/InitRejectedException.java @@ -0,0 +1,13 @@ +package org.yaz4j.exception; + +public class InitRejectedException extends ZoomException { + + + public InitRejectedException() { + super(); + } + + public InitRejectedException(String message) { + super(message); + } +} diff --git a/src/main/java/org/yaz4j/exception/InvalidQueryException.java b/src/main/java/org/yaz4j/exception/InvalidQueryException.java new file mode 100644 index 0000000..3ed1592 --- /dev/null +++ b/src/main/java/org/yaz4j/exception/InvalidQueryException.java @@ -0,0 +1,14 @@ +package org.yaz4j.exception; + +public class InvalidQueryException extends ZoomException { + + private static final long serialVersionUID = 1L; + + public InvalidQueryException() { + super(); + } + + public InvalidQueryException(String message) { + super(message); + } +} diff --git a/src/main/java/org/yaz4j/exception/ZoomException.java b/src/main/java/org/yaz4j/exception/ZoomException.java new file mode 100644 index 0000000..74a069d --- /dev/null +++ b/src/main/java/org/yaz4j/exception/ZoomException.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 1995-2010, Index Data + * All rights reserved. + * See the file LICENSE for details. + */ + +package org.yaz4j.exception; + +/** + * Generic exception representing any ZOOM-C error situation. + * @author jakub + */ +public class ZoomException extends Exception { + + public ZoomException() { + super(); + } + + public ZoomException(String msg) { + super(msg); + } + +} diff --git a/src/main/java/org/yaz4j/exception/ZoomImplementationException.java b/src/main/java/org/yaz4j/exception/ZoomImplementationException.java new file mode 100644 index 0000000..793615f --- /dev/null +++ b/src/main/java/org/yaz4j/exception/ZoomImplementationException.java @@ -0,0 +1,14 @@ +package org.yaz4j.exception; + +public class ZoomImplementationException extends ZoomException { + + private static final long serialVersionUID = 1L; + + public ZoomImplementationException() { + super(); + } + + public ZoomImplementationException(String message) { + super(message); + } +} diff --git a/src/test/java/yaz4jtest/ConnectionTest.java b/src/test/java/yaz4jtest/ConnectionTest.java index 2550f5b..9a73b6a 100644 --- a/src/test/java/yaz4jtest/ConnectionTest.java +++ b/src/test/java/yaz4jtest/ConnectionTest.java @@ -2,7 +2,8 @@ package yaz4jtest; import org.junit.*; import static org.junit.Assert.*; -import java.util.*; +import org.yaz4j.Connection.QueryType; +import org.yaz4j.exception.ZoomException; public class ConnectionTest { @@ -10,20 +11,25 @@ public class ConnectionTest { public void testConnection() { org.yaz4j.Connection con = new org.yaz4j.Connection("z3950.indexdata.dk:210/gils", 0); assertNotNull(con); - con.setSyntax("sutrs"); - org.yaz4j.PrefixQuery pqf = new org.yaz4j.PrefixQuery("@attr 1=4 utah"); - assertNotNull(pqf); - org.yaz4j.ResultSet s = con.search(pqf); - assertNotNull(s); - assertEquals(s.getSize(), 9); - org.yaz4j.Record rec = s.getRecord(0); - assertNotNull(rec); - byte[] content = rec.getContent(); - // first SUTRS record - assertEquals(content.length, 1940); - assertEquals(content[0], 103); - assertEquals(rec.getSyntax(), "SUTRS"); - assertEquals(rec.getDatabase(), "gils"); - + try { + con.setSyntax("sutrs"); + System.out.println("Open connection to z3950.indexdata.dk:210/gils..."); + con.connect(); + org.yaz4j.ResultSet s = con.search("@attr 1=4 utah", QueryType.PrefixQuery); + assertNotNull(s); + assertEquals(s.getSize(), 9); + org.yaz4j.Record rec = s.getRecord(0); + assertNotNull(rec); + byte[] content = rec.getContent(); + // first SUTRS record + assertEquals(content.length, 1940); + assertEquals(content[0], 103); + assertEquals(rec.getSyntax(), "SUTRS"); + assertEquals(rec.getDatabase(), "gils"); + } catch (ZoomException ze) { + fail(ze.getMessage()); + } finally { + con.close(); + } } } diff --git a/src/test/java/yaz4jtest/DinosaurTest.java b/src/test/java/yaz4jtest/DinosaurTest.java index efc2247..44c9876 100644 --- a/src/test/java/yaz4jtest/DinosaurTest.java +++ b/src/test/java/yaz4jtest/DinosaurTest.java @@ -3,6 +3,7 @@ package yaz4jtest; import org.junit.*; import static org.junit.Assert.*; import org.yaz4j.*; +import org.yaz4j.exception.ZoomException; /** * @author adam @@ -12,14 +13,18 @@ public class DinosaurTest { @Test public void test() { Connection con = new Connection("z3950.loc.gov:7090/voyager", 0); + try { assertNotNull(con); con.setSyntax("usmarc"); - PrefixQuery pqf = new PrefixQuery("@attr 1=7 0253333490"); - assertNotNull(pqf); - ResultSet set = con.search(pqf); + con.connect(); + ResultSet set = con.search("@attr 1=7 0253333490", Connection.QueryType.PrefixQuery); assertNotNull(set); Record rec = set.getRecord(0); assertNotNull(rec); - // System.out.println(rec.render()); + } catch (ZoomException ze) { + fail(ze.getMessage()); + } finally { + con.close(); + } } }