From 428d895d6dc31b784e953ea935d662cfc4a4bd43 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 21 Sep 2009 15:31:54 +0200 Subject: [PATCH 1/1] Use Maven for building yaz4j. --- .classpath | 11 +- .gitignore | 3 +- .project | 26 ++- AUTHORS | 6 +- README | 10 +- build-windows.xml | 48 ---- build.xml | 61 ----- dependencies/JUnit-4.3.1/junit-4.3.1.jar | Bin 106547 -> 0 bytes libyaz4j/build.sh | 2 +- pom.xml | 173 ++++++++++++++ src/main/java/org/yaz4j/Bib1Diagnostic.java | 134 +++++++++++ src/main/java/org/yaz4j/Bib1Exception.java | 16 ++ src/main/java/org/yaz4j/CQLQuery.java | 21 ++ src/main/java/org/yaz4j/Connection.java | 235 ++++++++++++++++++++ src/main/java/org/yaz4j/ConnectionExtended.java | 25 +++ .../org/yaz4j/ConnectionOptionsCollection.java | 42 ++++ .../java/org/yaz4j/ConnectionTimeoutException.java | 16 ++ .../org/yaz4j/ConnectionUnavailableException.java | 16 ++ src/main/java/org/yaz4j/InitRejectedException.java | 16 ++ src/main/java/org/yaz4j/InvalidQueryException.java | 16 ++ src/main/java/org/yaz4j/Package.java | 43 ++++ .../java/org/yaz4j/PackageOptionsCollection.java | 29 +++ src/main/java/org/yaz4j/PrefixQuery.java | 21 ++ src/main/java/org/yaz4j/Record.java | 71 ++++++ src/main/java/org/yaz4j/ResultSet.java | 66 ++++++ .../java/org/yaz4j/ResultSetOptionsCollection.java | 29 +++ src/main/java/org/yaz4j/ScanSet.java | 50 +++++ src/main/java/org/yaz4j/ScanTerm.java | 23 ++ src/main/java/org/yaz4j/Yaz4jMain.java | 31 +++ .../org/yaz4j/ZoomImplementationException.java | 16 ++ src/main/java/org/yaz4j/jni/.gitignore | 1 + src/org/yaz4j/Bib1Diagnostic.java | 134 ----------- src/org/yaz4j/Bib1Exception.java | 16 -- src/org/yaz4j/CQLQuery.java | 21 -- src/org/yaz4j/Connection.java | 235 -------------------- src/org/yaz4j/ConnectionExtended.java | 25 --- src/org/yaz4j/ConnectionOptionsCollection.java | 42 ---- src/org/yaz4j/ConnectionTimeoutException.java | 16 -- src/org/yaz4j/ConnectionUnavailableException.java | 16 -- src/org/yaz4j/InitRejectedException.java | 16 -- src/org/yaz4j/InvalidQueryException.java | 16 -- src/org/yaz4j/Package.java | 43 ---- src/org/yaz4j/PackageOptionsCollection.java | 29 --- src/org/yaz4j/PrefixQuery.java | 21 -- src/org/yaz4j/Record.java | 71 ------ src/org/yaz4j/ResultSet.java | 66 ------ src/org/yaz4j/ResultSetOptionsCollection.java | 29 --- src/org/yaz4j/ScanSet.java | 50 ----- src/org/yaz4j/ScanTerm.java | 23 -- src/org/yaz4j/Yaz4jMain.java | 31 --- src/org/yaz4j/ZoomImplementationException.java | 16 -- src/org/yaz4j/jni/.gitignore | 1 - src/site/site.xml | 19 ++ src/test/java/yaz4jtest/ConnectionTest.java | 24 ++ test/ConnectionTest.java | 24 -- 55 files changed, 1162 insertions(+), 1079 deletions(-) delete mode 100644 build-windows.xml delete mode 100644 build.xml delete mode 100644 dependencies/JUnit-4.3.1/junit-4.3.1.jar create mode 100644 pom.xml create mode 100644 src/main/java/org/yaz4j/Bib1Diagnostic.java create mode 100644 src/main/java/org/yaz4j/Bib1Exception.java create mode 100644 src/main/java/org/yaz4j/CQLQuery.java create mode 100644 src/main/java/org/yaz4j/Connection.java create mode 100644 src/main/java/org/yaz4j/ConnectionExtended.java create mode 100644 src/main/java/org/yaz4j/ConnectionOptionsCollection.java create mode 100644 src/main/java/org/yaz4j/ConnectionTimeoutException.java create mode 100644 src/main/java/org/yaz4j/ConnectionUnavailableException.java create mode 100644 src/main/java/org/yaz4j/InitRejectedException.java create mode 100644 src/main/java/org/yaz4j/InvalidQueryException.java create mode 100644 src/main/java/org/yaz4j/Package.java create mode 100644 src/main/java/org/yaz4j/PackageOptionsCollection.java create mode 100644 src/main/java/org/yaz4j/PrefixQuery.java create mode 100644 src/main/java/org/yaz4j/Record.java create mode 100644 src/main/java/org/yaz4j/ResultSet.java create mode 100644 src/main/java/org/yaz4j/ResultSetOptionsCollection.java create mode 100644 src/main/java/org/yaz4j/ScanSet.java create mode 100644 src/main/java/org/yaz4j/ScanTerm.java create mode 100644 src/main/java/org/yaz4j/Yaz4jMain.java create mode 100644 src/main/java/org/yaz4j/ZoomImplementationException.java create mode 100644 src/main/java/org/yaz4j/jni/.gitignore delete mode 100644 src/org/yaz4j/Bib1Diagnostic.java delete mode 100644 src/org/yaz4j/Bib1Exception.java delete mode 100644 src/org/yaz4j/CQLQuery.java delete mode 100644 src/org/yaz4j/Connection.java delete mode 100644 src/org/yaz4j/ConnectionExtended.java delete mode 100644 src/org/yaz4j/ConnectionOptionsCollection.java delete mode 100644 src/org/yaz4j/ConnectionTimeoutException.java delete mode 100644 src/org/yaz4j/ConnectionUnavailableException.java delete mode 100644 src/org/yaz4j/InitRejectedException.java delete mode 100644 src/org/yaz4j/InvalidQueryException.java delete mode 100644 src/org/yaz4j/Package.java delete mode 100644 src/org/yaz4j/PackageOptionsCollection.java delete mode 100644 src/org/yaz4j/PrefixQuery.java delete mode 100644 src/org/yaz4j/Record.java delete mode 100644 src/org/yaz4j/ResultSet.java delete mode 100644 src/org/yaz4j/ResultSetOptionsCollection.java delete mode 100644 src/org/yaz4j/ScanSet.java delete mode 100644 src/org/yaz4j/ScanTerm.java delete mode 100644 src/org/yaz4j/Yaz4jMain.java delete mode 100644 src/org/yaz4j/ZoomImplementationException.java delete mode 100644 src/org/yaz4j/jni/.gitignore create mode 100644 src/site/site.xml create mode 100644 src/test/java/yaz4jtest/ConnectionTest.java delete mode 100644 test/ConnectionTest.java diff --git a/.classpath b/.classpath index c1e85ad..caa7eba 100644 --- a/.classpath +++ b/.classpath @@ -1,11 +1,8 @@ - - - - - + + + - - + diff --git a/.gitignore b/.gitignore index f904b11..eb5a316 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -bin -distributions +target diff --git a/.project b/.project index 0bf3351..1b79910 100644 --- a/.project +++ b/.project @@ -4,14 +4,20 @@ - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.iam.jdt.core.mavenIncrementalBuilder + + + + + + org.eclipse.iam.jdt.core.mavenNature + org.eclipse.jdt.core.javanature + diff --git a/AUTHORS b/AUTHORS index c40cdd9..e310170 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,7 +1,5 @@ -Most of the work on yaz4j was done by: - Rob Styles +Adam Dickmeiss +J. Cayetano -Current version is maintained by: -Adam Dickmeiss diff --git a/README b/README index 5f06606..b974b3e 100644 --- a/README +++ b/README @@ -7,11 +7,11 @@ Copyright (C) 2006-2007, Talis Group Ltd. Copyright (C) 2008-2009, Index Data. See LICENSE for details. -In order to built yaz4j the Java JDK, ant, YAZ and Swig must be installed. +In order to built yaz4j the Java JDK, Maven, YAZ and Swig must be installed. The exact process varies from platform to platform. For example, on Ubuntu/Debian the following installs the components: - apt-get install sun-java6-jdk ant libyaz3-dev swig + apt-get install sun-java6-jdk maven2 libyaz3-dev swig The compilation is a two-step process. The environment variable JAVA_HOME should point to the Java JDK of your preference. For example, @@ -21,9 +21,9 @@ Build the shared libary (.so) with: cd libyaz4j ./build.sh -Rest is built by ant which reads build.xml: +Rest is built by maven which reads pom.xml: cd .. - ant + mvn compile If you network-connected you should be able to run tests with: - ant unit-test + mvn test diff --git a/build-windows.xml b/build-windows.xml deleted file mode 100644 index 883c460..0000000 --- a/build-windows.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - Build the java side of Yaz4J - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build.xml b/build.xml deleted file mode 100644 index 16bc930..0000000 --- a/build.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - Build the java side of Yaz4J - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dependencies/JUnit-4.3.1/junit-4.3.1.jar b/dependencies/JUnit-4.3.1/junit-4.3.1.jar deleted file mode 100644 index ff5d1888fc7a8b1501711594c70dc80fe07dce29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106547 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 diff --git a/libyaz4j/build.sh b/libyaz4j/build.sh index 98f55d9..d4687ad 100755 --- a/libyaz4j/build.sh +++ b/libyaz4j/build.sh @@ -6,7 +6,7 @@ YAZ_PREFIX=`${YAZ_CONFIG} --prefix` YAZ_CFLAGS=`${YAZ_CONFIG} --cflags` YAZ_LIBS=`${YAZ_CONFIG} --libs` -swig -I"include" -I"${YAZ_PREFIX}/include" -outdir ../src/org/yaz4j/jni -package org.yaz4j.jni -o src/libyaz4j.cpp -c++ -java libyaz4j.i +swig -I"include" -I"${YAZ_PREFIX}/include" -outdir ../src/main/java/org/yaz4j/jni -package org.yaz4j.jni -o src/libyaz4j.cpp -c++ -java libyaz4j.i g++ -fPIC -I"include" -I"$JNI_DIR" -I"$JNI_DIR/linux" ${YAZ_CFLAGS} -c -Wall -o obj/libyaz4j.o src/libyaz4j.cpp diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..94760c0 --- /dev/null +++ b/pom.xml @@ -0,0 +1,173 @@ + + + + + 4.0.0 + org.yaz4j + yaz4j + 1.0-SNAPSHOT + jar + + + yaz4j + http://indexdata.com/yaz4j + 2008 + + + BSD + http://www.opensource.org/licenses/bsd-license.php + + + Java wrapper for the ZOOM API of YAZ + + + + Rob Styles + + Rob.Styles@talis.com + + + + + + + Adam Dickmeiss + + adam@indexdata.dk + + + + + + + + + + + + junit + junit + 4.3.1 + test + + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + UTF-8 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + UTF-8 + 1.5 + 1.5 + true + true + + + + + org.apache.maven.plugins + maven-surefire-plugin + + once + target + -Djava.library.path=${basedir}/libyaz4j/lib + + + + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + false + **/*.java + src/main/java + + + + + org.apache.maven.plugins + + maven-project-info-reports-plugin + + + + + dependencies + project-team + mailing-list + issue-tracking + summary + scm + index + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + UTF-8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/yaz4j/Bib1Diagnostic.java b/src/main/java/org/yaz4j/Bib1Diagnostic.java new file mode 100644 index 0000000..5dd8c11 --- /dev/null +++ b/src/main/java/org/yaz4j/Bib1Diagnostic.java @@ -0,0 +1,134 @@ +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 new file mode 100644 index 0000000..742b9ab --- /dev/null +++ b/src/main/java/org/yaz4j/Bib1Exception.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..1411e28 --- /dev/null +++ b/src/main/java/org/yaz4j/CQLQuery.java @@ -0,0 +1,21 @@ +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 new file mode 100644 index 0000000..2c5fcf2 --- /dev/null +++ b/src/main/java/org/yaz4j/Connection.java @@ -0,0 +1,235 @@ +package org.yaz4j; + +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.yaz4jlib; +import org.yaz4j.jni.yaz4jlibConstants; + +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +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; + private boolean disposed = false; + + 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) + String libName = "yaz4j" ; + try + { + // System.err.println( "Loading library '"+ System.mapLibraryName( libName ) + "'" ); + System.loadLibrary( libName ); + } + catch( Throwable e ) + { + System.err.println( "Fatal Error: Failed to load library '" + System.mapLibraryName( libName ) + "'"); + e.printStackTrace(); + } + } + + public Connection(String host, int port) + { + this.host = host ; + this.port = port ; + + options = new ConnectionOptionsCollection(); + zoomConnection = yaz4jlib.ZOOM_connection_create(options.zoomOptions); + + SWIGTYPE_p_p_char cp = null; + SWIGTYPE_p_p_char addinfo = null ; + int errorCode = yaz4jlib.ZOOM_connection_error(zoomConnection, cp, addinfo); + CheckErrorCodeAndThrow(errorCode); + } + + 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 ); + } + } + + 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(); + + SWIGTYPE_p_ZOOM_query_p yazQuery = yaz4jlib.ZOOM_query_create(); + ResultSet resultSet = null; + + try + { + if( queryType == QueryType.CQLQuery ) + yaz4jlib.ZOOM_query_cql(yazQuery, query); + else if( queryType == QueryType.PrefixQuery ) + yaz4jlib.ZOOM_query_prefix(yazQuery, query); + else + throw new NotImplementedException(); + + SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search(zoomConnection, yazQuery); + + int errorCode = yaz4jlib.ZOOM_connection_errcode( zoomConnection ); + if (errorCode != yaz4jlib.ZOOM_ERROR_NONE) + { + yaz4jlib.ZOOM_resultset_destroy(yazResultSet); + } + CheckErrorCodeAndThrow(errorCode); + + resultSet = new ResultSet(yazResultSet, zoomConnection); + } + finally + { + yaz4jlib.ZOOM_query_destroy(yazQuery); // deallocate yazQuery also when exceptions + yazQuery = null; + } + return resultSet; + } + + public ScanSet Scan(String query) + { + EnsureConnected(); + SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan(zoomConnection, query); + + int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); + if( errorCode != yaz4jlib.ZOOM_ERROR_NONE ) + { + yaz4jlib.ZOOM_scanset_destroy(yazScanSet); + } + CheckErrorCodeAndThrow(errorCode); + + ScanSet scanSet = new ScanSet(yazScanSet, this); + return scanSet; + } + + public ConnectionOptionsCollection getOptions() + { + return options; + } + + protected void EnsureConnected() + { + if (! connected ) + Connect(); + } + + public void Connect() + { + yaz4jlib.ZOOM_connection_connect( zoomConnection, host, port); + int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); + CheckErrorCodeAndThrow(errorCode); + connected = true; + } + + public void Dispose() + { + if (! disposed ) + { + yaz4jlib.ZOOM_connection_destroy(zoomConnection); + zoomConnection = null; + disposed = true; + } + } + + public String getSyntax() + { + return options.get("preferredRecordSyntax"); + } + + public void setSyntax( String value) + { + options.set("preferredRecordSyntax", value ) ; + } + + public String getDatabaseName() + { + return options.get("databaseName"); + } + + public void setDatabaseName( String value ) + { + options.set("databaseName", value); + } + + public String getUsername() + { + return options.get("user"); + } + + public void setUsername( String value ) + { + options.set("user", value); + } + + public String getPassword() + { + return options.get("password"); + } + + public void setPassword( String value ) + { + options.set("password", value); + } +} diff --git a/src/main/java/org/yaz4j/ConnectionExtended.java b/src/main/java/org/yaz4j/ConnectionExtended.java new file mode 100644 index 0000000..8d9744b --- /dev/null +++ b/src/main/java/org/yaz4j/ConnectionExtended.java @@ -0,0 +1,25 @@ +package org.yaz4j; + +import org.yaz4j.jni.SWIGTYPE_p_ZOOM_options_p; +import org.yaz4j.jni.SWIGTYPE_p_ZOOM_package_p; +import org.yaz4j.jni.yaz4jlib; + +public class ConnectionExtended extends Connection +{ + public ConnectionExtended(String host, int port) + { + super(host, port); + } + + public Package Package(String type) + { + EnsureConnected(); + 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 new file mode 100644 index 0000000..fb60263 --- /dev/null +++ b/src/main/java/org/yaz4j/ConnectionOptionsCollection.java @@ -0,0 +1,42 @@ +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 new file mode 100644 index 0000000..7f6c574 --- /dev/null +++ b/src/main/java/org/yaz4j/ConnectionTimeoutException.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..25c7226 --- /dev/null +++ b/src/main/java/org/yaz4j/ConnectionUnavailableException.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..83c3c8d --- /dev/null +++ b/src/main/java/org/yaz4j/InitRejectedException.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..4f265c2 --- /dev/null +++ b/src/main/java/org/yaz4j/InvalidQueryException.java @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..590b172 --- /dev/null +++ b/src/main/java/org/yaz4j/Package.java @@ -0,0 +1,43 @@ +package org.yaz4j; + +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 String type; + + Package(SWIGTYPE_p_ZOOM_package_p pack, ConnectionExtended connection, String type) + { + this.type = type; + this.connection = connection; + this.pack = pack; + } + + public void finalize() + { + Dispose(); + } + + public PackageOptionsCollection getPackageOptions() + { + return new PackageOptionsCollection(pack); + } + + public void Send() + { + yaz4jlib.ZOOM_package_send( pack, type ); + } + + public void Dispose() + { + if ( pack != null ) + { + yaz4jlib.ZOOM_package_destroy( pack ); + connection = null; + pack = null ; + } + } +} diff --git a/src/main/java/org/yaz4j/PackageOptionsCollection.java b/src/main/java/org/yaz4j/PackageOptionsCollection.java new file mode 100644 index 0000000..7cff946 --- /dev/null +++ b/src/main/java/org/yaz4j/PackageOptionsCollection.java @@ -0,0 +1,29 @@ +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 new file mode 100644 index 0000000..f8d2e53 --- /dev/null +++ b/src/main/java/org/yaz4j/PrefixQuery.java @@ -0,0 +1,21 @@ +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 new file mode 100644 index 0000000..e1990a7 --- /dev/null +++ b/src/main/java/org/yaz4j/Record.java @@ -0,0 +1,71 @@ +package org.yaz4j; + +import java.io.UnsupportedEncodingException; + +import org.yaz4j.jni.SWIGTYPE_p_ZOOM_record_p; +import org.yaz4j.jni.SWIGTYPE_p_int; +import org.yaz4j.jni.yaz4jlib; + +public class Record +{ + private SWIGTYPE_p_ZOOM_record_p record = null ; + private ResultSet resultSet = null ; + private boolean disposed = false; + + Record(SWIGTYPE_p_ZOOM_record_p record, ResultSet resultSet) + { + this.resultSet = resultSet; + this.record = record; + } + + public void finalize() + { + Dispose(); + } + + public byte[] getContent() + { + String type = "raw"; + SWIGTYPE_p_int length = null ; + return yaz4jlib.ZOOM_record_get_bytes(record, type, length) ; +// String contentString = yaz4jlib.ZOOM_record_get(record, type, length) ; +// System.err.println("!!!!!"); +// System.err.println(contentString); +// System.err.println(contentString.length()); +// System.err.println("!!!!!"); +// try { +// byte[] bytes = contentString.getBytes("UTF8"); +// System.err.println(bytes.length); +// return bytes ; +// } catch (UnsupportedEncodingException e) { +// throw new RuntimeException(e); +// } + } + + public String getSyntax() + { + String type = "syntax"; + SWIGTYPE_p_int length = null ; + String syntax = yaz4jlib.ZOOM_record_get(record, type, length); + return syntax ; + } + + public String getDatabase() + { + String type = "database"; + SWIGTYPE_p_int length = null ; + String database = yaz4jlib.ZOOM_record_get(record, type, length); + + return database ; + } + + public void Dispose() + { + if (!disposed) + { + resultSet = null; + record = null; + disposed = true; + } + } +} diff --git a/src/main/java/org/yaz4j/ResultSet.java b/src/main/java/org/yaz4j/ResultSet.java new file mode 100644 index 0000000..b70a03e --- /dev/null +++ b/src/main/java/org/yaz4j/ResultSet.java @@ -0,0 +1,66 @@ +package org.yaz4j; + +import org.yaz4j.jni.SWIGTYPE_p_ZOOM_connection_p; +import org.yaz4j.jni.SWIGTYPE_p_ZOOM_record_p; +import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p; +import org.yaz4j.jni.yaz4jlib; + +public class ResultSet +{ + private SWIGTYPE_p_ZOOM_resultset_p resultSet; + private SWIGTYPE_p_ZOOM_connection_p connection; + private long size = 0 ; + private Record[] records = null ; + private boolean disposed = false; + + ResultSet(SWIGTYPE_p_ZOOM_resultset_p resultSet, SWIGTYPE_p_ZOOM_connection_p connection) + { + this.resultSet = resultSet ; + this.connection = connection ; + size = yaz4jlib.ZOOM_resultset_size(this.resultSet); + records = new Record[(int)size]; + } + + public void finalize() + { + this.Dispose(); + } + + ResultSetOptionsCollection getResultSetOptions() + { + return new ResultSetOptionsCollection(resultSet); + } + + public Record getRecord(int index) + { + if ( records[index] == null) + { + SWIGTYPE_p_ZOOM_record_p recordTemp = yaz4jlib.ZOOM_resultset_record(resultSet, index); + records[index] = new Record(recordTemp, this); + } + + return this.records[index]; + } + + public int getSize() + { + return (int)size ; + } + + public void Dispose() + { + if (! disposed ) + { + for( int i=0 ; i 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/org/yaz4j/Bib1Exception.java b/src/org/yaz4j/Bib1Exception.java deleted file mode 100644 index 742b9ab..0000000 --- a/src/org/yaz4j/Bib1Exception.java +++ /dev/null @@ -1,16 +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/org/yaz4j/CQLQuery.java b/src/org/yaz4j/CQLQuery.java deleted file mode 100644 index 1411e28..0000000 --- a/src/org/yaz4j/CQLQuery.java +++ /dev/null @@ -1,21 +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/org/yaz4j/Connection.java b/src/org/yaz4j/Connection.java deleted file mode 100644 index 2c5fcf2..0000000 --- a/src/org/yaz4j/Connection.java +++ /dev/null @@ -1,235 +0,0 @@ -package org.yaz4j; - -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.yaz4jlib; -import org.yaz4j.jni.yaz4jlibConstants; - -import sun.reflect.generics.reflectiveObjects.NotImplementedException; - -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; - private boolean disposed = false; - - 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) - String libName = "yaz4j" ; - try - { - // System.err.println( "Loading library '"+ System.mapLibraryName( libName ) + "'" ); - System.loadLibrary( libName ); - } - catch( Throwable e ) - { - System.err.println( "Fatal Error: Failed to load library '" + System.mapLibraryName( libName ) + "'"); - e.printStackTrace(); - } - } - - public Connection(String host, int port) - { - this.host = host ; - this.port = port ; - - options = new ConnectionOptionsCollection(); - zoomConnection = yaz4jlib.ZOOM_connection_create(options.zoomOptions); - - SWIGTYPE_p_p_char cp = null; - SWIGTYPE_p_p_char addinfo = null ; - int errorCode = yaz4jlib.ZOOM_connection_error(zoomConnection, cp, addinfo); - CheckErrorCodeAndThrow(errorCode); - } - - 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 ); - } - } - - 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(); - - SWIGTYPE_p_ZOOM_query_p yazQuery = yaz4jlib.ZOOM_query_create(); - ResultSet resultSet = null; - - try - { - if( queryType == QueryType.CQLQuery ) - yaz4jlib.ZOOM_query_cql(yazQuery, query); - else if( queryType == QueryType.PrefixQuery ) - yaz4jlib.ZOOM_query_prefix(yazQuery, query); - else - throw new NotImplementedException(); - - SWIGTYPE_p_ZOOM_resultset_p yazResultSet = yaz4jlib.ZOOM_connection_search(zoomConnection, yazQuery); - - int errorCode = yaz4jlib.ZOOM_connection_errcode( zoomConnection ); - if (errorCode != yaz4jlib.ZOOM_ERROR_NONE) - { - yaz4jlib.ZOOM_resultset_destroy(yazResultSet); - } - CheckErrorCodeAndThrow(errorCode); - - resultSet = new ResultSet(yazResultSet, zoomConnection); - } - finally - { - yaz4jlib.ZOOM_query_destroy(yazQuery); // deallocate yazQuery also when exceptions - yazQuery = null; - } - return resultSet; - } - - public ScanSet Scan(String query) - { - EnsureConnected(); - SWIGTYPE_p_ZOOM_scanset_p yazScanSet = yaz4jlib.ZOOM_connection_scan(zoomConnection, query); - - int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); - if( errorCode != yaz4jlib.ZOOM_ERROR_NONE ) - { - yaz4jlib.ZOOM_scanset_destroy(yazScanSet); - } - CheckErrorCodeAndThrow(errorCode); - - ScanSet scanSet = new ScanSet(yazScanSet, this); - return scanSet; - } - - public ConnectionOptionsCollection getOptions() - { - return options; - } - - protected void EnsureConnected() - { - if (! connected ) - Connect(); - } - - public void Connect() - { - yaz4jlib.ZOOM_connection_connect( zoomConnection, host, port); - int errorCode = yaz4jlib.ZOOM_connection_errcode(zoomConnection); - CheckErrorCodeAndThrow(errorCode); - connected = true; - } - - public void Dispose() - { - if (! disposed ) - { - yaz4jlib.ZOOM_connection_destroy(zoomConnection); - zoomConnection = null; - disposed = true; - } - } - - public String getSyntax() - { - return options.get("preferredRecordSyntax"); - } - - public void setSyntax( String value) - { - options.set("preferredRecordSyntax", value ) ; - } - - public String getDatabaseName() - { - return options.get("databaseName"); - } - - public void setDatabaseName( String value ) - { - options.set("databaseName", value); - } - - public String getUsername() - { - return options.get("user"); - } - - public void setUsername( String value ) - { - options.set("user", value); - } - - public String getPassword() - { - return options.get("password"); - } - - public void setPassword( String value ) - { - options.set("password", value); - } -} diff --git a/src/org/yaz4j/ConnectionExtended.java b/src/org/yaz4j/ConnectionExtended.java deleted file mode 100644 index 8d9744b..0000000 --- a/src/org/yaz4j/ConnectionExtended.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.yaz4j; - -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_options_p; -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_package_p; -import org.yaz4j.jni.yaz4jlib; - -public class ConnectionExtended extends Connection -{ - public ConnectionExtended(String host, int port) - { - super(host, port); - } - - public Package Package(String type) - { - EnsureConnected(); - 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/org/yaz4j/ConnectionOptionsCollection.java b/src/org/yaz4j/ConnectionOptionsCollection.java deleted file mode 100644 index fb60263..0000000 --- a/src/org/yaz4j/ConnectionOptionsCollection.java +++ /dev/null @@ -1,42 +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/org/yaz4j/ConnectionTimeoutException.java b/src/org/yaz4j/ConnectionTimeoutException.java deleted file mode 100644 index 7f6c574..0000000 --- a/src/org/yaz4j/ConnectionTimeoutException.java +++ /dev/null @@ -1,16 +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/org/yaz4j/ConnectionUnavailableException.java b/src/org/yaz4j/ConnectionUnavailableException.java deleted file mode 100644 index 25c7226..0000000 --- a/src/org/yaz4j/ConnectionUnavailableException.java +++ /dev/null @@ -1,16 +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/org/yaz4j/InitRejectedException.java b/src/org/yaz4j/InitRejectedException.java deleted file mode 100644 index 83c3c8d..0000000 --- a/src/org/yaz4j/InitRejectedException.java +++ /dev/null @@ -1,16 +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/org/yaz4j/InvalidQueryException.java b/src/org/yaz4j/InvalidQueryException.java deleted file mode 100644 index 4f265c2..0000000 --- a/src/org/yaz4j/InvalidQueryException.java +++ /dev/null @@ -1,16 +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/org/yaz4j/Package.java b/src/org/yaz4j/Package.java deleted file mode 100644 index 590b172..0000000 --- a/src/org/yaz4j/Package.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.yaz4j; - -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 String type; - - Package(SWIGTYPE_p_ZOOM_package_p pack, ConnectionExtended connection, String type) - { - this.type = type; - this.connection = connection; - this.pack = pack; - } - - public void finalize() - { - Dispose(); - } - - public PackageOptionsCollection getPackageOptions() - { - return new PackageOptionsCollection(pack); - } - - public void Send() - { - yaz4jlib.ZOOM_package_send( pack, type ); - } - - public void Dispose() - { - if ( pack != null ) - { - yaz4jlib.ZOOM_package_destroy( pack ); - connection = null; - pack = null ; - } - } -} diff --git a/src/org/yaz4j/PackageOptionsCollection.java b/src/org/yaz4j/PackageOptionsCollection.java deleted file mode 100644 index 7cff946..0000000 --- a/src/org/yaz4j/PackageOptionsCollection.java +++ /dev/null @@ -1,29 +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/org/yaz4j/PrefixQuery.java b/src/org/yaz4j/PrefixQuery.java deleted file mode 100644 index f8d2e53..0000000 --- a/src/org/yaz4j/PrefixQuery.java +++ /dev/null @@ -1,21 +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/org/yaz4j/Record.java b/src/org/yaz4j/Record.java deleted file mode 100644 index e1990a7..0000000 --- a/src/org/yaz4j/Record.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.yaz4j; - -import java.io.UnsupportedEncodingException; - -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_record_p; -import org.yaz4j.jni.SWIGTYPE_p_int; -import org.yaz4j.jni.yaz4jlib; - -public class Record -{ - private SWIGTYPE_p_ZOOM_record_p record = null ; - private ResultSet resultSet = null ; - private boolean disposed = false; - - Record(SWIGTYPE_p_ZOOM_record_p record, ResultSet resultSet) - { - this.resultSet = resultSet; - this.record = record; - } - - public void finalize() - { - Dispose(); - } - - public byte[] getContent() - { - String type = "raw"; - SWIGTYPE_p_int length = null ; - return yaz4jlib.ZOOM_record_get_bytes(record, type, length) ; -// String contentString = yaz4jlib.ZOOM_record_get(record, type, length) ; -// System.err.println("!!!!!"); -// System.err.println(contentString); -// System.err.println(contentString.length()); -// System.err.println("!!!!!"); -// try { -// byte[] bytes = contentString.getBytes("UTF8"); -// System.err.println(bytes.length); -// return bytes ; -// } catch (UnsupportedEncodingException e) { -// throw new RuntimeException(e); -// } - } - - public String getSyntax() - { - String type = "syntax"; - SWIGTYPE_p_int length = null ; - String syntax = yaz4jlib.ZOOM_record_get(record, type, length); - return syntax ; - } - - public String getDatabase() - { - String type = "database"; - SWIGTYPE_p_int length = null ; - String database = yaz4jlib.ZOOM_record_get(record, type, length); - - return database ; - } - - public void Dispose() - { - if (!disposed) - { - resultSet = null; - record = null; - disposed = true; - } - } -} diff --git a/src/org/yaz4j/ResultSet.java b/src/org/yaz4j/ResultSet.java deleted file mode 100644 index b70a03e..0000000 --- a/src/org/yaz4j/ResultSet.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.yaz4j; - -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_connection_p; -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_record_p; -import org.yaz4j.jni.SWIGTYPE_p_ZOOM_resultset_p; -import org.yaz4j.jni.yaz4jlib; - -public class ResultSet -{ - private SWIGTYPE_p_ZOOM_resultset_p resultSet; - private SWIGTYPE_p_ZOOM_connection_p connection; - private long size = 0 ; - private Record[] records = null ; - private boolean disposed = false; - - ResultSet(SWIGTYPE_p_ZOOM_resultset_p resultSet, SWIGTYPE_p_ZOOM_connection_p connection) - { - this.resultSet = resultSet ; - this.connection = connection ; - size = yaz4jlib.ZOOM_resultset_size(this.resultSet); - records = new Record[(int)size]; - } - - public void finalize() - { - this.Dispose(); - } - - ResultSetOptionsCollection getResultSetOptions() - { - return new ResultSetOptionsCollection(resultSet); - } - - public Record getRecord(int index) - { - if ( records[index] == null) - { - SWIGTYPE_p_ZOOM_record_p recordTemp = yaz4jlib.ZOOM_resultset_record(resultSet, index); - records[index] = new Record(recordTemp, this); - } - - return this.records[index]; - } - - public int getSize() - { - return (int)size ; - } - - public void Dispose() - { - if (! disposed ) - { - for( int i=0 ; i + + + yaz4j + http://www.indexdata.com/sites/indexdata.com/themes/indexd/topbar.gif + http://indexdata.com/yaz + + + + org.apache.tapestry + maven-skin + 1.1 + + +

+ ${reports} + + + diff --git a/src/test/java/yaz4jtest/ConnectionTest.java b/src/test/java/yaz4jtest/ConnectionTest.java new file mode 100644 index 0000000..2f143af --- /dev/null +++ b/src/test/java/yaz4jtest/ConnectionTest.java @@ -0,0 +1,24 @@ +package yaz4jtest; +import org.junit.*; +import static org.junit.Assert.*; +import java.util.*; + +public class ConnectionTest { + @Test + 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); + } +} diff --git a/test/ConnectionTest.java b/test/ConnectionTest.java deleted file mode 100644 index 2f143af..0000000 --- a/test/ConnectionTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package yaz4jtest; -import org.junit.*; -import static org.junit.Assert.*; -import java.util.*; - -public class ConnectionTest { - @Test - 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); - } -} -- 1.7.10.4