From 6c0ff20ff5da2b94b0c1076757412bfd30761d56 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 18 Feb 2009 11:49:29 +0100 Subject: [PATCH 001/147] Added Netbeans project. --- .gitignore | 5 + build.xml | 74 ++++ junit/README | 1 + manifest.mf | 3 + nbproject/build-impl.xml | 642 ++++++++++++++++++++++++++++++++++ nbproject/genfiles.properties | 8 + nbproject/project.properties | 63 ++++ nbproject/project.xml | 16 + 8 files changed, 812 insertions(+) create mode 100644 .gitignore create mode 100644 build.xml create mode 100644 junit/README create mode 100644 manifest.mf create mode 100644 nbproject/build-impl.xml create mode 100644 nbproject/genfiles.properties create mode 100644 nbproject/project.properties create mode 100644 nbproject/project.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1fac89 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build +dist +nbproject/private +*.swp +*~ diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..1e9b1b6 --- /dev/null +++ b/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project cql-java. + + + diff --git a/junit/README b/junit/README new file mode 100644 index 0000000..88a6cda --- /dev/null +++ b/junit/README @@ -0,0 +1 @@ +Unit Tests diff --git a/manifest.mf b/manifest.mf new file mode 100644 index 0000000..328e8e5 --- /dev/null +++ b/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml new file mode 100644 index 0000000..0723422 --- /dev/null +++ b/nbproject/build-impl.xml @@ -0,0 +1,642 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties new file mode 100644 index 0000000..a920ae6 --- /dev/null +++ b/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=42ac3f35 +build.xml.script.CRC32=bfe38990 +build.xml.stylesheet.CRC32=958a1d3e +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=42ac3f35 +nbproject/build-impl.xml.script.CRC32=7bcbe9fa +nbproject/build-impl.xml.stylesheet.CRC32=e55b27f5 diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..b2fc6d8 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,63 @@ +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/cql-java.jar +dist.javadoc.dir=${dist.dir}/javadoc +excludes= +file.reference.cql-java-junit=junit +file.reference.cql-java-src=src +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class= +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=${file.reference.cql-java-src} +test.src.dir=${file.reference.cql-java-junit} diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..09ea182 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,16 @@ + + + org.netbeans.modules.java.j2seproject + + + cql-java + 1.6.5 + + + + + + + + + From 53157e39bdd699e023a1b32fab5c54b77774ae35 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 18 Feb 2009 11:57:26 +0100 Subject: [PATCH 002/147] Added some project meta-data --- nbproject/project.properties | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/nbproject/project.properties b/nbproject/project.properties index b2fc6d8..9303b60 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -1,3 +1,10 @@ +application.desc=a free CQL compiler, and other CQL tools, for Java +application.homepage=http://ww.indexdata.com +application.title=cql-java +application.vendor=Index Data ApS +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80 +auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=default build.classes.dir=${build.dir}/classes build.classes.excludes=**/*.java,**/*.form # This directory is removed when the project is cleaned: @@ -44,6 +51,12 @@ javadoc.splitindex=true javadoc.use=true javadoc.version=false javadoc.windowtitle= +jnlp.codebase.type=local +jnlp.codebase.url=file:/home/jakub/code/masterkey2/cql-java/dist/ +jnlp.descriptor=application +jnlp.enabled=false +jnlp.offline-allowed=false +jnlp.signed=false main.class= manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF From e06d8db9fa2be9bf05ce67e65c0b43381d3b7c39 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 24 Jul 2009 17:27:24 +0200 Subject: [PATCH 003/147] Revert "Added some project meta-data" This reverts commit 53157e39bdd699e023a1b32fab5c54b77774ae35. --- nbproject/project.properties | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/nbproject/project.properties b/nbproject/project.properties index 9303b60..b2fc6d8 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -1,10 +1,3 @@ -application.desc=a free CQL compiler, and other CQL tools, for Java -application.homepage=http://ww.indexdata.com -application.title=cql-java -application.vendor=Index Data ApS -auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.tab-size=8 -auxiliary.org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width=80 -auxiliary.org-netbeans-modules-editor-indent.CodeStyle.usedProfile=default build.classes.dir=${build.dir}/classes build.classes.excludes=**/*.java,**/*.form # This directory is removed when the project is cleaned: @@ -51,12 +44,6 @@ javadoc.splitindex=true javadoc.use=true javadoc.version=false javadoc.windowtitle= -jnlp.codebase.type=local -jnlp.codebase.url=file:/home/jakub/code/masterkey2/cql-java/dist/ -jnlp.descriptor=application -jnlp.enabled=false -jnlp.offline-allowed=false -jnlp.signed=false main.class= manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF From af9fc1ccd0a8d9048d0b469a72b11bead020b719 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 24 Jul 2009 17:27:51 +0200 Subject: [PATCH 004/147] Revert "Added Netbeans project." This reverts commit 6c0ff20ff5da2b94b0c1076757412bfd30761d56. --- .gitignore | 5 - build.xml | 74 ---- junit/README | 1 - manifest.mf | 3 - nbproject/build-impl.xml | 642 ---------------------------------- nbproject/genfiles.properties | 8 - nbproject/project.properties | 63 ---- nbproject/project.xml | 16 - 8 files changed, 812 deletions(-) delete mode 100644 .gitignore delete mode 100644 build.xml delete mode 100644 junit/README delete mode 100644 manifest.mf delete mode 100644 nbproject/build-impl.xml delete mode 100644 nbproject/genfiles.properties delete mode 100644 nbproject/project.properties delete mode 100644 nbproject/project.xml diff --git a/.gitignore b/.gitignore deleted file mode 100644 index a1fac89..0000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -build -dist -nbproject/private -*.swp -*~ diff --git a/build.xml b/build.xml deleted file mode 100644 index 1e9b1b6..0000000 --- a/build.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - Builds, tests, and runs the project cql-java. - - - diff --git a/junit/README b/junit/README deleted file mode 100644 index 88a6cda..0000000 --- a/junit/README +++ /dev/null @@ -1 +0,0 @@ -Unit Tests diff --git a/manifest.mf b/manifest.mf deleted file mode 100644 index 328e8e5..0000000 --- a/manifest.mf +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -X-COMMENT: Main-Class will be added automatically by build - diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml deleted file mode 100644 index 0723422..0000000 --- a/nbproject/build-impl.xml +++ /dev/null @@ -1,642 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set src.dir - Must set test.src.dir - Must set build.dir - Must set dist.dir - Must set build.classes.dir - Must set dist.javadoc.dir - Must set build.test.classes.dir - Must set build.test.results.dir - Must set build.classes.excludes - Must set dist.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set debug.class - - - - - Must set fix.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - Some tests failed; see details above. - - - - - - - - - Must select some files in the IDE or set test.includes - - - - Some tests failed; see details above. - - - - - Must select one file in the IDE or set test.class - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties deleted file mode 100644 index a920ae6..0000000 --- a/nbproject/genfiles.properties +++ /dev/null @@ -1,8 +0,0 @@ -build.xml.data.CRC32=42ac3f35 -build.xml.script.CRC32=bfe38990 -build.xml.stylesheet.CRC32=958a1d3e -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=42ac3f35 -nbproject/build-impl.xml.script.CRC32=7bcbe9fa -nbproject/build-impl.xml.stylesheet.CRC32=e55b27f5 diff --git a/nbproject/project.properties b/nbproject/project.properties deleted file mode 100644 index b2fc6d8..0000000 --- a/nbproject/project.properties +++ /dev/null @@ -1,63 +0,0 @@ -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/cql-java.jar -dist.javadoc.dir=${dist.dir}/javadoc -excludes= -file.reference.cql-java-junit=junit -file.reference.cql-java-src=src -includes=** -jar.compress=false -javac.classpath= -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.source=1.5 -javac.target=1.5 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir}:\ - ${libs.junit.classpath}:\ - ${libs.junit_4.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -main.class= -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project -# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value -# or test-sys-prop.name=value to set system properties for unit tests): -run.jvmargs= -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -src.dir=${file.reference.cql-java-src} -test.src.dir=${file.reference.cql-java-junit} diff --git a/nbproject/project.xml b/nbproject/project.xml deleted file mode 100644 index 09ea182..0000000 --- a/nbproject/project.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - org.netbeans.modules.java.j2seproject - - - cql-java - 1.6.5 - - - - - - - - - From d58739419882639439b40b18fcefeb9e51488fb9 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 24 Jul 2009 18:02:26 +0200 Subject: [PATCH 005/147] Mavenized. I assume none of the makefiles work. So if somebody wants to keep them for nostalgic reasons, he should fixed them. Or removed them for good :) --- .gitignore | 3 ++ pom.xml | 32 +++++++++++++++++++ .../java}/org/z3950/zing/cql/.cvsignore | 0 .../java}/org/z3950/zing/cql/CQLAndNode.java | 0 .../org/z3950/zing/cql/CQLBooleanNode.java | 0 .../org/z3950/zing/cql/CQLGenerator.java | 0 .../java}/org/z3950/zing/cql/CQLLexer.java | 0 .../java}/org/z3950/zing/cql/CQLNode.java | 0 .../java}/org/z3950/zing/cql/CQLNotNode.java | 0 .../java}/org/z3950/zing/cql/CQLOrNode.java | 0 .../org/z3950/zing/cql/CQLParseException.java | 0 .../java}/org/z3950/zing/cql/CQLParser.java | 0 .../java}/org/z3950/zing/cql/CQLPrefix.java | 0 .../org/z3950/zing/cql/CQLPrefixNode.java | 0 .../java}/org/z3950/zing/cql/CQLProxNode.java | 0 .../java}/org/z3950/zing/cql/CQLRelation.java | 0 .../java}/org/z3950/zing/cql/CQLSortNode.java | 0 .../java}/org/z3950/zing/cql/CQLTermNode.java | 0 .../java}/org/z3950/zing/cql/Makefile | 0 .../zing/cql/MissingParameterException.java | 0 .../java}/org/z3950/zing/cql/Modifier.java | 0 .../java}/org/z3950/zing/cql/ModifierSet.java | 0 .../zing/cql/PQFTranslationException.java | 0 .../z3950/zing/cql/UnknownIndexException.java | 0 .../zing/cql/UnknownPositionException.java | 0 .../zing/cql/UnknownRelationException.java | 0 .../cql/UnknownRelationModifierException.java | 0 .../java}/org/z3950/zing/cql/Utils.java | 0 28 files changed, 35 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml rename src/{ => main/java}/org/z3950/zing/cql/.cvsignore (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLAndNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLBooleanNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLGenerator.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLLexer.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLNotNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLOrNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLParseException.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLParser.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLPrefix.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLPrefixNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLProxNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLRelation.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLSortNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/CQLTermNode.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/Makefile (100%) rename src/{ => main/java}/org/z3950/zing/cql/MissingParameterException.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/Modifier.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/ModifierSet.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/PQFTranslationException.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/UnknownIndexException.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/UnknownPositionException.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/UnknownRelationException.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/UnknownRelationModifierException.java (100%) rename src/{ => main/java}/org/z3950/zing/cql/Utils.java (100%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2a2c7a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target/ +*.swp +*~ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..fd08049 --- /dev/null +++ b/pom.xml @@ -0,0 +1,32 @@ + + 4.0.0 + org.z3950.zing + cql-java + jar + 1.3 + cql-java + http://maven.apache.org + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + + + + junit + junit + 3.8.1 + test + + + + diff --git a/src/org/z3950/zing/cql/.cvsignore b/src/main/java/org/z3950/zing/cql/.cvsignore similarity index 100% rename from src/org/z3950/zing/cql/.cvsignore rename to src/main/java/org/z3950/zing/cql/.cvsignore diff --git a/src/org/z3950/zing/cql/CQLAndNode.java b/src/main/java/org/z3950/zing/cql/CQLAndNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLAndNode.java rename to src/main/java/org/z3950/zing/cql/CQLAndNode.java diff --git a/src/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLBooleanNode.java rename to src/main/java/org/z3950/zing/cql/CQLBooleanNode.java diff --git a/src/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java similarity index 100% rename from src/org/z3950/zing/cql/CQLGenerator.java rename to src/main/java/org/z3950/zing/cql/CQLGenerator.java diff --git a/src/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java similarity index 100% rename from src/org/z3950/zing/cql/CQLLexer.java rename to src/main/java/org/z3950/zing/cql/CQLLexer.java diff --git a/src/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLNode.java rename to src/main/java/org/z3950/zing/cql/CQLNode.java diff --git a/src/org/z3950/zing/cql/CQLNotNode.java b/src/main/java/org/z3950/zing/cql/CQLNotNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLNotNode.java rename to src/main/java/org/z3950/zing/cql/CQLNotNode.java diff --git a/src/org/z3950/zing/cql/CQLOrNode.java b/src/main/java/org/z3950/zing/cql/CQLOrNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLOrNode.java rename to src/main/java/org/z3950/zing/cql/CQLOrNode.java diff --git a/src/org/z3950/zing/cql/CQLParseException.java b/src/main/java/org/z3950/zing/cql/CQLParseException.java similarity index 100% rename from src/org/z3950/zing/cql/CQLParseException.java rename to src/main/java/org/z3950/zing/cql/CQLParseException.java diff --git a/src/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java similarity index 100% rename from src/org/z3950/zing/cql/CQLParser.java rename to src/main/java/org/z3950/zing/cql/CQLParser.java diff --git a/src/org/z3950/zing/cql/CQLPrefix.java b/src/main/java/org/z3950/zing/cql/CQLPrefix.java similarity index 100% rename from src/org/z3950/zing/cql/CQLPrefix.java rename to src/main/java/org/z3950/zing/cql/CQLPrefix.java diff --git a/src/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLPrefixNode.java rename to src/main/java/org/z3950/zing/cql/CQLPrefixNode.java diff --git a/src/org/z3950/zing/cql/CQLProxNode.java b/src/main/java/org/z3950/zing/cql/CQLProxNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLProxNode.java rename to src/main/java/org/z3950/zing/cql/CQLProxNode.java diff --git a/src/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java similarity index 100% rename from src/org/z3950/zing/cql/CQLRelation.java rename to src/main/java/org/z3950/zing/cql/CQLRelation.java diff --git a/src/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLSortNode.java rename to src/main/java/org/z3950/zing/cql/CQLSortNode.java diff --git a/src/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java similarity index 100% rename from src/org/z3950/zing/cql/CQLTermNode.java rename to src/main/java/org/z3950/zing/cql/CQLTermNode.java diff --git a/src/org/z3950/zing/cql/Makefile b/src/main/java/org/z3950/zing/cql/Makefile similarity index 100% rename from src/org/z3950/zing/cql/Makefile rename to src/main/java/org/z3950/zing/cql/Makefile diff --git a/src/org/z3950/zing/cql/MissingParameterException.java b/src/main/java/org/z3950/zing/cql/MissingParameterException.java similarity index 100% rename from src/org/z3950/zing/cql/MissingParameterException.java rename to src/main/java/org/z3950/zing/cql/MissingParameterException.java diff --git a/src/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java similarity index 100% rename from src/org/z3950/zing/cql/Modifier.java rename to src/main/java/org/z3950/zing/cql/Modifier.java diff --git a/src/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java similarity index 100% rename from src/org/z3950/zing/cql/ModifierSet.java rename to src/main/java/org/z3950/zing/cql/ModifierSet.java diff --git a/src/org/z3950/zing/cql/PQFTranslationException.java b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java similarity index 100% rename from src/org/z3950/zing/cql/PQFTranslationException.java rename to src/main/java/org/z3950/zing/cql/PQFTranslationException.java diff --git a/src/org/z3950/zing/cql/UnknownIndexException.java b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java similarity index 100% rename from src/org/z3950/zing/cql/UnknownIndexException.java rename to src/main/java/org/z3950/zing/cql/UnknownIndexException.java diff --git a/src/org/z3950/zing/cql/UnknownPositionException.java b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java similarity index 100% rename from src/org/z3950/zing/cql/UnknownPositionException.java rename to src/main/java/org/z3950/zing/cql/UnknownPositionException.java diff --git a/src/org/z3950/zing/cql/UnknownRelationException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java similarity index 100% rename from src/org/z3950/zing/cql/UnknownRelationException.java rename to src/main/java/org/z3950/zing/cql/UnknownRelationException.java diff --git a/src/org/z3950/zing/cql/UnknownRelationModifierException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java similarity index 100% rename from src/org/z3950/zing/cql/UnknownRelationModifierException.java rename to src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java diff --git a/src/org/z3950/zing/cql/Utils.java b/src/main/java/org/z3950/zing/cql/Utils.java similarity index 100% rename from src/org/z3950/zing/cql/Utils.java rename to src/main/java/org/z3950/zing/cql/Utils.java From 77b874686236b328d63ab155e833f2d977e26a88 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 27 Jul 2009 09:30:12 +0200 Subject: [PATCH 006/147] Ignore. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index d2a2c7a..76c3508 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ target/ *.swp *~ +build +dist +nbproject From 6ddb06e5ef8e08201e423e9e0913ee1b63c7e16c Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Tue, 13 Apr 2010 15:41:36 +0200 Subject: [PATCH 007/147] Add id-maven-repo as target/source --- pom.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pom.xml b/pom.xml index fd08049..cfa074b 100644 --- a/pom.xml +++ b/pom.xml @@ -28,5 +28,19 @@ test + + + false + id-maven-repo + Index Data Maven Repository + scp://maven.indexdata.com/var/www/maven/repository + + + + + id-maven-repo + http://maven.indexdata.com + + From 06f53c73a7a63844a6d6829037d86d619737a1e7 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 19 May 2010 23:16:37 +0100 Subject: [PATCH 008/147] Add source directory to CLASSPATH to pick up newly built .class files. --- test/regression/runtests | 1 + 1 file changed, 1 insertion(+) diff --git a/test/regression/runtests b/test/regression/runtests index 3c06174..1630be9 100755 --- a/test/regression/runtests +++ b/test/regression/runtests @@ -5,6 +5,7 @@ use IO::File; use strict; +$ENV{CLASSPATH} .= ":../../src/main/java"; $ENV{CLASSPATH} .= ":../../lib/cql-java.jar"; if (@ARGV != 2) { From 05aa9a4ce59ab143934ee59e8a929bd37a704f40 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 19 May 2010 23:17:08 +0100 Subject: [PATCH 009/147] Move .cvsignore to .gitignore --- lib/{.cvsignore => .gitignore} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{.cvsignore => .gitignore} (100%) diff --git a/lib/.cvsignore b/lib/.gitignore similarity index 100% rename from lib/.cvsignore rename to lib/.gitignore From 360edd65f95ee2d1ddbd5d94381aca8212f0c14d Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 19 May 2010 23:17:50 +0100 Subject: [PATCH 010/147] Move .cvsignore to .gitignore --- src/main/java/org/z3950/zing/cql/{.cvsignore => .gitignore} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/org/z3950/zing/cql/{.cvsignore => .gitignore} (100%) diff --git a/src/main/java/org/z3950/zing/cql/.cvsignore b/src/main/java/org/z3950/zing/cql/.gitignore similarity index 100% rename from src/main/java/org/z3950/zing/cql/.cvsignore rename to src/main/java/org/z3950/zing/cql/.gitignore From 8e3c6c8a4977f2f1030a86052c765e8b39d9c304 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 19 May 2010 23:18:22 +0100 Subject: [PATCH 011/147] Adjust paths in Makefile to allow for maven compification. --- src/main/java/org/z3950/zing/cql/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/Makefile b/src/main/java/org/z3950/zing/cql/Makefile index 39c4f21..00b82d5 100644 --- a/src/main/java/org/z3950/zing/cql/Makefile +++ b/src/main/java/org/z3950/zing/cql/Makefile @@ -19,15 +19,15 @@ OBJ = Utils.class \ UnknownRelationModifierException.class UnknownPositionException.class JARPATH = ../lib/cql-java.jar -JAR = ../../../../$(JARPATH) +JAR = ../../../../../../$(JARPATH) $(JAR): $(OBJ) - cd ../../../..; jar cf $(JARPATH) org/z3950/zing/cql/*.class + cd ../../../../../..; jar cf $(JARPATH) main/java/org/z3950/zing/cql/*.class %.class: %.java javac -Xlint:unchecked *.java test: $(JAR) - cd ../../../../../test/regression && make + cd ../../../../../../../test/regression && make clean: rm -f $(OBJ) 'CQLLexer$$Keyword.class' From fe7dbbb0c303187bc9e0488226627604ae9aa159 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 19 May 2010 23:18:42 +0100 Subject: [PATCH 012/147] Towards 1.4 --- Changes | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Changes b/Changes index 4441afe..5ad49e5 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,17 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. +1.4 [IN PROGRESS] + - Add support for interpreting sequences of non-keywords as a + single multi-word term rather than a broken INDEX RELATION + TERM triplet. This means that "oxford street" is a valid + query rather than a syntax error, and "tottenham court road" + is what it looks like rather than a search for the word + "court" related by the relation "court" to the index + "tottenham". Note that the word-formed relations "all" and + "exact" (### and others?) are still treated specially. + ### Not yet done + 1.3 Wed May 28 11:02:00 BST 2008 - Add getSortIndexes() to CQLSortNode, as suggested by Marcel Versteeg From 83ec0e33533dc85b30897f2f38f3a30286937c98 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 19 May 2010 23:20:16 +0100 Subject: [PATCH 013/147] Move many more .cvsignore files to .gitignore --- test/regression/sections/01/{.cvsignore => .gitignore} | 0 test/regression/sections/02/{.cvsignore => .gitignore} | 0 test/regression/sections/03/{.cvsignore => .gitignore} | 0 test/regression/sections/04/{.cvsignore => .gitignore} | 0 test/regression/sections/05/{.cvsignore => .gitignore} | 0 test/regression/sections/06/{.cvsignore => .gitignore} | 0 test/regression/sections/07/{.cvsignore => .gitignore} | 0 test/regression/sections/08/{.cvsignore => .gitignore} | 0 test/regression/sections/09/{.cvsignore => .gitignore} | 0 test/regression/sections/10/{.cvsignore => .gitignore} | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename test/regression/sections/01/{.cvsignore => .gitignore} (100%) rename test/regression/sections/02/{.cvsignore => .gitignore} (100%) rename test/regression/sections/03/{.cvsignore => .gitignore} (100%) rename test/regression/sections/04/{.cvsignore => .gitignore} (100%) rename test/regression/sections/05/{.cvsignore => .gitignore} (100%) rename test/regression/sections/06/{.cvsignore => .gitignore} (100%) rename test/regression/sections/07/{.cvsignore => .gitignore} (100%) rename test/regression/sections/08/{.cvsignore => .gitignore} (100%) rename test/regression/sections/09/{.cvsignore => .gitignore} (100%) rename test/regression/sections/10/{.cvsignore => .gitignore} (100%) diff --git a/test/regression/sections/01/.cvsignore b/test/regression/sections/01/.gitignore similarity index 100% rename from test/regression/sections/01/.cvsignore rename to test/regression/sections/01/.gitignore diff --git a/test/regression/sections/02/.cvsignore b/test/regression/sections/02/.gitignore similarity index 100% rename from test/regression/sections/02/.cvsignore rename to test/regression/sections/02/.gitignore diff --git a/test/regression/sections/03/.cvsignore b/test/regression/sections/03/.gitignore similarity index 100% rename from test/regression/sections/03/.cvsignore rename to test/regression/sections/03/.gitignore diff --git a/test/regression/sections/04/.cvsignore b/test/regression/sections/04/.gitignore similarity index 100% rename from test/regression/sections/04/.cvsignore rename to test/regression/sections/04/.gitignore diff --git a/test/regression/sections/05/.cvsignore b/test/regression/sections/05/.gitignore similarity index 100% rename from test/regression/sections/05/.cvsignore rename to test/regression/sections/05/.gitignore diff --git a/test/regression/sections/06/.cvsignore b/test/regression/sections/06/.gitignore similarity index 100% rename from test/regression/sections/06/.cvsignore rename to test/regression/sections/06/.gitignore diff --git a/test/regression/sections/07/.cvsignore b/test/regression/sections/07/.gitignore similarity index 100% rename from test/regression/sections/07/.cvsignore rename to test/regression/sections/07/.gitignore diff --git a/test/regression/sections/08/.cvsignore b/test/regression/sections/08/.gitignore similarity index 100% rename from test/regression/sections/08/.cvsignore rename to test/regression/sections/08/.gitignore diff --git a/test/regression/sections/09/.cvsignore b/test/regression/sections/09/.gitignore similarity index 100% rename from test/regression/sections/09/.cvsignore rename to test/regression/sections/09/.gitignore diff --git a/test/regression/sections/10/.cvsignore b/test/regression/sections/10/.gitignore similarity index 100% rename from test/regression/sections/10/.cvsignore rename to test/regression/sections/10/.gitignore From 7d8ec6eaa2b799a2c466605af660e381644c48cc Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 19 May 2010 23:41:25 +0100 Subject: [PATCH 014/147] Rename method isRelation() to isSymbolicRelation() --- src/main/java/org/z3950/zing/cql/CQLParser.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 58e0326..7580959 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -159,7 +159,7 @@ private ModifierSet gatherModifiers(String base) + "got " + lexer.render()); String type = lexer.sval.toLowerCase(); match(lexer.ttype); - if (!isRelation()) { + if (!isSymbolicRelation()) { // It's a simple modifier consisting of type only ms.addModifier(type); } else { @@ -192,7 +192,7 @@ private CQLNode parseTerm(String index, CQLRelation relation) debug("non-parenthesised term"); word = matchSymbol("index or term"); - if (!isRelation() && lexer.ttype != lexer.TT_WORD) + if (!isSymbolicRelation() && lexer.ttype != lexer.TT_WORD) break; index = word; @@ -232,8 +232,8 @@ private CQLNode parsePrefix(String index, CQLRelation relation, } // Checks for a relation - private boolean isRelation() { - debug("isRelation: checking ttype=" + lexer.ttype + + private boolean isSymbolicRelation() { + debug("isSymbolicRelation: checking ttype=" + lexer.ttype + " (" + lexer.render() + ")"); return (lexer.ttype == '<' || lexer.ttype == '>' || From 937c1bab3e8708237535d1c402ae093bb9b5e000 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 20 May 2010 00:27:40 +0100 Subject: [PATCH 015/147] Add new and more general isRelation() that recognises well-known word relations. --- src/main/java/org/z3950/zing/cql/CQLParser.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 7580959..dab0e80 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -231,7 +231,19 @@ private CQLNode parsePrefix(String index, CQLRelation relation, return new CQLPrefixNode(name, identifier, node); } - // Checks for a relation + private boolean isRelation() { + debug("isRelation: checking ttype=" + lexer.ttype + + " (" + lexer.render() + ")"); + if (lexer.ttype == lexer.TT_WORD && + (lexer.sval == "exact" || + lexer.sval == "any" || + lexer.sval == "all" || + (lexer.sval == "scr" && compat == V1POINT2))) + return true; + + return isSymbolicRelation(); + } + private boolean isSymbolicRelation() { debug("isSymbolicRelation: checking ttype=" + lexer.ttype + " (" + lexer.render() + ")"); From 4d0ef95b01450f0462d1b2bffccbc3cefb5c2996 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 20 May 2010 00:37:46 +0100 Subject: [PATCH 016/147] isRelation() recognises word-form relations from context sets. parseTerm() accumulates multi-word query terms. --- src/main/java/org/z3950/zing/cql/CQLParser.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index dab0e80..25b49d0 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -192,7 +192,12 @@ private CQLNode parseTerm(String index, CQLRelation relation) debug("non-parenthesised term"); word = matchSymbol("index or term"); - if (!isSymbolicRelation() && lexer.ttype != lexer.TT_WORD) + while (lexer.ttype == lexer.TT_WORD && !isRelation()) { + word = word + " " + lexer.sval; + match(lexer.TT_WORD); + } + + if (!isRelation()) break; index = word; @@ -235,10 +240,11 @@ private boolean isRelation() { debug("isRelation: checking ttype=" + lexer.ttype + " (" + lexer.render() + ")"); if (lexer.ttype == lexer.TT_WORD && - (lexer.sval == "exact" || - lexer.sval == "any" || - lexer.sval == "all" || - (lexer.sval == "scr" && compat == V1POINT2))) + (lexer.sval.indexOf('.') >= 0 || + lexer.sval.equals("exact") || + lexer.sval.equals("any") || + lexer.sval.equals("all") || + (lexer.sval.equals("scr") && compat == V1POINT2))) return true; return isSymbolicRelation(); From f4b3ca8388346bed9262d4472ff4c3322cbf91ea Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 20 May 2010 00:39:05 +0100 Subject: [PATCH 017/147] Version 1.4, supports multiple-word search terms. --- Changes | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index 5ad49e5..1197ce9 100644 --- a/Changes +++ b/Changes @@ -6,16 +6,17 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. -1.4 [IN PROGRESS] +1.4 Thu May 20 00:38:40 BST 2010 - Add support for interpreting sequences of non-keywords as a single multi-word term rather than a broken INDEX RELATION TERM triplet. This means that "oxford street" is a valid query rather than a syntax error, and "tottenham court road" is what it looks like rather than a search for the word "court" related by the relation "court" to the index - "tottenham". Note that the word-formed relations "all" and - "exact" (### and others?) are still treated specially. - ### Not yet done + "tottenham". Note that the word-formed relations "any", + "all", "exact" and (for CQL v1.2) "scr" are still treated + specially, as are profiled relations in context sets, of the + form .. 1.3 Wed May 28 11:02:00 BST 2008 - Add getSortIndexes() to CQLSortNode, as suggested by Marcel From e73291c7d5c0023cb55ebbb287c95fca9f2e0091 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 20 May 2010 00:39:11 +0100 Subject: [PATCH 018/147] Version 1.4, supports multiple-word search terms. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 7e32cd5..c068b24 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3 +1.4 From 801e980014525774921192500be1430dc3645454 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 20 May 2010 00:41:23 +0100 Subject: [PATCH 019/147] Bump version number for Maven. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cfa074b..d536a3d 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.z3950.zing cql-java jar - 1.3 + 1.4 cql-java http://maven.apache.org From ba1429da6e78bc9fe4622d4e83b4fdbd8b1ceb85 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Fri, 21 May 2010 11:35:52 +0100 Subject: [PATCH 020/147] Fix up paths post-Mavenization. --- docs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index c77810a..a61ae53 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -2,8 +2,8 @@ all: overview-tree.html -overview-tree.html: ../src/org/z3950/zing/cql/*.java - nice javadoc -classpath ../src \ +overview-tree.html: ../src/main/java/org/z3950/zing/cql/*.java + nice javadoc -classpath ../src/main/java \ -author -version -windowtitle cql-java org.z3950.zing.cql clean: From 96594ecb275d4f5713a74fed8a126a90918b15c4 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Fri, 21 May 2010 11:36:39 +0100 Subject: [PATCH 021/147] Rename .cvsignore to .gitignore --- docs/{.cvsignore => .gitignore} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{.cvsignore => .gitignore} (100%) diff --git a/docs/.cvsignore b/docs/.gitignore similarity index 100% rename from docs/.cvsignore rename to docs/.gitignore From 1a9e9bef8c89c7b53c9d657b4a23e61b7c9f750e Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Fri, 21 May 2010 11:36:59 +0100 Subject: [PATCH 022/147] Fix for post-Maven paths. --- mkdist | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mkdist b/mkdist index e5d401e..13fcf9b 100755 --- a/mkdist +++ b/mkdist @@ -1,7 +1,6 @@ #!/bin/sh # mkdist - make a distribution of the CQL-Java software -# $Id: mkdist,v 1.6 2008-05-28 10:06:40 mike Exp $ version=`cat VERSION` distdir=cql-java-$version @@ -12,8 +11,8 @@ trap "rm -rf $tmpdir" 1 2 15 # 0 cp -rp . $tmpdir cd $tmpdir find . \( -name CVS -o -name .cvsignore \) -print | xargs rm -rf -rm -r archive mkdist etc/chris-hubick etc/xslt src/org/z3950/zing/ralph -( cd src/org/z3950/zing/cql && make && make clean ) +rm -rf archive mkdist etc/xslt .git +( cd src/main/java/org/z3950/zing/cql && make && make clean ) ( cd docs && make ) ( cd test/regression && make distclean ) cd .. From 67054ebf3e57c9570fab3d6e2c962f816487848e Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 15:53:29 +0200 Subject: [PATCH 023/147] Correct the set of word-relations recognised -- fixes #3435 Add encloses and within for all versions Add adj for V1.2 only Restrict exact to V1.1 only Switch sense for scr, now recognised only in 1.1 and not 1.2 --- src/main/java/org/z3950/zing/cql/CQLParser.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 25b49d0..90e9f59 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -241,10 +241,13 @@ private boolean isRelation() { " (" + lexer.render() + ")"); if (lexer.ttype == lexer.TT_WORD && (lexer.sval.indexOf('.') >= 0 || - lexer.sval.equals("exact") || lexer.sval.equals("any") || lexer.sval.equals("all") || - (lexer.sval.equals("scr") && compat == V1POINT2))) + lexer.sval.equals("within") || + lexer.sval.equals("encloses") || + (lexer.sval.equals("exact") && compat != V1POINT2) || + (lexer.sval.equals("scr") && compat != V1POINT2) || + (lexer.sval.equals("adj") && compat == V1POINT2))) return true; return isSymbolicRelation(); From fa0e579600e88748d6345fbbd9b437abcff374c8 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:00:57 +0200 Subject: [PATCH 024/147] Generate only word-relations that are good for both v1.1 and v1.2 --- src/main/java/org/z3950/zing/cql/CQLGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java index 416b771..cc8ac14 100644 --- a/src/main/java/org/z3950/zing/cql/CQLGenerator.java +++ b/src/main/java/org/z3950/zing/cql/CQLGenerator.java @@ -198,7 +198,7 @@ private String generate_base_relation() throws MissingParameterException { return generate_numeric_relation(); } else { switch (rnd.nextInt(3)) { - case 0: return "exact"; + case 0: return "within"; case 1: return "all"; case 2: return "any"; } From 81f8f4c23e11b92cd21ea71b723ac57d60f8226f Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:01:23 +0200 Subject: [PATCH 025/147] Fix rule that builds jar to use paths correctly. --- src/main/java/org/z3950/zing/cql/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/Makefile b/src/main/java/org/z3950/zing/cql/Makefile index 00b82d5..c318cc0 100644 --- a/src/main/java/org/z3950/zing/cql/Makefile +++ b/src/main/java/org/z3950/zing/cql/Makefile @@ -18,10 +18,10 @@ OBJ = Utils.class \ UnknownIndexException.class UnknownRelationException.class \ UnknownRelationModifierException.class UnknownPositionException.class -JARPATH = ../lib/cql-java.jar +JARPATH = ../../../lib/cql-java.jar JAR = ../../../../../../$(JARPATH) $(JAR): $(OBJ) - cd ../../../../../..; jar cf $(JARPATH) main/java/org/z3950/zing/cql/*.class + cd ../../../..; jar cf $(JARPATH) org/z3950/zing/cql/*.class %.class: %.java javac -Xlint:unchecked *.java From cb70dcd8334f8f81dad12f8361d4466c4770df5a Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:02:10 +0200 Subject: [PATCH 026/147] *sigh* fix the Maven-mangled src path yet again. --- Build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build b/Build index a399888..2c2f550 100755 --- a/Build +++ b/Build @@ -3,7 +3,7 @@ # $Id: Build,v 1.2 2002-11-20 17:20:11 mike Exp $ : ${MAKE=make} -for dir in src/org/z3950/zing/cql test/regression docs; do +for dir in src/main/java/org/z3950/zing/cql test/regression docs; do echo "=== Building in $dir ===" ( cd $dir; $MAKE ${@+"$@"} ) done From cab72229696568fdc524a5218b6231a0ccbda4ff Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:03:52 +0200 Subject: [PATCH 027/147] Would you believe ... fix the src path? --- docs/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index c77810a..a61ae53 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -2,8 +2,8 @@ all: overview-tree.html -overview-tree.html: ../src/org/z3950/zing/cql/*.java - nice javadoc -classpath ../src \ +overview-tree.html: ../src/main/java/org/z3950/zing/cql/*.java + nice javadoc -classpath ../src/main/java \ -author -version -windowtitle cql-java org.z3950.zing.cql clean: From f2834b0b08f014e37438f54697bf6a92f325bd23 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:06:12 +0200 Subject: [PATCH 028/147] Count iterations and summarise results. --- test/random/mkrandom | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/random/mkrandom b/test/random/mkrandom index f300534..185f2c3 100755 --- a/test/random/mkrandom +++ b/test/random/mkrandom @@ -12,12 +12,17 @@ if (@ARGV > 1) { $n = $ARGV[0]; } +my $nok = 0; for (my $i = 0; $i < $n; $i++) { print $i+1, " of $n -- "; my $query=`CQLGenerator ../../etc/generate.properties`; print $query; my $canon=`CQLParser -c '$query'`; - if ($canon ne $query) { + if ($canon eq $query) { + $nok++; + } else { print "ERROR: canonicalised query differs from original\n"; } } + +print "Passed $nok/$n -- ", int(100*$nok/$n), "%\n"; From 6576a20678aedf101f2e7d25628c48121a9757e6 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:06:40 +0200 Subject: [PATCH 029/147] Rename .cvsignore to .gitignore --- docs/{.cvsignore => .gitignore} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{.cvsignore => .gitignore} (100%) diff --git a/docs/.cvsignore b/docs/.gitignore similarity index 100% rename from docs/.cvsignore rename to docs/.gitignore From a719f98137eb5c7a300e7e66a5a36903f9009b90 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:09:47 +0200 Subject: [PATCH 030/147] Release 1.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d536a3d..663fe2c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.z3950.zing cql-java jar - 1.4 + 1.5 cql-java http://maven.apache.org From 7cffa653fbadef402ccc6af3bf6696e06b7858ee Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:19:30 +0200 Subject: [PATCH 031/147] Updated for V1.2 semantics. --- test/regression/sections/02/02.xcql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/regression/sections/02/02.xcql b/test/regression/sections/02/02.xcql index 2b78ddf..edd35b8 100644 --- a/test/regression/sections/02/02.xcql +++ b/test/regression/sections/02/02.xcql @@ -1,7 +1,7 @@ - title + cql.serverChoice - exact + = - fish + title exact fish From b306a0bee75d8a4cc9eef354a217fe8d335b36e8 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:36:57 +0200 Subject: [PATCH 032/147] Modify some test-queries to fit 1.2 syntax. --- test/regression/queries.raw | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/regression/queries.raw b/test/regression/queries.raw index c4104ca..6075e69 100644 --- a/test/regression/queries.raw +++ b/test/regression/queries.raw @@ -26,7 +26,7 @@ dc.title any/stem fish dc.fish all/stem/fuzzy "fish chips" (title any frog) ((dc.title any/stem "frog pond")) -dc.title scr "fish frog chicken" +dc.title any "fish frog chicken" dc.title =/rel.algorithm=CORI squid author any/f.foo/b.bar>1 "sanderson taylor" numberOfLegs <= 4 @@ -57,7 +57,7 @@ cat prox/distance=3/unit=word/ordered hat cat prox/distance<3 hat "fish food" prox/unit=sentence and title all "chips frog" prox/distance<=5 exact -(dc.author exact "jones" prox/distance>5/unit=element title >= "smith") +(dc.author == "jones" prox/distance>5/unit=element title >= "smith") ((cat prox hat)) a and/rel.SumOfScores b a and/rel.algorithm=CORI b @@ -85,7 +85,7 @@ cat?dog # Lame Searches -any or all:stem and all exact any prox prox=fuzzy +any or all:stem and all contains any prox proxfuzzy (((((((((any))))))))) "" > any > any = exact any > any From bbf1fb7346c159289fc392c25de4ea1ece7fe2bf Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:37:55 +0200 Subject: [PATCH 033/147] Updated results for fixed queries and V1.2 relations --- test/regression/sections/02/12.xcql | 2 +- test/regression/sections/05/06.xcql | 2 +- test/regression/sections/09/01.xcql | 46 ++++++++++------------------- 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/test/regression/sections/02/12.xcql b/test/regression/sections/02/12.xcql index a648cc5..b4bcf3b 100644 --- a/test/regression/sections/02/12.xcql +++ b/test/regression/sections/02/12.xcql @@ -1,7 +1,7 @@ dc.title - scr + any fish frog chicken diff --git a/test/regression/sections/05/06.xcql b/test/regression/sections/05/06.xcql index 42029b0..4ffea29 100644 --- a/test/regression/sections/05/06.xcql +++ b/test/regression/sections/05/06.xcql @@ -18,7 +18,7 @@ dc.author - exact + == jones diff --git a/test/regression/sections/09/01.xcql b/test/regression/sections/09/01.xcql index d0a5e52..f721ed0 100644 --- a/test/regression/sections/09/01.xcql +++ b/test/regression/sections/09/01.xcql @@ -1,55 +1,39 @@ - prox + and - and + or - - - or - - - - cql.serverChoice - - = - - any - - - - - cql.serverChoice - - = - - all:stem - - - + + cql.serverChoice + + = + + any + - all + cql.serverChoice - exact + = - any + all:stem - prox + all contains - = + any - fuzzy + prox proxfuzzy From ca93d10a428f70674dc47b8f2b9c824e0c0b4aa8 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 25 May 2010 16:44:39 +0200 Subject: [PATCH 034/147] Release 1.5 --- Changes | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Changes b/Changes index 1197ce9..1a85da8 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,16 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. +1.5 Tue May 25 16:44:35 CEST 2010 + - Fix recognition of word-relations to correctly match what is + specified in the CQL v1.1 and v1.2 documents. In + particular, "encloses" and "within" are recognised, so that + Masterkey's use of "encloses" for IP range authentication + works again. + - Update regression tests accordingly. + - Extend test/random/ to emit summary line of successful + recompilations. + 1.4 Thu May 20 00:38:40 BST 2010 - Add support for interpreting sequences of non-keywords as a single multi-word term rather than a broken INDEX RELATION From 73b5fc1a94eab5761e96ba3890688d2eb1a9301a Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 17 Jun 2010 10:55:39 +0100 Subject: [PATCH 035/147] Remove 'target' from distribution. --- mkdist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdist b/mkdist index 13fcf9b..fb065f8 100755 --- a/mkdist +++ b/mkdist @@ -11,11 +11,11 @@ trap "rm -rf $tmpdir" 1 2 15 # 0 cp -rp . $tmpdir cd $tmpdir find . \( -name CVS -o -name .cvsignore \) -print | xargs rm -rf -rm -rf archive mkdist etc/xslt .git +rm -rf archive mkdist etc/xslt .git target ( cd src/main/java/org/z3950/zing/cql && make && make clean ) ( cd docs && make ) ( cd test/regression && make distclean ) cd .. tar cf - $distdir | gzip -9v > $distfile rm -rf $tmpdir -echo "Made $distfile" +echo "Made /tmp/$distfile" From f134c1f96541111e111f00e620118c1813c0d412 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 17 Jun 2010 10:56:13 +0100 Subject: [PATCH 036/147] A fix at last for the lexing bug for terms that begin with digits -- thanks to Erik Hetzner for the patch. --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 5df3822..7aca234 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -69,7 +69,11 @@ private class Keyword { ordinaryChar('('); ordinaryChar(')'); wordChars('\'', '\''); // prevent this from introducing strings - parseNumbers(); + //parseNumbers(); + ordinaryChar('-'); + wordChars('-', '-'); + ordinaryChars('0', '9'); + wordChars('0', '9'); DEBUG = lexdebug; } From 3e97d3ae992857c62bb697c1be31f3f40edf8576 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 17 Jun 2010 10:56:29 +0100 Subject: [PATCH 037/147] Release 1.6 --- Changes | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index 1a85da8..93b05d5 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,12 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. +1.6 Thu Jun 17 10:56:24 BST 2010 + - Fix the bug where "9x" is lexed as two tokens, a TT_NUMBER + followed by a TT_WORD, making unquoted search-terms such as + 2010-06-17 syntax errors. Thanks to Erik Hetzner + for the patch. + 1.5 Tue May 25 16:44:35 CEST 2010 - Fix recognition of word-relations to correctly match what is specified in the CQL v1.1 and v1.2 documents. In @@ -196,10 +202,6 @@ Library of Australia, whose help we gratefully acknowledge. case-sensitivity. - Add a new configuration file that allows arbitrary new relations and relation modifiers to be defined. - - Fix the bug where "9x" is parsed as two tokens, a TT_NUMBER - followed by a TT_WORD. The problem here is that I don't - think it's actually possible to fix this without throwing - out StreamTokenizer and rolling our own, which we absolutely - Fix term-to-PQF translation to omit empty properties (for the broken Korean server) - Write "package.html" file for the javadoc documentation. From 4d84226ed6ab8219f1ed4285af55592fead4c8da Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 17 Jun 2010 10:57:56 +0100 Subject: [PATCH 038/147] Fix pom.xml to build/install version 1.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 663fe2c..1071e8f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.z3950.zing cql-java jar - 1.5 + 1.6 cql-java http://maven.apache.org From cb987ade92bf94da6dd321fd585f70a6dd711da8 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Thu, 17 Jun 2010 11:00:30 +0100 Subject: [PATCH 039/147] Version number to 1.6 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index c068b24..810ee4e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.4 +1.6 From 54f3ed06b35c7f352909cf159432e961ca38c264 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 27 Jul 2010 17:16:38 +0100 Subject: [PATCH 040/147] Patch from Ralph LeVan to recognise "qualifier.dc.creator"-like properties as well as "index.dc.creator" -- backwards compatible with version prior to 1.0 as well as those subsequent. --- src/main/java/org/z3950/zing/cql/CQLTermNode.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index f9b17ac..924b6ba 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -43,6 +43,7 @@ private static boolean isResultSetIndex(String qual) { qual.equals("cql.resultSetName")); } + @Override public String getResultSetName() { if (isResultSetIndex(index)) return term; @@ -95,6 +96,8 @@ private Vector getAttrs(Properties config) throws PQFTranslationException { attrs.add(attr); attr = config.getProperty("index." + index); + if (attr == null) + attr = config.getProperty("qualifier." + index); if (attr == null) throw new UnknownIndexException(index); attrs.add(attr); @@ -227,7 +230,7 @@ public byte[] toType1BER(Properties config) throws PQFTranslationException { if (len > 0 && text.substring(len-1, len).equals("^")) text = text.substring(0, len-1); - String attr, attrList, term = text; + String attr, attrList; byte[] operand = new byte[text.length()+100]; int i, j, offset, type, value; offset = putTag(CONTEXT, 0, CONSTRUCTED, operand, 0); // op @@ -264,7 +267,7 @@ public byte[] toType1BER(Properties config) throws PQFTranslationException { operand[offset++] = 0x00; offset = putTag(CONTEXT, 45, PRIMITIVE, operand, offset); // general Term - byte[] t = term.getBytes(); + byte[] t = text.getBytes(); offset = putLen(t.length, operand, offset); System.arraycopy(t, 0, operand, offset, t.length); offset += t.length; From 8949cd732beec19c23b09c261577677eaf2ae67e Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 27 Jul 2010 17:17:16 +0100 Subject: [PATCH 041/147] Towards v1.7 --- Changes | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Changes b/Changes index 93b05d5..1ceac7d 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,12 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. +1.7 [IN PROGRESS] + - Patch from Ralph LeVan to recognise + "qualifier.dc.creator"-like properties as well as + "index.dc.creator" -- backwards compatible with version + prior to 1.0 as well as those subsequent. + 1.6 Thu Jun 17 10:56:24 BST 2010 - Fix the bug where "9x" is lexed as two tokens, a TT_NUMBER followed by a TT_WORD, making unquoted search-terms such as From 1387063d408c45ec66e3c21f0e4dcf5cf211beb9 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 27 Jul 2010 17:20:57 +0100 Subject: [PATCH 042/147] Reinstate the "exact" relation even when v1.2 is in effect (the default), despite its removal from v1.2 of CQL. In practice, it seems to be in fairly widespread use, and little real purpose is served in removing it. --- src/main/java/org/z3950/zing/cql/CQLParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 90e9f59..cf1272c 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -245,7 +245,7 @@ private boolean isRelation() { lexer.sval.equals("all") || lexer.sval.equals("within") || lexer.sval.equals("encloses") || - (lexer.sval.equals("exact") && compat != V1POINT2) || + lexer.sval.equals("exact") || (lexer.sval.equals("scr") && compat != V1POINT2) || (lexer.sval.equals("adj") && compat == V1POINT2))) return true; From 11d547b83c661823bc32ea0fb7de831d050d87fb Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 27 Jul 2010 17:21:19 +0100 Subject: [PATCH 043/147] More changes for v1.7 --- Changes | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changes b/Changes index 1ceac7d..9948e81 100644 --- a/Changes +++ b/Changes @@ -11,6 +11,10 @@ Library of Australia, whose help we gratefully acknowledge. "qualifier.dc.creator"-like properties as well as "index.dc.creator" -- backwards compatible with version prior to 1.0 as well as those subsequent. + - Reinstate the "exact" relation even when v1.2 is in effect + (the default), despite its removal from v1.2 of CQL. In + practice, it seems to be in fairly widespread use, and + little real purpose is served in removing it. 1.6 Thu Jun 17 10:56:24 BST 2010 - Fix the bug where "9x" is lexed as two tokens, a TT_NUMBER From 5210c88d6b74dcd0bfb37bf973fe7b0e3613864e Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 27 Jul 2010 17:31:12 +0100 Subject: [PATCH 044/147] Tweak expected output of test 02/02 to allow for the reinstatement of the "exact" relation. --- test/regression/sections/02/02.xcql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/regression/sections/02/02.xcql b/test/regression/sections/02/02.xcql index edd35b8..2b78ddf 100644 --- a/test/regression/sections/02/02.xcql +++ b/test/regression/sections/02/02.xcql @@ -1,7 +1,7 @@ - cql.serverChoice + title - = + exact - title exact fish + fish From f6a814227aefa2fc8596e89d9d4c8677348c58a9 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 27 Jul 2010 17:35:16 +0100 Subject: [PATCH 045/147] Bump version number to 1.7 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 810ee4e..d3bdbdf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.6 +1.7 From 57c753117eff047d3223cbb4c419abcea24daaea Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Tue, 27 Jul 2010 17:35:29 +0100 Subject: [PATCH 046/147] Release 1.7 --- Changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changes b/Changes index 9948e81..69ceb31 100644 --- a/Changes +++ b/Changes @@ -6,7 +6,7 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. -1.7 [IN PROGRESS] +1.7 Tue Jul 27 17:35:25 BST 2010 - Patch from Ralph LeVan to recognise "qualifier.dc.creator"-like properties as well as "index.dc.creator" -- backwards compatible with version From 1d9c3f38d80f705dbed7b26ec59fdc3bf1884bfe Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 28 Jul 2010 09:41:46 +0100 Subject: [PATCH 047/147] pom.xml version (for Maven) up to 1.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1071e8f..f8012c2 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.z3950.zing cql-java jar - 1.6 + 1.7 cql-java http://maven.apache.org From 46c3b079ceedf72b8447152e35d518d541728350 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 11:22:41 +0200 Subject: [PATCH 048/147] Make constants read-only --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 18 +++++++++--------- .../java/org/z3950/zing/cql/CQLParser.java | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 7aca234..31abebc 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -16,15 +16,15 @@ // class CQLLexer extends StreamTokenizer { // New publicly visible token-types - static int TT_LE = 1000; // The "<=" relation - static int TT_GE = 1001; // The ">=" relation - static int TT_NE = 1002; // The "<>" relation - static int TT_EQEQ = 1003; // The "==" relation - static int TT_AND = 1004; // The "and" boolean - static int TT_OR = 1005; // The "or" boolean - static int TT_NOT = 1006; // The "not" boolean - static int TT_PROX = 1007; // The "prox" boolean - static int TT_SORTBY = 1008; // The "sortby" operator + public final static int TT_LE = 1000; // The "<=" relation + public final static int TT_GE = 1001; // The ">=" relation + public final static int TT_NE = 1002; // The "<>" relation + public final static int TT_EQEQ = 1003; // The "==" relation + public final static int TT_AND = 1004; // The "and" boolean + public final static int TT_OR = 1005; // The "or" boolean + public final static int TT_NOT = 1006; // The "not" boolean + public final static int TT_PROX = 1007; // The "prox" boolean + public final static int TT_SORTBY = 1008; // The "sortby" operator // Support for keywords. It would be nice to compile this linear // list into a Hashtable, but it's hard to store ints as hash diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index cf1272c..dd69218 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -19,9 +19,9 @@ public class CQLParser { private CQLLexer lexer; private int compat; // When false, implement CQL 1.2 - public static int V1POINT1 = 12368; - public static int V1POINT2 = 12369; - public static int V1POINT1SORT = 12370; + public static final int V1POINT1 = 12368; + public static final int V1POINT2 = 12369; + public static final int V1POINT1SORT = 12370; static private boolean DEBUG = false; static private boolean LEXDEBUG = false; From 41fcd9c3be17618728c4f175e4cb65ed61421447 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 12:40:55 +0200 Subject: [PATCH 049/147] Hide some memebers as private, add getters --- Changes | 5 +++++ .../org/z3950/zing/cql/CQLBooleanNode.java | 22 ++++++++++++++----- .../java/org/z3950/zing/cql/CQLGenerator.java | 4 ++-- src/main/java/org/z3950/zing/cql/CQLNode.java | 3 +-- .../java/org/z3950/zing/cql/CQLParser.java | 2 +- .../java/org/z3950/zing/cql/CQLPrefix.java | 12 ++++++++-- .../org/z3950/zing/cql/CQLPrefixNode.java | 12 ++++++++-- .../java/org/z3950/zing/cql/CQLRelation.java | 11 ---------- .../java/org/z3950/zing/cql/CQLSortNode.java | 6 ++++- .../java/org/z3950/zing/cql/ModifierSet.java | 4 ++-- 10 files changed, 53 insertions(+), 28 deletions(-) diff --git a/Changes b/Changes index 69ceb31..e5159f6 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,11 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. +1.8 IN PROGRESS + - API changes: more information hiding, introduce getters + - make some contants read-only + + 1.7 Tue Jul 27 17:35:25 BST 2010 - Patch from Ralph LeVan to recognise "qualifier.dc.creator"-like properties as well as diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index ec0608c..a5b1772 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -11,20 +11,32 @@ * @version $Id: CQLBooleanNode.java,v 1.18 2007-07-03 16:03:00 mike Exp $ */ public abstract class CQLBooleanNode extends CQLNode { + + private CQLNode left; + /** * The root of a parse-tree representing the left-hand side. - */ - public CQLNode left; + */ + public CQLNode getLeft() { + return left; + } + + private CQLNode right; /** * The root of a parse-tree representing the right-hand side. - */ - public CQLNode right; + */ + public CQLNode getRight() { + return right; + } + ModifierSet ms; /** * The set of modifiers that are applied to this boolean. */ - public ModifierSet ms; + public Vector getModifiers() { + return ms.getModifiers(); + } protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms) { this.left = left; diff --git a/src/main/java/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java index cc8ac14..8d02022 100644 --- a/src/main/java/org/z3950/zing/cql/CQLGenerator.java +++ b/src/main/java/org/z3950/zing/cql/CQLGenerator.java @@ -27,8 +27,8 @@ * >http://zing.z3950.org/cql/index.html */ public class CQLGenerator { - Properties params; - Random rnd; + private Properties params; + private Random rnd; static private boolean DEBUG = false; /** diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index 3e42e1e..d300782 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -191,8 +191,7 @@ protected static final int putTag(int asn1class, int fldid, int form, * @param len length to put into record * @return the new, incremented value of the offset parameter. */ - public // ### shouldn't this be protected? - static final int putLen(int len, byte[] record, int offset) { + static final int putLen(int len, byte[] record, int offset) { if (len < 128) record[offset++] = (byte)len; diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index dd69218..b8f2ef9 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -206,7 +206,7 @@ private CQLNode parseTerm(String index, CQLRelation relation) relation = new CQLRelation(relstr); match(lexer.ttype); ModifierSet ms = gatherModifiers(relstr); - relation.setModifiers(ms); + relation.ms = ms; debug("index='" + index + ", " + "relation='" + relation.toCQL() + "'"); } diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefix.java b/src/main/java/org/z3950/zing/cql/CQLPrefix.java index af7c906..374535a 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefix.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefix.java @@ -14,14 +14,22 @@ public class CQLPrefix { * itself, such as dc, as it might be used in an index * like dc.title. */ - public String name; + String name; + + public String getName() { + return name; + } /** * The full identifier name of the prefix mapping. That is, * typically, a URI permanently allocated to a specific index * set, such as http://zthes.z3950.org/cql/1.0. */ - public String identifier; + String identifier; + + public String getIdentifier() { + return identifier; + } /** * Creates a new CQLPrefix mapping, which maps the specified name diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index dd01d85..10cff1a 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -15,13 +15,21 @@ public class CQLPrefixNode extends CQLNode { /** * The prefix definition that governs the subtree. */ - public CQLPrefix prefix; + private CQLPrefix prefix; + + public CQLPrefix getPrefix() { + return prefix; + } /** * The root of a parse-tree representing the part of the query * that is governed by this prefix definition. */ - public CQLNode subtree; + private CQLNode subtree; + + public CQLNode getSubtree() { + return subtree; + } /** * Creates a new CQLPrefixNode inducing a mapping from the diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 570afff..95eb303 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -35,17 +35,6 @@ public String getBase() { return ms.getBase(); } - /** - * Sets the modifiers of the specified CQLRelation. - * Typical relation modifiers include relevant, - * fuzzy, stem and phonetic. On the - * whole, these modifiers have a meaningful interpretation only - * for the text relations. - */ - public void setModifiers(ModifierSet ms) { - this.ms = ms; - } - /** * Returns an array of the modifiers associated with a CQLRelation. * @return diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 6e7f21d..53c7ef1 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -15,7 +15,7 @@ public class CQLSortNode extends CQLNode { * The root of a subtree representing the query whose result is to * be sorted. */ - public CQLNode subtree; + private CQLNode subtree; /** * The set of sort keys by which results are to be sorted, @@ -24,6 +24,10 @@ public class CQLSortNode extends CQLNode { */ Vector keys; + public CQLNode getSubtree() { + return subtree; + } + public CQLSortNode(CQLNode subtree) { this.subtree = subtree; keys = new Vector(); diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index 7b6991a..835e731 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -18,8 +18,8 @@ * @version $Id: ModifierSet.java,v 1.13 2007-07-03 13:30:18 mike Exp $ */ public class ModifierSet { - String base; - Vector modifiers; + private String base; + private Vector modifiers; /** * Creates a new ModifierSet with the specified base. From 0109aec019aeba5a9ef1e42cb08a796a3cb5fc88 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 13:02:42 +0200 Subject: [PATCH 050/147] Maven version 1.8 --- pom.xml | 2 +- test/random/Makefile | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f8012c2..53a1e90 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.z3950.zing cql-java jar - 1.7 + 1.8 cql-java http://maven.apache.org diff --git a/test/random/Makefile b/test/random/Makefile index cdb8f4e..e64135d 100644 --- a/test/random/Makefile +++ b/test/random/Makefile @@ -1,7 +1,10 @@ # $Id: Makefile,v 1.2 2007-06-07 16:16:15 mike Exp $ -all: - PATH=$(PATH):../../bin CLASSPATH=../../lib/cql-java.jar ./mkrandom 100 +../../target/cql-java-1.7.jar: + cd ../../ && mvn compile + +all: ../../target/cql-java-1.7.jar + PATH=$(PATH):../../bin CLASSPATH=../../target/cql-java-1.7.jar ./mkrandom 100 clean: @echo "Nothing to do to 'make clean'" From 791833362f2e87616d70ffc3f1ce6b0191ff7a0f Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 13:39:04 +0200 Subject: [PATCH 051/147] Change obsolete collections, remove redundant imports --- .../org/z3950/zing/cql/CQLBooleanNode.java | 8 ++++---- .../java/org/z3950/zing/cql/CQLLexer.java | 1 - src/main/java/org/z3950/zing/cql/CQLNode.java | 20 ++++++++++--------- .../org/z3950/zing/cql/CQLParseException.java | 1 - .../java/org/z3950/zing/cql/CQLParser.java | 5 +++-- .../java/org/z3950/zing/cql/CQLPrefix.java | 1 - .../org/z3950/zing/cql/CQLPrefixNode.java | 14 ++++++------- .../java/org/z3950/zing/cql/CQLRelation.java | 8 ++++---- .../java/org/z3950/zing/cql/CQLSortNode.java | 13 ++++++------ .../java/org/z3950/zing/cql/CQLTermNode.java | 17 ++++++++-------- .../zing/cql/MissingParameterException.java | 1 - .../java/org/z3950/zing/cql/Modifier.java | 1 - .../java/org/z3950/zing/cql/ModifierSet.java | 9 +++++---- .../zing/cql/PQFTranslationException.java | 1 - .../z3950/zing/cql/UnknownIndexException.java | 1 - .../zing/cql/UnknownPositionException.java | 1 - .../zing/cql/UnknownRelationException.java | 1 - .../cql/UnknownRelationModifierException.java | 1 - 18 files changed, 50 insertions(+), 54 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index a5b1772..dafb19b 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -1,8 +1,8 @@ // $Id: CQLBooleanNode.java,v 1.18 2007-07-03 16:03:00 mike Exp $ package org.z3950.zing.cql; +import java.util.List; import java.util.Properties; -import java.util.Vector; /** @@ -34,7 +34,7 @@ public CQLNode getRight() { /** * The set of modifiers that are applied to this boolean. */ - public Vector getModifiers() { + public List getModifiers() { return ms.getModifiers(); } @@ -44,8 +44,8 @@ protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms) { this.ms = ms; } - public String toXCQL(int level, Vector prefixes, - Vector sortkeys) { + public String toXCQL(int level, List prefixes, + List sortkeys) { return (indent(level) + "\n" + renderPrefixes(level+1, prefixes) + ms.toXCQL(level+1, "boolean") + diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 31abebc..b0da745 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -3,7 +3,6 @@ package org.z3950.zing.cql; import java.io.StreamTokenizer; import java.io.StringReader; -import java.util.Hashtable; // This is a semi-trivial subclass for java.io.StreamTokenizer that: diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index d300782..34add8e 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -1,8 +1,10 @@ // $Id: CQLNode.java,v 1.26 2007-07-03 13:36:03 mike Exp $ package org.z3950.zing.cql; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Properties; -import java.util.Vector; /** @@ -41,19 +43,19 @@ public String toXCQL(int level) { return toXCQL(level, null); } - public String toXCQL(int level, Vector prefixes) { + public String toXCQL(int level, List prefixes) { return toXCQL(level, prefixes, null); } - abstract public String toXCQL(int level, Vector prefixes, - Vector sortkeys); + abstract public String toXCQL(int level, List prefixes, + List sortkeys); - protected static String renderPrefixes(int level, Vector prefixes) { + protected static String renderPrefixes(int level, List prefixes) { if (prefixes == null || prefixes.size() == 0) return ""; String res = indent(level) + "\n"; for (int i = 0; i < prefixes.size(); i++) { - CQLPrefix p = (CQLPrefix) prefixes.get(i); + CQLPrefix p = prefixes.get(i); res += indent(level+1) + "\n"; if (p.name != null) res += indent(level+2) + "" + p.name + "\n"; @@ -65,7 +67,7 @@ protected static String renderPrefixes(int level, Vector prefixes) { } protected static String renderSortKeys(int level, - Vector sortkeys) { + List sortkeys) { if (sortkeys == null || sortkeys.size() == 0) return ""; String res = indent(level) + "\n"; @@ -261,8 +263,8 @@ protected static final int putNum(long num, byte record[], int offset) { } // Used only by the makeOID() method - private static final java.util.Hashtable madeOIDs = - new java.util.Hashtable(10); + private static final Map madeOIDs = + new HashMap(10); protected static final byte[] makeOID(String oid) { byte[] o; diff --git a/src/main/java/org/z3950/zing/cql/CQLParseException.java b/src/main/java/org/z3950/zing/cql/CQLParseException.java index 845dfff..ee237f5 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParseException.java +++ b/src/main/java/org/z3950/zing/cql/CQLParseException.java @@ -1,7 +1,6 @@ // $Id: CQLParseException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; -import java.lang.Exception; /** diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index b8f2ef9..0503977 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -2,11 +2,12 @@ package org.z3950.zing.cql; import java.io.IOException; -import java.util.Vector; import java.util.Properties; import java.io.InputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; /** @@ -369,7 +370,7 @@ public static void main (String[] args) { char mode = 'x'; // x=XCQL, c=CQL, p=PQF String pfile = null; - Vector argv = new Vector(); + List argv = new ArrayList(); for (int i = 0; i < args.length; i++) { argv.add(args[i]); } diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefix.java b/src/main/java/org/z3950/zing/cql/CQLPrefix.java index 374535a..fac6503 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefix.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefix.java @@ -1,7 +1,6 @@ // $Id: CQLPrefix.java,v 1.5 2007-06-27 22:39:55 mike Exp $ package org.z3950.zing.cql; -import java.lang.String; /** * Represents a CQL prefix mapping from short name to long identifier. diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index 10cff1a..84fb9a7 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -1,9 +1,9 @@ // $Id: CQLPrefixNode.java,v 1.10 2007-07-03 16:40:11 mike Exp $ package org.z3950.zing.cql; -import java.lang.String; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; -import java.util.Vector; /** @@ -41,11 +41,11 @@ public CQLPrefixNode(String name, String identifier, CQLNode subtree) { this.subtree = subtree; } - public String toXCQL(int level, Vector prefixes, - Vector sortkeys) { - Vector tmp = (prefixes == null ? - new Vector() : - new Vector(prefixes)); + public String toXCQL(int level, List prefixes, + List sortkeys) { + List tmp = (prefixes == null ? + new ArrayList() : + new ArrayList(prefixes)); tmp.add(prefix); return subtree.toXCQL(level, tmp, sortkeys); } diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 95eb303..9e17d27 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -1,9 +1,8 @@ // $Id: CQLRelation.java,v 1.19 2007-07-03 13:40:58 mike Exp $ package org.z3950.zing.cql; -import java.util.Vector; +import java.util.List; import java.util.Properties; -import java.lang.StringBuffer; /** * Represents a relation between a CQL index and term. @@ -40,11 +39,12 @@ public String getBase() { * @return * An array of Modifier objects. */ - public Vector getModifiers() { + public List getModifiers() { return ms.getModifiers(); } - public String toXCQL(int level, Vector prefixes, Vector sortkeys) { + public String toXCQL(int level, List prefixes, + List sortkeys) { if (sortkeys != null) throw new Error("CQLRelation.toXCQL() called with sortkeys"); diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 53c7ef1..306f8c6 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -1,8 +1,9 @@ // $Id: CQLSortNode.java,v 1.2 2008-04-11 12:05:15 mike Exp $ package org.z3950.zing.cql; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; -import java.util.Vector; /** @@ -22,7 +23,7 @@ public class CQLSortNode extends CQLNode { * each expressed as an index together with zero or more * modifiers. */ - Vector keys; + List keys; public CQLNode getSubtree() { return subtree; @@ -30,19 +31,19 @@ public CQLNode getSubtree() { public CQLSortNode(CQLNode subtree) { this.subtree = subtree; - keys = new Vector(); + keys = new ArrayList(); } public void addSortIndex(ModifierSet key) { keys.add(key); } - public Vector getSortIndexes() { + public List getSortIndexes() { return keys; } - public String toXCQL(int level, Vector prefixes, - Vector sortkeys) { + public String toXCQL(int level, List prefixes, + List sortkeys) { if (sortkeys != null) throw new Error("CQLSortNode.toXCQL() called with sortkeys"); return subtree.toXCQL(level, prefixes, keys); diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index 924b6ba..1f03a4e 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -1,8 +1,9 @@ // $Id: CQLTermNode.java,v 1.28 2007-07-03 13:41:24 mike Exp $ package org.z3950.zing.cql; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; -import java.util.Vector; /** @@ -51,8 +52,8 @@ public String getResultSetName() { return null; } - public String toXCQL(int level, Vector prefixes, - Vector sortkeys) { + public String toXCQL(int level, List prefixes, + List sortkeys) { return (indent(level) + "\n" + renderPrefixes(level+1, prefixes) + indent(level+1) + "" + xq(index) + "\n" + @@ -80,8 +81,8 @@ public String toCQL() { // ### Interaction between this and its callers is not good as // regards truncation of the term and generation of truncation // attributes. Change the interface to fix this. - private Vector getAttrs(Properties config) throws PQFTranslationException { - Vector attrs = new Vector(); + private List getAttrs(Properties config) throws PQFTranslationException { + List attrs = new ArrayList(); // Do this first so that if any other truncation or // completeness attributes are generated, they "overwrite" @@ -118,7 +119,7 @@ private Vector getAttrs(Properties config) throws PQFTranslationException { throw new UnknownRelationException(rel); attrs.add(attr); - Vector mods = relation.getModifiers(); + List mods = relation.getModifiers(); for (int i = 0; i < mods.size(); i++) { String type = mods.get(i).type; attr = config.getProperty("relationModifier." + type); @@ -164,7 +165,7 @@ public String toPQF(Properties config) throws PQFTranslationException { return "@set " + maybeQuote(term); } - Vector attrs = getAttrs(config); + List attrs = getAttrs(config); String attr, s = ""; for (int i = 0; i < attrs.size(); i++) { @@ -240,7 +241,7 @@ public byte[] toType1BER(Properties config) throws PQFTranslationException { offset = putTag(CONTEXT, 44, CONSTRUCTED, operand, offset); // AttributeList operand[offset++] = (byte)(0x80&0xff); // indefinite length - Vector attrs = getAttrs(config); + List attrs = getAttrs(config); for(i = 0; i < attrs.size(); i++) { attrList = (String) attrs.get(i); java.util.StringTokenizer st = diff --git a/src/main/java/org/z3950/zing/cql/MissingParameterException.java b/src/main/java/org/z3950/zing/cql/MissingParameterException.java index 3b54668..07873b8 100644 --- a/src/main/java/org/z3950/zing/cql/MissingParameterException.java +++ b/src/main/java/org/z3950/zing/cql/MissingParameterException.java @@ -1,7 +1,6 @@ // $Id: MissingParameterException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; -import java.lang.Exception; /** diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index 4992b25..7b9fbbe 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -1,7 +1,6 @@ // $Id: Modifier.java,v 1.4 2007-07-03 13:29:34 mike Exp $ package org.z3950.zing.cql; -import java.util.Vector; import java.lang.StringBuffer; /** diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index 835e731..31fdad1 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -1,8 +1,9 @@ // $Id: ModifierSet.java,v 1.13 2007-07-03 13:30:18 mike Exp $ package org.z3950.zing.cql; -import java.util.Vector; import java.lang.StringBuffer; +import java.util.ArrayList; +import java.util.List; /** * Represents a base String and a set of Modifiers. @@ -19,14 +20,14 @@ */ public class ModifierSet { private String base; - private Vector modifiers; + private List modifiers; /** * Creates a new ModifierSet with the specified base. */ public ModifierSet(String base) { this.base = base; - modifiers = new Vector(); + modifiers = new ArrayList(); } /** @@ -73,7 +74,7 @@ public String modifier(String type) { * @return * An array of Modifiers. */ - public Vector getModifiers() { + public List getModifiers() { return modifiers; } diff --git a/src/main/java/org/z3950/zing/cql/PQFTranslationException.java b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java index 85ec184..0272e84 100644 --- a/src/main/java/org/z3950/zing/cql/PQFTranslationException.java +++ b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java @@ -1,7 +1,6 @@ // $Id: PQFTranslationException.java,v 1.1 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; -import java.lang.Exception; /** diff --git a/src/main/java/org/z3950/zing/cql/UnknownIndexException.java b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java index b4201d3..7eabe75 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownIndexException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java @@ -1,7 +1,6 @@ // $Id: UnknownIndexException.java,v 1.2 2007-06-27 22:44:40 mike Exp $ package org.z3950.zing.cql; -import java.lang.Exception; /** diff --git a/src/main/java/org/z3950/zing/cql/UnknownPositionException.java b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java index 5f38ab5..f1fc9f3 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownPositionException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java @@ -1,7 +1,6 @@ // $Id: UnknownPositionException.java,v 1.2 2002-11-29 16:42:54 mike Exp $ package org.z3950.zing.cql; -import java.lang.Exception; /** diff --git a/src/main/java/org/z3950/zing/cql/UnknownRelationException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java index 4d65e72..11cedb7 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownRelationException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java @@ -1,7 +1,6 @@ // $Id: UnknownRelationException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; -import java.lang.Exception; /** diff --git a/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java index 9d449b5..8025eb9 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java @@ -1,7 +1,6 @@ // $Id: UnknownRelationModifierException.java,v 1.1 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; -import java.lang.Exception; /** From 63162cbb93bec07caf9a8ec00cb0c006fea8dabd Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 14:19:31 +0200 Subject: [PATCH 052/147] Add override annotations --- src/main/java/org/z3950/zing/cql/CQLAndNode.java | 1 + src/main/java/org/z3950/zing/cql/CQLBooleanNode.java | 4 ++++ src/main/java/org/z3950/zing/cql/CQLLexer.java | 1 + src/main/java/org/z3950/zing/cql/CQLNotNode.java | 1 + src/main/java/org/z3950/zing/cql/CQLOrNode.java | 1 + src/main/java/org/z3950/zing/cql/CQLPrefixNode.java | 4 ++++ src/main/java/org/z3950/zing/cql/CQLProxNode.java | 2 ++ src/main/java/org/z3950/zing/cql/CQLRelation.java | 4 ++++ src/main/java/org/z3950/zing/cql/CQLSortNode.java | 4 ++++ src/main/java/org/z3950/zing/cql/CQLTermNode.java | 4 ++++ 10 files changed, 26 insertions(+) diff --git a/src/main/java/org/z3950/zing/cql/CQLAndNode.java b/src/main/java/org/z3950/zing/cql/CQLAndNode.java index dc452db..a1ebf76 100644 --- a/src/main/java/org/z3950/zing/cql/CQLAndNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLAndNode.java @@ -18,6 +18,7 @@ public CQLAndNode(CQLNode left, CQLNode right, ModifierSet ms) { } // ### Too much code duplication here with OR and NOT + @Override byte[] opType1() { byte[] op = new byte[5]; putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index dafb19b..465b725 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -44,6 +44,7 @@ protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms) { this.ms = ms; } + @Override public String toXCQL(int level, List prefixes, List sortkeys) { return (indent(level) + "\n" + @@ -59,6 +60,7 @@ public String toXCQL(int level, List prefixes, indent(level) + "\n"); } + @Override public String toCQL() { // ### We don't always need parens around the operands return ("(" + left.toCQL() + ")" + @@ -66,6 +68,7 @@ public String toCQL() { "(" + right.toCQL() + ")"); } + @Override public String toPQF(Properties config) throws PQFTranslationException { return ("@" + opPQF() + " " + left.toPQF(config) + @@ -75,6 +78,7 @@ public String toPQF(Properties config) throws PQFTranslationException { // represents the operation for PQF: overridden for CQLProxNode String opPQF() { return ms.getBase(); } + @Override public byte[] toType1BER(Properties config) throws PQFTranslationException { System.out.println("in CQLBooleanNode.toType1BER(): PQF=" + toPQF(config)); diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index b0da745..7bbf115 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -93,6 +93,7 @@ private void halfDecentPushBack() { saved_sval = sval; } + @Override public int nextToken() throws java.io.IOException { if (saved_ttype != TT_UNDEFINED) { ttype = saved_ttype; diff --git a/src/main/java/org/z3950/zing/cql/CQLNotNode.java b/src/main/java/org/z3950/zing/cql/CQLNotNode.java index 7b56de3..90346f4 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNotNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNotNode.java @@ -17,6 +17,7 @@ public CQLNotNode(CQLNode left, CQLNode right, ModifierSet ms) { super(left, right, ms); } + @Override byte[] opType1() { byte[] op = new byte[5]; putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator diff --git a/src/main/java/org/z3950/zing/cql/CQLOrNode.java b/src/main/java/org/z3950/zing/cql/CQLOrNode.java index 9e7d66e..67a292d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLOrNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLOrNode.java @@ -17,6 +17,7 @@ public CQLOrNode(CQLNode left, CQLNode right, ModifierSet ms) { super(left, right, ms); } + @Override byte[] opType1() { byte[] op = new byte[5]; putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index 84fb9a7..c793d2f 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -41,6 +41,7 @@ public CQLPrefixNode(String name, String identifier, CQLNode subtree) { this.subtree = subtree; } + @Override public String toXCQL(int level, List prefixes, List sortkeys) { List tmp = (prefixes == null ? @@ -50,6 +51,7 @@ public String toXCQL(int level, List prefixes, return subtree.toXCQL(level, tmp, sortkeys); } + @Override public String toCQL() { // ### We don't always need parens around the subtree if (prefix.name == null) { @@ -61,6 +63,7 @@ public String toCQL() { } } + @Override public String toPQF(Properties config) throws PQFTranslationException { // Prefixes and their identifiers don't actually play any role // in PQF translation, since the meanings of the indexes, @@ -69,6 +72,7 @@ public String toPQF(Properties config) throws PQFTranslationException { return subtree.toPQF(config); } + @Override public byte[] toType1BER(Properties config) throws PQFTranslationException { // See comment on toPQF() return subtree.toType1BER(config); diff --git a/src/main/java/org/z3950/zing/cql/CQLProxNode.java b/src/main/java/org/z3950/zing/cql/CQLProxNode.java index 2ce355f..9f1f0c3 100644 --- a/src/main/java/org/z3950/zing/cql/CQLProxNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLProxNode.java @@ -29,6 +29,7 @@ public CQLProxNode(CQLNode left, CQLNode right, ModifierSet ms) { * which-code ::= 'known' | 'private' | integer. * unit-code ::= integer. */ + @Override String opPQF() { int relCode = getRelCode(); int unitCode = getProxUnitCode(); @@ -77,6 +78,7 @@ private int getProxUnitCode() { } + @Override byte[] opType1() { byte[] op = new byte[100]; int offset, value; diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 9e17d27..44a55e6 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -43,6 +43,7 @@ public List getModifiers() { return ms.getModifiers(); } + @Override public String toXCQL(int level, List prefixes, List sortkeys) { if (sortkeys != null) @@ -51,14 +52,17 @@ public String toXCQL(int level, List prefixes, return ms.toXCQL(level, "relation"); } + @Override public String toCQL() { return ms.toCQL(); } + @Override public String toPQF(Properties config) throws PQFTranslationException { throw new Error("CQLRelation.toPQF() can never be called"); } + @Override public byte[] toType1BER(Properties config) { throw new Error("CQLRelation.toType1BER() can never be called"); } diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 306f8c6..1c3aa14 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -42,6 +42,7 @@ public List getSortIndexes() { return keys; } + @Override public String toXCQL(int level, List prefixes, List sortkeys) { if (sortkeys != null) @@ -49,6 +50,7 @@ public String toXCQL(int level, List prefixes, return subtree.toXCQL(level, prefixes, keys); } + @Override public String toCQL() { StringBuffer buf = new StringBuffer(subtree.toCQL()); @@ -63,10 +65,12 @@ public String toCQL() { return buf.toString(); } + @Override public String toPQF(Properties config) throws PQFTranslationException { return "@attr 1=oops \"###\""; } + @Override public byte[] toType1BER(Properties config) throws PQFTranslationException { // There is no way to represent sorting in a standard Z39.50 diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index 1f03a4e..b45abdc 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -52,6 +52,7 @@ public String getResultSetName() { return null; } + @Override public String toXCQL(int level, List prefixes, List sortkeys) { return (indent(level) + "\n" + @@ -63,6 +64,7 @@ public String toXCQL(int level, List prefixes, indent(level) + "\n"); } + @Override public String toCQL() { String quotedIndex = maybeQuote(index); String quotedTerm = maybeQuote(term); @@ -158,6 +160,7 @@ private List getAttrs(Properties config) throws PQFTranslationException return attrs; } + @Override public String toPQF(Properties config) throws PQFTranslationException { if (isResultSetIndex(index)) { // Special case: ignore relation, modifiers, wildcards, etc. @@ -204,6 +207,7 @@ static String maybeQuote(String str) { return str; } + @Override public byte[] toType1BER(Properties config) throws PQFTranslationException { if (isResultSetIndex(index)) { // Special case: ignore relation, modifiers, wildcards, etc. From 85a4cca539b075ae52cfed13e2c52da89e0bad9c Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 14:33:03 +0200 Subject: [PATCH 053/147] Replace object with class ref for statics --- .../java/org/z3950/zing/cql/CQLParser.java | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 0503977..7ed9f59 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -80,7 +80,7 @@ public CQLNode parse(String cql) debug("about to parseQuery()"); CQLNode root = parseTopLevelPrefixes("cql.serverChoice", new CQLRelation(compat == V1POINT2 ? "=" : "scr")); - if (lexer.ttype != lexer.TT_EOF) + if (lexer.ttype != CQLLexer.TT_EOF) throw new CQLParseException("junk after end: " + lexer.render()); return root; @@ -96,12 +96,12 @@ private CQLNode parseTopLevelPrefixes(String index, CQLRelation relation) CQLNode node = parseQuery(index, relation); if ((compat == V1POINT2 || compat == V1POINT1SORT) && - lexer.ttype == lexer.TT_SORTBY) { + lexer.ttype == CQLLexer.TT_SORTBY) { match(lexer.ttype); debug("sortspec"); CQLSortNode sortnode = new CQLSortNode(node); - while (lexer.ttype != lexer.TT_EOF) { + while (lexer.ttype != CQLLexer.TT_EOF) { String sortindex = matchSymbol("sort index"); ModifierSet ms = gatherModifiers(sortindex); sortnode.addSortIndex(ms); @@ -122,21 +122,21 @@ private CQLNode parseQuery(String index, CQLRelation relation) debug("in parseQuery()"); CQLNode term = parseTerm(index, relation); - while (lexer.ttype != lexer.TT_EOF && + while (lexer.ttype != CQLLexer.TT_EOF && lexer.ttype != ')' && - lexer.ttype != lexer.TT_SORTBY) { - if (lexer.ttype == lexer.TT_AND || - lexer.ttype == lexer.TT_OR || - lexer.ttype == lexer.TT_NOT || - lexer.ttype == lexer.TT_PROX) { + lexer.ttype != CQLLexer.TT_SORTBY) { + if (lexer.ttype == CQLLexer.TT_AND || + lexer.ttype == CQLLexer.TT_OR || + lexer.ttype == CQLLexer.TT_NOT || + lexer.ttype == CQLLexer.TT_PROX) { int type = lexer.ttype; String val = lexer.sval; match(type); ModifierSet ms = gatherModifiers(val); CQLNode term2 = parseTerm(index, relation); - term = ((type == lexer.TT_AND) ? new CQLAndNode(term, term2, ms) : - (type == lexer.TT_OR) ? new CQLOrNode (term, term2, ms) : - (type == lexer.TT_NOT) ? new CQLNotNode(term, term2, ms) : + term = ((type == CQLLexer.TT_AND) ? new CQLAndNode(term, term2, ms) : + (type == CQLLexer.TT_OR) ? new CQLOrNode (term, term2, ms) : + (type == CQLLexer.TT_NOT) ? new CQLNotNode(term, term2, ms) : new CQLProxNode(term, term2, ms)); } else { throw new CQLParseException("expected boolean, got " + @@ -155,7 +155,7 @@ private ModifierSet gatherModifiers(String base) ModifierSet ms = new ModifierSet(base); while (lexer.ttype == '/') { match('/'); - if (lexer.ttype != lexer.TT_WORD) + if (lexer.ttype != CQLLexer.TT_WORD) throw new CQLParseException("expected modifier, " + "got " + lexer.render()); String type = lexer.sval.toLowerCase(); @@ -193,16 +193,16 @@ private CQLNode parseTerm(String index, CQLRelation relation) debug("non-parenthesised term"); word = matchSymbol("index or term"); - while (lexer.ttype == lexer.TT_WORD && !isRelation()) { + while (lexer.ttype == CQLLexer.TT_WORD && !isRelation()) { word = word + " " + lexer.sval; - match(lexer.TT_WORD); + match(CQLLexer.TT_WORD); } if (!isRelation()) break; index = word; - String relstr = (lexer.ttype == lexer.TT_WORD ? + String relstr = (lexer.ttype == CQLLexer.TT_WORD ? lexer.sval : lexer.render(lexer.ttype, false)); relation = new CQLRelation(relstr); match(lexer.ttype); @@ -240,7 +240,7 @@ private CQLNode parsePrefix(String index, CQLRelation relation, private boolean isRelation() { debug("isRelation: checking ttype=" + lexer.ttype + " (" + lexer.render() + ")"); - if (lexer.ttype == lexer.TT_WORD && + if (lexer.ttype == CQLLexer.TT_WORD && (lexer.sval.indexOf('.') >= 0 || lexer.sval.equals("any") || lexer.sval.equals("all") || @@ -260,10 +260,10 @@ private boolean isSymbolicRelation() { return (lexer.ttype == '<' || lexer.ttype == '>' || lexer.ttype == '=' || - lexer.ttype == lexer.TT_LE || - lexer.ttype == lexer.TT_GE || - lexer.ttype == lexer.TT_NE || - lexer.ttype == lexer.TT_EQEQ); + lexer.ttype == CQLLexer.TT_LE || + lexer.ttype == CQLLexer.TT_GE || + lexer.ttype == CQLLexer.TT_NE || + lexer.ttype == CQLLexer.TT_EQEQ); } private void match(int token) @@ -283,20 +283,20 @@ private String matchSymbol(String expected) throws CQLParseException, IOException { debug("in matchSymbol()"); - if (lexer.ttype == lexer.TT_WORD || - lexer.ttype == lexer.TT_NUMBER || + if (lexer.ttype == CQLLexer.TT_WORD || + lexer.ttype == CQLLexer.TT_NUMBER || lexer.ttype == '"' || // The following is a complete list of keywords. Because // they're listed here, they can be used unquoted as // indexes, terms, prefix names and prefix identifiers. // ### Instead, we should ask the lexer whether what we // have is a keyword, and let the knowledge reside there. - lexer.ttype == lexer.TT_AND || - lexer.ttype == lexer.TT_OR || - lexer.ttype == lexer.TT_NOT || - lexer.ttype == lexer.TT_PROX || - lexer.ttype == lexer.TT_SORTBY) { - String symbol = (lexer.ttype == lexer.TT_NUMBER) ? + lexer.ttype == CQLLexer.TT_AND || + lexer.ttype == CQLLexer.TT_OR || + lexer.ttype == CQLLexer.TT_NOT || + lexer.ttype == CQLLexer.TT_PROX || + lexer.ttype == CQLLexer.TT_SORTBY) { + String symbol = (lexer.ttype == CQLLexer.TT_NUMBER) ? lexer.render() : lexer.sval; match(lexer.ttype); return symbol; From b07c9ebbcf1956dc21df4fb7737439e369e30e83 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 14:47:43 +0200 Subject: [PATCH 054/147] Use StringBuilder instead of StringBuffer, optimize --- .../java/org/z3950/zing/cql/CQLSortNode.java | 4 +-- .../java/org/z3950/zing/cql/Modifier.java | 27 +++++++++---------- .../java/org/z3950/zing/cql/ModifierSet.java | 22 +++++++-------- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 1c3aa14..55e69d5 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -52,13 +52,13 @@ public String toXCQL(int level, List prefixes, @Override public String toCQL() { - StringBuffer buf = new StringBuffer(subtree.toCQL()); + StringBuilder buf = new StringBuilder(subtree.toCQL()); if (keys != null) { buf.append(" sortby"); for (int i = 0; i < keys.size(); i++) { ModifierSet key = keys.get(i); - buf.append(" " + key.toCQL()); + buf.append(" ").append(key.toCQL()); } } diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index 7b9fbbe..9057dee 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -1,7 +1,6 @@ // $Id: Modifier.java,v 1.4 2007-07-03 13:29:34 mike Exp $ package org.z3950.zing.cql; -import java.lang.StringBuffer; /** * Represents a single modifier, consisting of three elements: a type, @@ -60,27 +59,27 @@ public String getValue() { } public String toXCQL(int level, String relationElement) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); - buf.append(Utils.indent(level) + "\n"); - buf.append(Utils.indent(level+1) + - "" + Utils.xq(type) + "\n"); + buf.append(Utils.indent(level)).append("\n"). + append(Utils.indent(level + 1)).append(""). + append(Utils.xq(type)).append("\n"); if (value != null) { - buf.append(Utils.indent(level+1) + "<" + relationElement + ">" + - Utils.xq(comparison) + "\n"); - buf.append(Utils.indent(level+1) + - "" + Utils.xq(value) + "\n"); + buf.append(Utils.indent(level + 1)).append("<"). + append(relationElement).append(">"). + append(Utils.xq(comparison)).append("\n"). + append(Utils.indent(level + 1)).append(""). + append(Utils.xq(value)).append("\n"); } - - buf.append(Utils.indent(level) + "\n"); + buf.append(Utils.indent(level)).append("\n"); return buf.toString(); } public String toCQL() { - StringBuffer buf = new StringBuffer(type); + StringBuilder buf = new StringBuilder(type); if (value != null) - buf.append(" " + comparison + " " + value); - + buf.append(" ").append(comparison).append(" ").append(value); return buf.toString(); } } diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index 31fdad1..ce5915c 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -1,7 +1,6 @@ // $Id: ModifierSet.java,v 1.13 2007-07-03 13:30:18 mike Exp $ package org.z3950.zing.cql; -import java.lang.StringBuffer; import java.util.ArrayList; import java.util.List; @@ -88,26 +87,27 @@ public String sortKeyToXCQL(int level) { private String underlyingToXCQL(int level, String topLevelElement, String valueElement) { - StringBuffer buf = new StringBuffer(); - buf.append(Utils.indent(level) + "<" + topLevelElement + ">\n"); - buf.append(Utils.indent(level+1) + - "<" + valueElement + ">" + Utils.xq(base) + - "\n"); + StringBuilder buf = new StringBuilder(); + buf.append(Utils.indent(level)).append("<").append(topLevelElement). + append(">\n").append(Utils.indent(level + 1)).append("<"). + append(valueElement).append(">").append(Utils.xq(base)).append("\n"); if (modifiers.size() > 0) { - buf.append(Utils.indent(level+1) + "\n"); + buf.append(Utils.indent(level + 1)).append("\n"); for (int i = 0; i < modifiers.size(); i++) { buf.append(modifiers.get(i).toXCQL(level+2, "comparison")); } - buf.append(Utils.indent(level+1) + "\n"); + buf.append(Utils.indent(level + 1)).append("\n"); } - buf.append(Utils.indent(level) + "\n"); + buf.append(Utils.indent(level)).append("\n"); return buf.toString(); } public String toCQL() { - StringBuffer buf = new StringBuffer(base); + StringBuilder buf = new StringBuilder(base); for (int i = 0; i < modifiers.size(); i++) { - buf.append("/" + modifiers.get(i).toCQL()); + buf.append("/").append(modifiers.get(i).toCQL()); } return buf.toString(); From f079ba53623fc80782044f8f06488d19a3948b27 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 14:59:39 +0200 Subject: [PATCH 055/147] Rewrite inefficient string functions --- .../java/org/z3950/zing/cql/CQLTermNode.java | 4 +- src/main/java/org/z3950/zing/cql/Utils.java | 41 ++++++++----------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index b45abdc..5966700 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -173,7 +173,7 @@ public String toPQF(Properties config) throws PQFTranslationException { String attr, s = ""; for (int i = 0; i < attrs.size(); i++) { attr = (String) attrs.get(i); - s += "@attr " + Utils.replaceString(attr, " ", " @attr ") + " "; + s += "@attr " + attr.replace(" ", " @attr ") + " "; } String text = term; @@ -201,7 +201,7 @@ static String maybeQuote(String str) { str.indexOf('/') != -1 || str.indexOf('(') != -1 || str.indexOf(')') != -1) { - str = '"' + Utils.replaceString(str, "\"", "\\\"") + '"'; + str = '"' + str.replace("\"", "\\\"") + '"'; } return str; diff --git a/src/main/java/org/z3950/zing/cql/Utils.java b/src/main/java/org/z3950/zing/cql/Utils.java index 6777e46..9224d36 100644 --- a/src/main/java/org/z3950/zing/cql/Utils.java +++ b/src/main/java/org/z3950/zing/cql/Utils.java @@ -22,30 +22,25 @@ static String indent(int level) { // s/&/&/g; // s//>/g; - // This is hideously inefficient, but I just don't see a better - // way using the standard JAVA library. - // static String xq(String str) { - str = replaceString(str, "&", "&"); - str = replaceString(str, "<", "<"); - str = replaceString(str, ">", ">"); - return str; - } - - // I can't _believe_ I have to write this by hand in 2002 ... - static String replaceString(String str, String from, String to) { - StringBuffer sb = new StringBuffer(); - int ix; // index of next `from' - int offset = 0; // index of previous `from' + length(from) - - while ((ix = str.indexOf(from, offset)) != -1) { - sb.append(str.substring(offset, ix)); - sb.append(to); - offset = ix + from.length(); - } - - // End of string: append last bit and we're done - sb.append(str.substring(offset)); + StringBuilder sb = new StringBuilder(); + for(int i = 0; i': + sb.append(">"); + break; + case '&': + sb.append("&"); + break; + default: + sb.append(c); + } + } return sb.toString(); } + } From 7cff92fa0b727aa844456f130744ec2fe263ba48 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 15:09:07 +0200 Subject: [PATCH 056/147] Import statics directly, bump version --- VERSION | 2 +- .../org/z3950/zing/cql/CQLBooleanNode.java | 2 ++ src/main/java/org/z3950/zing/cql/CQLNode.java | 14 ++------------ .../java/org/z3950/zing/cql/CQLTermNode.java | 2 ++ src/main/java/org/z3950/zing/cql/Modifier.java | 18 ++++++++++-------- .../java/org/z3950/zing/cql/ModifierSet.java | 14 ++++++++------ 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/VERSION b/VERSION index d3bdbdf..6259340 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.7 +1.8 diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index 465b725..19f96c7 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -4,6 +4,8 @@ import java.util.List; import java.util.Properties; +import static org.z3950.zing.cql.Utils.*; + /** * Represents a boolean node in a CQL parse-tree. diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index 34add8e..88b50ca 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -6,6 +6,8 @@ import java.util.Map; import java.util.Properties; +import static org.z3950.zing.cql.Utils.*; + /** * Represents a node in a CQL parse-tree. @@ -112,18 +114,6 @@ protected static String renderSortKeys(int level, abstract public String toPQF(Properties config) throws PQFTranslationException; - /** - * Returns a String of spaces for indenting to the specified level. - */ - protected static String indent(int level) { return Utils.indent(level); } - - /** - * Returns the argument String quoted for XML. - * For example, each occurrence of < is translated to - * &lt;. - */ - protected static String xq(String str) { return Utils.xq(str); } - /** * Renders a parser-tree into a BER-endoded packet representing an * equivalent Z39.50 Type-1 query. If you don't know what that diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index 5966700..cdb62f7 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.Properties; +import static org.z3950.zing.cql.Utils.*; + /** * Represents a terminal node in a CQL parse-tree. diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index 9057dee..d85c8a1 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -2,6 +2,8 @@ package org.z3950.zing.cql; +import static org.z3950.zing.cql.Utils.*; + /** * Represents a single modifier, consisting of three elements: a type, * a comparision and a value. For example, "distance", "<", "3". The @@ -61,18 +63,18 @@ public String getValue() { public String toXCQL(int level, String relationElement) { StringBuilder buf = new StringBuilder(); - buf.append(Utils.indent(level)).append("\n"). - append(Utils.indent(level + 1)).append(""). - append(Utils.xq(type)).append("\n"); + buf.append(indent(level)).append("\n"). + append(indent(level + 1)).append(""). + append(xq(type)).append("\n"); if (value != null) { - buf.append(Utils.indent(level + 1)).append("<"). + buf.append(indent(level + 1)).append("<"). append(relationElement).append(">"). - append(Utils.xq(comparison)).append("\n"). - append(Utils.indent(level + 1)).append(""). - append(Utils.xq(value)).append("\n"); + append(indent(level + 1)).append(""). + append(xq(value)).append("\n"); } - buf.append(Utils.indent(level)).append("\n"); + buf.append(indent(level)).append("\n"); return buf.toString(); } diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index ce5915c..213f199 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.List; +import static org.z3950.zing.cql.Utils.*; + /** * Represents a base String and a set of Modifiers. *

@@ -88,18 +90,18 @@ public String sortKeyToXCQL(int level) { private String underlyingToXCQL(int level, String topLevelElement, String valueElement) { StringBuilder buf = new StringBuilder(); - buf.append(Utils.indent(level)).append("<").append(topLevelElement). - append(">\n").append(Utils.indent(level + 1)).append("<"). - append(valueElement).append(">").append(Utils.xq(base)).append("\n").append(indent(level + 1)).append("<"). + append(valueElement).append(">").append(xq(base)).append("\n"); if (modifiers.size() > 0) { - buf.append(Utils.indent(level + 1)).append("\n"); + buf.append(indent(level + 1)).append("\n"); for (int i = 0; i < modifiers.size(); i++) { buf.append(modifiers.get(i).toXCQL(level+2, "comparison")); } - buf.append(Utils.indent(level + 1)).append("\n"); + buf.append(indent(level + 1)).append("\n"); } - buf.append(Utils.indent(level)).append("\n"); return buf.toString(); } From 00b61385371994aaf79ad06561e0d775754567ad Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 15:16:53 +0200 Subject: [PATCH 057/147] Depend on jar --- test/random/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/random/Makefile b/test/random/Makefile index e64135d..d8f6a80 100644 --- a/test/random/Makefile +++ b/test/random/Makefile @@ -1,10 +1,10 @@ # $Id: Makefile,v 1.2 2007-06-07 16:16:15 mike Exp $ -../../target/cql-java-1.7.jar: - cd ../../ && mvn compile +all: ../../target/cql-java-1.8.jar + PATH=$(PATH):../../bin CLASSPATH=../../target/cql-java-1.8.jar ./mkrandom 100 -all: ../../target/cql-java-1.7.jar - PATH=$(PATH):../../bin CLASSPATH=../../target/cql-java-1.7.jar ./mkrandom 100 +../../target/cql-java-1.8.jar: + cd ../../ && mvn package clean: @echo "Nothing to do to 'make clean'" From 64ca1306b4e0d55a8b15b8da982bc1d37bc8b63c Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 16:51:07 +0200 Subject: [PATCH 058/147] Rewrite XML serialization avoiding string concats --- .../org/z3950/zing/cql/CQLBooleanNode.java | 29 +++++----- src/main/java/org/z3950/zing/cql/CQLNode.java | 45 ++++++++-------- .../java/org/z3950/zing/cql/CQLParser.java | 2 +- .../org/z3950/zing/cql/CQLPrefixNode.java | 4 +- .../java/org/z3950/zing/cql/CQLRelation.java | 5 +- .../java/org/z3950/zing/cql/CQLSortNode.java | 4 +- .../java/org/z3950/zing/cql/CQLTermNode.java | 19 +++---- .../java/org/z3950/zing/cql/Modifier.java | 25 ++++----- .../java/org/z3950/zing/cql/ModifierSet.java | 33 ++++++------ src/main/java/org/z3950/zing/cql/Utils.java | 46 ---------------- .../java/org/z3950/zing/cql/XCQLBuilder.java | 54 +++++++++++++++++++ 11 files changed, 132 insertions(+), 134 deletions(-) delete mode 100644 src/main/java/org/z3950/zing/cql/Utils.java create mode 100644 src/main/java/org/z3950/zing/cql/XCQLBuilder.java diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index 19f96c7..d5a81e8 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -4,9 +4,6 @@ import java.util.List; import java.util.Properties; -import static org.z3950.zing.cql.Utils.*; - - /** * Represents a boolean node in a CQL parse-tree. * @@ -47,19 +44,19 @@ protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms) { } @Override - public String toXCQL(int level, List prefixes, - List sortkeys) { - return (indent(level) + "\n" + - renderPrefixes(level+1, prefixes) + - ms.toXCQL(level+1, "boolean") + - indent(level+1) + "\n" + - left.toXCQL(level+2) + - indent(level+1) + "\n" + - indent(level+1) + "\n" + - right.toXCQL(level+2) + - indent(level+1) + "\n" + - renderSortKeys(level+1, sortkeys) + - indent(level) + "\n"); + void toXCQLInternal(XCQLBuilder b, int level, + List prefixes, List sortkeys) { + b.indent(level).append("\n"); + renderPrefixes(b, level + 1, prefixes); + ms.toXCQLInternal(b, level + 1, "boolean"); + b.indent(level + 1).append("\n"); + left.toXCQLInternal(b, level + 2); + b.indent(level + 1).append("\n"); + b.indent(level + 1).append("\n"); + right.toXCQLInternal(b, level + 2); + b.indent(level + 1).append("\n"); + renderSortKeys(b, level + 1, sortkeys); + b.indent(level).append("\n"); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index 88b50ca..afaa892 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -6,7 +6,6 @@ import java.util.Map; import java.util.Properties; -import static org.z3950.zing.cql.Utils.*; /** @@ -41,43 +40,47 @@ public String getResultSetName() { * A String containing an XCQL document equivalent to the * parse-tree whose root is this node. */ - public String toXCQL(int level) { - return toXCQL(level, null); + public String toXCQL() { + StringBuilder sb = new StringBuilder(); + toXCQLInternal(new XCQLBuilder(sb), 0); + return sb.toString(); } - public String toXCQL(int level, List prefixes) { - return toXCQL(level, prefixes, null); + void toXCQLInternal(XCQLBuilder b, int level) { + toXCQLInternal(b, level, null, null); } - abstract public String toXCQL(int level, List prefixes, - List sortkeys); + abstract void toXCQLInternal(XCQLBuilder b, int level, + List prefixes, List sortkeys); - protected static String renderPrefixes(int level, List prefixes) { + static void renderPrefixes(XCQLBuilder b, + int level, List prefixes) { if (prefixes == null || prefixes.size() == 0) - return ""; - String res = indent(level) + "\n"; + return; + b.indent(level).append("\n"); for (int i = 0; i < prefixes.size(); i++) { CQLPrefix p = prefixes.get(i); - res += indent(level+1) + "\n"; + b.indent(level+1).append("\n"); if (p.name != null) - res += indent(level+2) + "" + p.name + "\n"; - res += indent(level+2) + - "" + p.identifier + "\n"; - res += indent(level+1) + "\n"; + b.indent(level + 2).append(""). + append(p.name).append("\n"); + b.indent(level + 2).append("").append(p.identifier). + append("\n"); + b.indent(level+1).append("\n"); } - return res + indent(level) + "\n"; + b.indent(level).append("\n"); } - protected static String renderSortKeys(int level, + static void renderSortKeys(XCQLBuilder b, int level, List sortkeys) { if (sortkeys == null || sortkeys.size() == 0) - return ""; - String res = indent(level) + "\n"; + return; + b.indent(level).append("\n"); for (int i = 0; i < sortkeys.size(); i++) { ModifierSet key = sortkeys.get(i); - res += key.sortKeyToXCQL(level+1); + b.append(key.sortKeyToXCQL(level+1)); } - return res + indent(level) + "\n"; + b.indent(level).append("\n"); } /** diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 7ed9f59..be365de 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -443,7 +443,7 @@ public static void main (String[] args) { f.close(); System.out.println(root.toPQF(config)); } else { - System.out.print(root.toXCQL(0)); + System.out.print(root.toXCQL()); } } catch (IOException ex) { System.err.println("Can't render query: " + ex.getMessage()); diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index c793d2f..eed3d34 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -42,13 +42,13 @@ public CQLPrefixNode(String name, String identifier, CQLNode subtree) { } @Override - public String toXCQL(int level, List prefixes, + void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { List tmp = (prefixes == null ? new ArrayList() : new ArrayList(prefixes)); tmp.add(prefix); - return subtree.toXCQL(level, tmp, sortkeys); + subtree.toXCQLInternal(b, level, tmp, sortkeys); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 44a55e6..351d8d4 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -44,12 +44,11 @@ public List getModifiers() { } @Override - public String toXCQL(int level, List prefixes, + void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { if (sortkeys != null) throw new Error("CQLRelation.toXCQL() called with sortkeys"); - - return ms.toXCQL(level, "relation"); + ms.toXCQLInternal(b, level, "relation"); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 55e69d5..68a4ea9 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -43,11 +43,11 @@ public List getSortIndexes() { } @Override - public String toXCQL(int level, List prefixes, + void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { if (sortkeys != null) throw new Error("CQLSortNode.toXCQL() called with sortkeys"); - return subtree.toXCQL(level, prefixes, keys); + subtree.toXCQLInternal(b, level, prefixes, keys); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index cdb62f7..dfd0e63 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -5,9 +5,6 @@ import java.util.List; import java.util.Properties; -import static org.z3950.zing.cql.Utils.*; - - /** * Represents a terminal node in a CQL parse-tree. * A term node consists of the term String itself, together with, @@ -55,15 +52,15 @@ public String getResultSetName() { } @Override - public String toXCQL(int level, List prefixes, + void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { - return (indent(level) + "\n" + - renderPrefixes(level+1, prefixes) + - indent(level+1) + "" + xq(index) + "\n" + - relation.toXCQL(level+1) + - indent(level+1) + "" + xq(term) + "\n" + - renderSortKeys(level+1, sortkeys) + - indent(level) + "\n"); + b.indent(level).append("\n"); + renderPrefixes(b, level + 1, prefixes); + b.indent(level + 1).append("").xq(index).append("\n"); + relation.toXCQLInternal(b, level + 1); + b.indent(level + 1).append("").xq(term).append("\n"); + renderSortKeys(b, level + 1, sortkeys); + b.indent(level).append("\n"); } @Override diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index d85c8a1..8c5cef7 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -2,8 +2,6 @@ package org.z3950.zing.cql; -import static org.z3950.zing.cql.Utils.*; - /** * Represents a single modifier, consisting of three elements: a type, * a comparision and a value. For example, "distance", "<", "3". The @@ -60,22 +58,17 @@ public String getValue() { return value; } - public String toXCQL(int level, String relationElement) { - StringBuilder buf = new StringBuilder(); - - buf.append(indent(level)).append("\n"). - append(indent(level + 1)).append(""). - append(xq(type)).append("\n"); + protected XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, String relationElement) { + b.indent(level).append("\n"); + b.indent(level + 1).append(""); + b.xq(type).append("\n"); if (value != null) { - buf.append(indent(level + 1)).append("<"). - append(relationElement).append(">"). - append(xq(comparison)).append("\n"). - append(indent(level + 1)).append(""). - append(xq(value)).append("\n"); + b.indent(level + 1).append("<").append(relationElement).append(">"); + b.xq(comparison).append("\n"); + b.indent(level + 1).append(""); + b.xq(value).append("\n"); } - buf.append(indent(level)).append("\n"); - return buf.toString(); + return b.indent(level).append("\n"); } public String toCQL() { diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index 213f199..c04bb88 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -4,8 +4,6 @@ import java.util.ArrayList; import java.util.List; -import static org.z3950.zing.cql.Utils.*; - /** * Represents a base String and a set of Modifiers. *

@@ -80,30 +78,33 @@ public List getModifiers() { } public String toXCQL(int level, String topLevelElement) { - return underlyingToXCQL(level, topLevelElement, "value"); + return "";//underlyingToXCQL(level, topLevelElement, "value"); } public String sortKeyToXCQL(int level) { - return underlyingToXCQL(level, "key", "index"); + return "";//underlyingToXCQL(level, "key", "index"); + } + + protected XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, + String topLevelElement) { + return toXCQLInternal(b, level, topLevelElement, "value"); } - private String underlyingToXCQL(int level, String topLevelElement, - String valueElement) { - StringBuilder buf = new StringBuilder(); - buf.append(indent(level)).append("<").append(topLevelElement). - append(">\n").append(indent(level + 1)).append("<"). - append(valueElement).append(">").append(xq(base)).append("\n").indent(level + 1).append("<"). + append(valueElement).append(">").xq(base).append("\n"); if (modifiers.size() > 0) { - buf.append(indent(level + 1)).append("\n"); + b.indent(level + 1).append("\n"); for (int i = 0; i < modifiers.size(); i++) { - buf.append(modifiers.get(i).toXCQL(level+2, "comparison")); + modifiers.get(i).toXCQLInternal(b, level+2, "comparison"); } - buf.append(indent(level + 1)).append("\n"); + b.indent(level + 1).append("\n"); } - buf.append(indent(level)).append("\n"); - return buf.toString(); + b.indent(level).append("\n"); + return b; } public String toCQL() { diff --git a/src/main/java/org/z3950/zing/cql/Utils.java b/src/main/java/org/z3950/zing/cql/Utils.java deleted file mode 100644 index 9224d36..0000000 --- a/src/main/java/org/z3950/zing/cql/Utils.java +++ /dev/null @@ -1,46 +0,0 @@ -// $Id: Utils.java,v 1.2 2002-11-06 00:05:58 mike Exp $ - -package org.z3950.zing.cql; - - -/** - * Utility functions for the org.z3950.zing.cql package. - * Not intended for use outside this package. - * - * @version $Id: Utils.java,v 1.2 2002-11-06 00:05:58 mike Exp $ - */ -class Utils { - static String indent(int level) { - String x = ""; - while (level-- > 0) { - x += " "; - } - return x; - } - - // XML Quote -- - // s/&/&/g; - // s//>/g; - static String xq(String str) { - StringBuilder sb = new StringBuilder(); - for(int i = 0; i': - sb.append(">"); - break; - case '&': - sb.append("&"); - break; - default: - sb.append(c); - } - } - return sb.toString(); - } - -} diff --git a/src/main/java/org/z3950/zing/cql/XCQLBuilder.java b/src/main/java/org/z3950/zing/cql/XCQLBuilder.java new file mode 100644 index 0000000..d59ce89 --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/XCQLBuilder.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1995-2011, Index Data + * All rights reserved. + * See the file LICENSE for details. + */ +package org.z3950.zing.cql; + +/** + * + * @author jakub + */ +class XCQLBuilder { + private StringBuilder sb; + + XCQLBuilder(StringBuilder sb) { + this.sb = sb; + } + + XCQLBuilder indent(int level) { + while (level-- > 0) { + sb.append(" "); + } + return this; + } + + XCQLBuilder xq(String str) { + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + switch (c) { + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + case '&': + sb.append("&"); + break; + default: + sb.append(c); + } + } + return this; + } + + XCQLBuilder append(String str) { + sb.append(str); + return this; + } + + public String toString() { + return sb.toString(); + } +} \ No newline at end of file From b9f0ad15f2fadc4cb9a0f035d7efdd3c94a75272 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 17:26:28 +0200 Subject: [PATCH 059/147] Move some code around, simplify --- .../java/org/z3950/zing/cql/CQLBooleanNode.java | 2 +- src/main/java/org/z3950/zing/cql/CQLNode.java | 8 ++++---- .../java/org/z3950/zing/cql/CQLRelation.java | 2 +- src/main/java/org/z3950/zing/cql/Modifier.java | 4 ++-- .../java/org/z3950/zing/cql/ModifierSet.java | 16 +--------------- 5 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index d5a81e8..902e6b5 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -48,7 +48,7 @@ void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { b.indent(level).append("\n"); renderPrefixes(b, level + 1, prefixes); - ms.toXCQLInternal(b, level + 1, "boolean"); + ms.toXCQLInternal(b, level + 1, "boolean", "value"); b.indent(level + 1).append("\n"); left.toXCQLInternal(b, level + 2); b.indent(level + 1).append("\n"); diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index afaa892..4ba6649 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -64,9 +64,9 @@ static void renderPrefixes(XCQLBuilder b, if (p.name != null) b.indent(level + 2).append(""). append(p.name).append("\n"); - b.indent(level + 2).append("").append(p.identifier). - append("\n"); - b.indent(level+1).append("\n"); + b.indent(level + 2).append(""). + append(p.identifier).append("\n"); + b.indent(level+1).append("\n"); } b.indent(level).append("\n"); } @@ -78,7 +78,7 @@ static void renderSortKeys(XCQLBuilder b, int level, b.indent(level).append("\n"); for (int i = 0; i < sortkeys.size(); i++) { ModifierSet key = sortkeys.get(i); - b.append(key.sortKeyToXCQL(level+1)); + key.toXCQLInternal(b, level+1, "key", "index"); } b.indent(level).append("\n"); } diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 351d8d4..4e9fd27 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -48,7 +48,7 @@ void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { if (sortkeys != null) throw new Error("CQLRelation.toXCQL() called with sortkeys"); - ms.toXCQLInternal(b, level, "relation"); + ms.toXCQLInternal(b, level, "relation", "value"); } @Override diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index 8c5cef7..91d3a17 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -58,7 +58,7 @@ public String getValue() { return value; } - protected XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, String relationElement) { + void toXCQLInternal(XCQLBuilder b, int level, String relationElement) { b.indent(level).append("\n"); b.indent(level + 1).append(""); b.xq(type).append("\n"); @@ -68,7 +68,7 @@ protected XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, String relationEl b.indent(level + 1).append(""); b.xq(value).append("\n"); } - return b.indent(level).append("\n"); + b.indent(level).append("\n"); } public String toCQL() { diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index c04bb88..7eb965f 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -77,20 +77,7 @@ public List getModifiers() { return modifiers; } - public String toXCQL(int level, String topLevelElement) { - return "";//underlyingToXCQL(level, topLevelElement, "value"); - } - - public String sortKeyToXCQL(int level) { - return "";//underlyingToXCQL(level, "key", "index"); - } - - protected XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, - String topLevelElement) { - return toXCQLInternal(b, level, topLevelElement, "value"); - } - - private XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, + void toXCQLInternal(XCQLBuilder b, int level, String topLevelElement, String valueElement) { b.indent(level).append("<").append(topLevelElement). append(">\n").indent(level + 1).append("<"). @@ -104,7 +91,6 @@ private XCQLBuilder toXCQLInternal(XCQLBuilder b, int level, b.indent(level + 1).append("\n"); } b.indent(level).append("\n"); - return b; } public String toCQL() { From 2201900abb957fe030809d9b6a79e8815a094edf Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 18:02:22 +0200 Subject: [PATCH 060/147] Rename --- src/main/java/org/z3950/zing/cql/CQLBooleanNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index 902e6b5..f30dd78 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -16,7 +16,7 @@ public abstract class CQLBooleanNode extends CQLNode { /** * The root of a parse-tree representing the left-hand side. */ - public CQLNode getLeft() { + public CQLNode getLeftOperand() { return left; } @@ -25,7 +25,7 @@ public CQLNode getLeft() { /** * The root of a parse-tree representing the right-hand side. */ - public CQLNode getRight() { + public CQLNode getRightOperand() { return right; } From 1b9781178153160fe7159cbd92c8491516600c08 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 18:03:25 +0200 Subject: [PATCH 061/147] Version 1.8 --- Changes | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index e5159f6..c182200 100644 --- a/Changes +++ b/Changes @@ -6,10 +6,12 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. -1.8 IN PROGRESS - - API changes: more information hiding, introduce getters - - make some contants read-only - +1.8 Fri Jul 22 18:02:41 CEST 2011 + - API changes: removed direct access to internal state and introduced + getters, removed usages of obsolete collections (Vector, Hashtable), + simplified method signatues (toXCQL), modified constants to be + read-only + - implemented faster XCQL serialization, using pure StringBuilder 1.7 Tue Jul 27 17:35:25 BST 2010 - Patch from Ralph LeVan to recognise From 5b8519ea50605aa4fb128e0330176b8d1cbea64a Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 22 Jul 2011 20:58:11 +0200 Subject: [PATCH 062/147] Move JavaDocs around --- pom.xml | 11 +++++++++-- src/main/java/org/z3950/zing/cql/CQLBooleanNode.java | 1 + src/main/java/org/z3950/zing/cql/CQLNode.java | 6 ------ src/main/java/org/z3950/zing/cql/CQLPrefix.java | 10 ++++++---- src/main/java/org/z3950/zing/cql/CQLPrefixNode.java | 11 ++++++----- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 53a1e90..8c518c6 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,14 @@ 1.8 cql-java http://maven.apache.org - + + + + org.apache.maven.wagon + wagon-ssh + 1.0-beta-6 + + org.apache.maven.plugins @@ -33,7 +40,7 @@ false id-maven-repo Index Data Maven Repository - scp://maven.indexdata.com/var/www/maven/repository + scp://maven.indexdata.com:222/var/www/maven/repository diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index f30dd78..06a9bc9 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -30,6 +30,7 @@ public CQLNode getRightOperand() { } ModifierSet ms; + /** * The set of modifiers that are applied to this boolean. */ diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index 4ba6649..fa263ae 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -14,7 +14,6 @@ * @version $Id: CQLNode.java,v 1.26 2007-07-03 13:36:03 mike Exp $ */ public abstract class CQLNode { - CQLNode() {} // prevent javadoc from documenting this /** * Returns the name of the result-set to which this query is a @@ -31,11 +30,6 @@ public String getResultSetName() { /** * Translates a parse-tree into an XCQL document. *

- * @param level - * The number of levels to indent the top element of the XCQL - * document. This will typically be 0 when invoked by an - * application; it takes higher values when this method is - * invoked recursively for nodes further down the tree. * @return * A String containing an XCQL document equivalent to the * parse-tree whose root is this node. diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefix.java b/src/main/java/org/z3950/zing/cql/CQLPrefix.java index fac6503..cb3043f 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefix.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefix.java @@ -8,24 +8,26 @@ * @version $Id: CQLPrefix.java,v 1.5 2007-06-27 22:39:55 mike Exp $ */ public class CQLPrefix { + + String name; + /** * The short name of the prefix mapping. That is, the prefix * itself, such as dc, as it might be used in an index * like dc.title. */ - String name; - public String getName() { return name; } + + String identifier; + /** * The full identifier name of the prefix mapping. That is, * typically, a URI permanently allocated to a specific index * set, such as http://zthes.z3950.org/cql/1.0. */ - String identifier; - public String getIdentifier() { return identifier; } diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index eed3d34..656f6e6 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -12,21 +12,22 @@ * @version $Id: CQLPrefixNode.java,v 1.10 2007-07-03 16:40:11 mike Exp $ */ public class CQLPrefixNode extends CQLNode { + + private CQLPrefix prefix; + /** * The prefix definition that governs the subtree. */ - private CQLPrefix prefix; - public CQLPrefix getPrefix() { return prefix; } + private CQLNode subtree; + /** * The root of a parse-tree representing the part of the query * that is governed by this prefix definition. - */ - private CQLNode subtree; - + */ public CQLNode getSubtree() { return subtree; } From ba96cf25453ec7f3f770a4dcad3bf145354b83e8 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Thu, 19 Jan 2012 13:01:14 +0100 Subject: [PATCH 063/147] Add ability to parse from char streams --- .../java/org/z3950/zing/cql/CQLLexer.java | 10 ++++++-- .../java/org/z3950/zing/cql/CQLParser.java | 24 ++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 7bbf115..69211c8 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -1,6 +1,8 @@ // $Id: CQLLexer.java,v 1.14 2007-07-03 13:30:42 mike Exp $ package org.z3950.zing.cql; +import java.io.InputStream; +import java.io.Reader; import java.io.StreamTokenizer; import java.io.StringReader; @@ -56,8 +58,12 @@ private class Keyword { // Controls debugging output private static boolean DEBUG; - CQLLexer(String cql, boolean lexdebug) { - super(new StringReader(cql)); + public CQLLexer(String cql, boolean lexdebug) { + this(new StringReader(cql), DEBUG); + } + + CQLLexer(Reader cql, boolean lexdebug) { + super(cql); wordChars('!', '?'); // ASCII-dependency! wordChars('[', '`'); // ASCII-dependency! quoteChar('"'); diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index be365de..9970aa7 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -6,6 +6,8 @@ import java.io.InputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.Reader; +import java.io.StringReader; import java.util.ArrayList; import java.util.List; @@ -55,6 +57,26 @@ private static void debug(String str) { if (DEBUG) System.err.println("PARSEDEBUG: " + str); } + + /** + * Compiles a CQL query. + *

+ * The resulting parse tree may be further processed by hand (see + * the individual node-types' documentation for details on the + * data structure) or, more often, simply rendered out in the + * desired form using one of the back-ends. toCQL() + * returns a decompiled CQL query equivalent to the one that was + * compiled in the first place; toXCQL() returns an + * XML snippet representing the query; and toPQF() + * returns the query rendered in Index Data's Prefix Query + * Format. + * + * @param cql The query + * @return A CQLNode object which is the root of a parse + * tree representing the query. */ + public CQLNode parse(String cql) throws CQLParseException, IOException { + return parse(new StringReader(cql)); + } /** * Compiles a CQL query. @@ -72,7 +94,7 @@ private static void debug(String str) { * @param cql The query * @return A CQLNode object which is the root of a parse * tree representing the query. */ - public CQLNode parse(String cql) + public CQLNode parse(Reader cql) throws CQLParseException, IOException { lexer = new CQLLexer(cql, LEXDEBUG); From 5a9c5ccd6e4249a2f00cd3a4be157a20de29ae82 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Thu, 19 Jan 2012 13:05:10 +0100 Subject: [PATCH 064/147] Should not be exposed --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 69211c8..d1e2cc9 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -58,7 +58,7 @@ private class Keyword { // Controls debugging output private static boolean DEBUG; - public CQLLexer(String cql, boolean lexdebug) { + CQLLexer(String cql, boolean lexdebug) { this(new StringReader(cql), DEBUG); } From 9604e077dabfb5d75856a293b74394ada821356b Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Thu, 19 Jan 2012 13:06:12 +0100 Subject: [PATCH 065/147] Argh.. fix the debug flag --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index d1e2cc9..24dd241 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -59,7 +59,7 @@ private class Keyword { private static boolean DEBUG; CQLLexer(String cql, boolean lexdebug) { - this(new StringReader(cql), DEBUG); + this(new StringReader(cql), lexdebug); } CQLLexer(Reader cql, boolean lexdebug) { From 795d3baab798fb65b209ac4ceeee021baf2fe489 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Thu, 9 Feb 2012 16:42:27 +0100 Subject: [PATCH 066/147] Version 1.9 under development --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8c518c6..e0ce43e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.z3950.zing cql-java jar - 1.8 + 1.9-SNAPSHOT cql-java http://maven.apache.org From b44d16a11b3f7ab297743bfff3d14a167a647503 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Thu, 9 Feb 2012 16:42:58 +0100 Subject: [PATCH 067/147] Relation 'exact' is illegal in CQL 1.2 --- src/main/java/org/z3950/zing/cql/CQLParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 9970aa7..795b2f1 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -268,7 +268,7 @@ private boolean isRelation() { lexer.sval.equals("all") || lexer.sval.equals("within") || lexer.sval.equals("encloses") || - lexer.sval.equals("exact") || + (lexer.sval.equals("exact") && compat != V1POINT2) || (lexer.sval.equals("scr") && compat != V1POINT2) || (lexer.sval.equals("adj") && compat == V1POINT2))) return true; From 17a5ae63a282405db3d75a1ad22e9edd74cf08b7 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 14 Mar 2012 01:10:59 +0100 Subject: [PATCH 068/147] Reformat only --- pom.xml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index e0ce43e..c716438 100644 --- a/pom.xml +++ b/pom.xml @@ -15,19 +15,19 @@ 1.0-beta-6 - - - org.apache.maven.plugins - maven-compiler-plugin - 2.0.2 - - 1.6 - 1.6 - - - - - + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + + junit junit From 11a9f24579b91c007f7d73d6f85068357582a0ed Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 14 Mar 2012 01:11:45 +0100 Subject: [PATCH 069/147] Add release plugin --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index c716438..7d85ab5 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,17 @@ 1.6 + + org.apache.maven.plugins + maven-release-plugin + 2.2.1 + + clean install + https://svn.apache.org/repos/asf/maven/components/releases + production + true + + From 58d69179cc83a235722ff40d26308d3cd5cdd0a6 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 14 Mar 2012 01:14:20 +0100 Subject: [PATCH 070/147] Add scm connection --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 7d85ab5..f803ff8 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,10 @@ 1.9-SNAPSHOT cql-java http://maven.apache.org + + scm:git:ssh://git.indexdata.com:222/home/git/private/cql-java + http://gitid.indexdata.com/?p=cql-java.git + From 8813065049df380b81da5f09b692b2c72a36330c Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 14 Mar 2012 01:14:58 +0100 Subject: [PATCH 071/147] [maven-release-plugin] prepare release v1.9 --- pom.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f803ff8..0668e8a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,10 +1,9 @@ - + 4.0.0 org.z3950.zing cql-java jar - 1.9-SNAPSHOT + 1.9 cql-java http://maven.apache.org From 4e874df732f94bfee7f0e737b74143b191cde33f Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 14 Mar 2012 01:15:00 +0100 Subject: [PATCH 072/147] [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0668e8a..a11164a 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.9 + 1.10-SNAPSHOT cql-java http://maven.apache.org From 07cee0c3fb9b8785583343df2317d2946408e2cc Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 14 Mar 2012 01:16:14 +0100 Subject: [PATCH 073/147] Source is encoded in UTF-8 --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index a11164a..1c06b86 100644 --- a/pom.xml +++ b/pom.xml @@ -63,5 +63,8 @@ http://maven.indexdata.com + + UTF-8 + From 01f75157030636072792a125db1eb81b9fbc139b Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 14 Mar 2012 09:43:41 +0100 Subject: [PATCH 074/147] Make the relase plugin work locally --- pom.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 1c06b86..7129982 100644 --- a/pom.xml +++ b/pom.xml @@ -31,12 +31,13 @@ org.apache.maven.plugins maven-release-plugin - 2.2.1 + 2.2.2 - clean install - https://svn.apache.org/repos/asf/maven/components/releases + clean verify production - true + v@{project.version} + false + true From db60fd485297a360e886ad1d8f76ef16ea94c42e Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 16 Mar 2012 16:57:07 +0100 Subject: [PATCH 075/147] Record position in parse exception --- .../org/z3950/zing/cql/CQLParseException.java | 12 +- .../java/org/z3950/zing/cql/CQLParser.java | 19 ++-- .../z3950/zing/cql/PositionAwareReader.java | 107 ++++++++++++++++++ 3 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/z3950/zing/cql/PositionAwareReader.java diff --git a/src/main/java/org/z3950/zing/cql/CQLParseException.java b/src/main/java/org/z3950/zing/cql/CQLParseException.java index ee237f5..ceb97de 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParseException.java +++ b/src/main/java/org/z3950/zing/cql/CQLParseException.java @@ -9,14 +9,24 @@ * @version $Id: CQLParseException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ */ public class CQLParseException extends Exception { + private int pos; /** * Creates a new CQLParseException. * @param s * An error message describing the problem with the query, * usually a syntax error of some kind. */ - public CQLParseException(String s) { + public CQLParseException(String s, int pos) { super(s); + this.pos = pos; + } + + /** + * Character position of the parsing error. + * @return + */ + public int getPosition() { + return pos; } } diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 795b2f1..62a51b6 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -21,6 +21,7 @@ */ public class CQLParser { private CQLLexer lexer; + private PositionAwareReader par; //active reader with position private int compat; // When false, implement CQL 1.2 public static final int V1POINT1 = 12368; public static final int V1POINT2 = 12369; @@ -96,14 +97,16 @@ public CQLNode parse(String cql) throws CQLParseException, IOException { * tree representing the query. */ public CQLNode parse(Reader cql) throws CQLParseException, IOException { - lexer = new CQLLexer(cql, LEXDEBUG); + par = new PositionAwareReader(cql); + lexer = new CQLLexer(par, LEXDEBUG); lexer.nextToken(); debug("about to parseQuery()"); CQLNode root = parseTopLevelPrefixes("cql.serverChoice", new CQLRelation(compat == V1POINT2 ? "=" : "scr")); if (lexer.ttype != CQLLexer.TT_EOF) - throw new CQLParseException("junk after end: " + lexer.render()); + throw new CQLParseException("junk after end: " + lexer.render(), + par.getPosition()); return root; } @@ -130,7 +133,7 @@ private CQLNode parseTopLevelPrefixes(String index, CQLRelation relation) } if (sortnode.keys.size() == 0) { - throw new CQLParseException("no sort keys"); + throw new CQLParseException("no sort keys", par.getPosition()); } node = sortnode; @@ -162,7 +165,7 @@ private CQLNode parseQuery(String index, CQLRelation relation) new CQLProxNode(term, term2, ms)); } else { throw new CQLParseException("expected boolean, got " + - lexer.render()); + lexer.render(), par.getPosition()); } } @@ -179,7 +182,8 @@ private ModifierSet gatherModifiers(String base) match('/'); if (lexer.ttype != CQLLexer.TT_WORD) throw new CQLParseException("expected modifier, " - + "got " + lexer.render()); + + "got " + lexer.render(), + par.getPosition()); String type = lexer.sval.toLowerCase(); match(lexer.ttype); if (!isSymbolicRelation()) { @@ -294,7 +298,8 @@ private void match(int token) if (lexer.ttype != token) throw new CQLParseException("expected " + lexer.render(token, true) + - ", " + "got " + lexer.render()); + ", " + "got " + lexer.render(), + par.getPosition()); int tmp = lexer.nextToken(); debug("match() got token=" + lexer.ttype + ", " + "nval=" + lexer.nval + ", sval='" + lexer.sval + "'" + @@ -325,7 +330,7 @@ private String matchSymbol(String expected) } throw new CQLParseException("expected " + expected + ", " + - "got " + lexer.render()); + "got " + lexer.render(), par.getPosition()); } diff --git a/src/main/java/org/z3950/zing/cql/PositionAwareReader.java b/src/main/java/org/z3950/zing/cql/PositionAwareReader.java new file mode 100644 index 0000000..b3294c0 --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/PositionAwareReader.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 1995-2012, Index Data + * All rights reserved. + * See the file LICENSE for details. + */ +package org.z3950.zing.cql; + +import java.io.IOException; +import java.io.Reader; +import java.nio.CharBuffer; + +/** + * Reader proxy to count how many characters has been read so far. + * @author jakub + */ +public class PositionAwareReader extends Reader { + protected Reader reader; + protected int pos = -1; + + public PositionAwareReader(Reader reader) { + this.reader = reader; + } + + /* + * Position of the last read character or -1 if either reading from an empty + * stream or no 'read' has been invoked for this reader. + */ + public int getPosition() { + return pos; + } + + @Override + public void mark(int readAheadLimit) throws IOException { + reader.mark(readAheadLimit); + } + + @Override + public boolean markSupported() { + return reader.markSupported(); + } + + @Override + public int read() throws IOException { + int c = reader.read(); + if (c != -1) pos++; + return c; + } + + @Override + public int read(char[] cbuf) throws IOException { + int c = reader.read(cbuf); + if (c != -1) pos+=c; + return c; + } + + @Override + public int read(CharBuffer target) throws IOException { + int c = reader.read(target); + if (c != -1) pos+=c; + return c; + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + int c = reader.read(cbuf, off, len); + if (c != -1) pos+=c; + return c; + } + + @Override + public boolean ready() throws IOException { + return reader.ready(); + } + + @Override + public long skip(long n) throws IOException { + return reader.skip(n); + } + + @Override + public void close() throws IOException { + reader.close(); + } + + @Override + public void reset() throws IOException { + reader.reset(); + } + + //override object methods, to be on the safe-side + + @Override + public boolean equals(Object obj) { + return reader.equals(obj); + } + + @Override + public String toString() { + return reader.toString(); + } + + @Override + public int hashCode() { + return reader.hashCode(); + } + +} From 0a4e696f4ad51362360cd1648fe9290961df0eff Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 19 Mar 2012 10:37:43 +0100 Subject: [PATCH 076/147] Following SCM location change --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7129982..76f3e14 100644 --- a/pom.xml +++ b/pom.xml @@ -7,8 +7,8 @@ cql-java http://maven.apache.org - scm:git:ssh://git.indexdata.com:222/home/git/private/cql-java - http://gitid.indexdata.com/?p=cql-java.git + scm:git:ssh://git.indexdata.com:222/home/git/pub/cql-java + http://git.indexdata.com/?p=cql-java.git From b57b119f02e910a68cbf7d4f0b93b7a5c9f78315 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 19 Mar 2012 10:48:14 +0100 Subject: [PATCH 077/147] Update project meta-data --- pom.xml | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 76f3e14..9fc8415 100644 --- a/pom.xml +++ b/pom.xml @@ -5,11 +5,44 @@ jar 1.10-SNAPSHOT cql-java - http://maven.apache.org + http://www.indexdata.com/cql-java + 2008 + + Index Data + http://www.indexdata.com + + + + Mike Taylor + mike + mike@indexdata.com + Index Data + http://www.indexdata.com/ + + + + + Jakub Skoczen + jakub + jakub@indexdata.dk + Index Data + http://www.indexdata.com/ + + + + scm:git:ssh://git.indexdata.com:222/home/git/pub/cql-java http://git.indexdata.com/?p=cql-java.git + + Bugzilla + http://bugzilla.indexdata.dk/ + + + hudson + http://hudson.indexdata.com/ + From e0df687fdc030fa8dec657c36fa61dfa2c216146 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 19 Mar 2012 10:50:36 +0100 Subject: [PATCH 078/147] [maven-release-plugin] prepare release v1.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9fc8415..8ffad48 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.10-SNAPSHOT + 1.10 cql-java http://www.indexdata.com/cql-java 2008 From b24e5e1099493769f8ed990599d98dae9359bfa0 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 19 Mar 2012 10:50:36 +0100 Subject: [PATCH 079/147] [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8ffad48..1c5d165 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.10 + 1.11-SNAPSHOT cql-java http://www.indexdata.com/cql-java 2008 From b87baddb6921af76237a2b75a282a02d192908f2 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 19 Mar 2012 11:41:26 +0100 Subject: [PATCH 080/147] Publish site/docs to ID website --- pom.xml | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1c5d165..8687876 100644 --- a/pom.xml +++ b/pom.xml @@ -43,12 +43,29 @@ hudson http://hudson.indexdata.com/ + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8.1 + + UTF-8 + + + + org.apache.maven.wagon wagon-ssh - 1.0-beta-6 + 2.2 + + + org.apache.maven.wagon + wagon-ssh-external + 2.2 @@ -90,6 +107,10 @@ Index Data Maven Repository scp://maven.indexdata.com:222/var/www/maven/repository + + id-website + scpexe://www.indexdata.com/var/www/software/cql-java/ + @@ -100,5 +121,40 @@ UTF-8 + + + maven-3 + + + + ${basedir} + + + + + + + org.apache.maven.plugins + maven-site-plugin + 3.0 + + + + + + maven-site-plugin + + + attach-descriptor + + attach-descriptor + + + + + + + + From 3a0f860e544d750bdda5e9290650357577196890 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 19 Mar 2012 12:02:57 +0100 Subject: [PATCH 081/147] Update licence --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 8687876..07fdd9c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,6 +6,13 @@ 1.11-SNAPSHOT cql-java http://www.indexdata.com/cql-java + + + LGPL + http://www.indexdata.com/licences/lgpl + repo + + 2008 Index Data From 2ef8d2fc0e5a32518b1a5750e6f68cdb91e64de2 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 25 Jul 2012 11:06:32 +0200 Subject: [PATCH 082/147] Remove CVS expansions --- Build | 1 - Changes | 1 - Makefile | 1 - README | 1 - archive/chris-hubick/README | 1 - bin/CQLGenerator | 1 - bin/CQLLexer | 1 - bin/CQLParser | 1 - docs/Makefile | 1 - etc/generate.properties | 1 - etc/pqf.properties | 1 - etc/xslt/README | 1 - lib/README | 1 - spec/bnf | 1 - src/main/java/org/z3950/zing/cql/CQLAndNode.java | 2 -- src/main/java/org/z3950/zing/cql/CQLBooleanNode.java | 2 -- src/main/java/org/z3950/zing/cql/CQLGenerator.java | 2 -- src/main/java/org/z3950/zing/cql/CQLLexer.java | 1 - src/main/java/org/z3950/zing/cql/CQLNode.java | 2 -- src/main/java/org/z3950/zing/cql/CQLNotNode.java | 2 -- src/main/java/org/z3950/zing/cql/CQLOrNode.java | 2 -- src/main/java/org/z3950/zing/cql/CQLParseException.java | 2 -- src/main/java/org/z3950/zing/cql/CQLParser.java | 2 -- src/main/java/org/z3950/zing/cql/CQLPrefix.java | 2 -- src/main/java/org/z3950/zing/cql/CQLPrefixNode.java | 2 -- src/main/java/org/z3950/zing/cql/CQLProxNode.java | 2 -- src/main/java/org/z3950/zing/cql/CQLRelation.java | 2 -- src/main/java/org/z3950/zing/cql/CQLSortNode.java | 2 -- src/main/java/org/z3950/zing/cql/CQLTermNode.java | 2 -- src/main/java/org/z3950/zing/cql/Makefile | 1 - src/main/java/org/z3950/zing/cql/MissingParameterException.java | 2 -- src/main/java/org/z3950/zing/cql/Modifier.java | 2 -- src/main/java/org/z3950/zing/cql/ModifierSet.java | 2 -- src/main/java/org/z3950/zing/cql/PQFTranslationException.java | 2 -- src/main/java/org/z3950/zing/cql/UnknownIndexException.java | 2 -- src/main/java/org/z3950/zing/cql/UnknownPositionException.java | 2 -- src/main/java/org/z3950/zing/cql/UnknownRelationException.java | 2 -- .../org/z3950/zing/cql/UnknownRelationModifierException.java | 2 -- test/random/Makefile | 1 - test/random/README | 1 - test/random/mkrandom | 1 - test/regression/Makefile | 1 - test/regression/README | 1 - test/regression/mkanswers | 1 - test/regression/mktests | 1 - test/regression/runcanon | 1 - test/regression/runtests | 1 - test/regression/showtest | 1 - 48 files changed, 70 deletions(-) diff --git a/Build b/Build index 2c2f550..87facee 100755 --- a/Build +++ b/Build @@ -1,6 +1,5 @@ #!/bin/sh -# $Id: Build,v 1.2 2002-11-20 17:20:11 mike Exp $ : ${MAKE=make} for dir in src/main/java/org/z3950/zing/cql test/regression docs; do diff --git a/Changes b/Changes index c182200..2a0ee39 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,3 @@ -$Id: Changes,v 1.46 2008-05-28 10:03:53 mike Exp $ Revision history for the CQL-Java package. See the bottom of this file for a list of things still to do. diff --git a/Makefile b/Makefile index 2836ab6..0308585 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.1 2002-11-17 23:29:55 mike Exp $ **make-default**: ./Build diff --git a/README b/README index eea8b25..0120033 100644 --- a/README +++ b/README @@ -1,4 +1,3 @@ -$Id: README,v 1.24 2007-06-07 16:04:50 mike Exp $ CQL-Java - a free CQL compiler, and other CQL tools, for Java diff --git a/archive/chris-hubick/README b/archive/chris-hubick/README index b7292e5..35021e4 100644 --- a/archive/chris-hubick/README +++ b/archive/chris-hubick/README @@ -1,4 +1,3 @@ -$Id: README,v 1.1 2005-08-29 15:15:02 mike Exp $ This directory contains a substantial rewrite of CQL-Java v0.7 as supplied by Chris Hubick on 22nd August 2005. I don't think diff --git a/bin/CQLGenerator b/bin/CQLGenerator index 97c2765..55de086 100755 --- a/bin/CQLGenerator +++ b/bin/CQLGenerator @@ -1,6 +1,5 @@ #!/bin/sh -# $Id: CQLGenerator,v 1.1 2002-11-02 01:24:41 mike Exp $ # Trivial script to invoke the CQLGenerator test-harness java org.z3950.zing.cql.CQLGenerator ${@+"$@"} diff --git a/bin/CQLLexer b/bin/CQLLexer index 4967738..c07e566 100755 --- a/bin/CQLLexer +++ b/bin/CQLLexer @@ -1,6 +1,5 @@ #!/bin/sh -# $Id: CQLLexer,v 1.2 2002-11-01 23:45:28 mike Exp $ # Trivial script to invoke the CQLLexer test-harness java org.z3950.zing.cql.CQLLexer ${@+"$@"} diff --git a/bin/CQLParser b/bin/CQLParser index 3147d85..26a52b1 100755 --- a/bin/CQLParser +++ b/bin/CQLParser @@ -1,6 +1,5 @@ #!/bin/sh -# $Id: CQLParser,v 1.2 2002-11-01 23:45:28 mike Exp $ # Trivial script to invoke the CQLParser test-harness java org.z3950.zing.cql.CQLParser ${@+"$@"} diff --git a/docs/Makefile b/docs/Makefile index a61ae53..36ce6b8 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.2 2007-06-06 13:20:44 mike Exp $ all: overview-tree.html diff --git a/etc/generate.properties b/etc/generate.properties index 0494623..409f872 100644 --- a/etc/generate.properties +++ b/etc/generate.properties @@ -1,4 +1,3 @@ -# $Id: generate.properties,v 1.2 2002-11-03 16:49:38 mike Exp $ # # Propeties file to drive the org.z3950.zing.cql.CQLGenerator # test-harness. See that class's documentation for the semantics of diff --git a/etc/pqf.properties b/etc/pqf.properties index 6de0172..2448482 100644 --- a/etc/pqf.properties +++ b/etc/pqf.properties @@ -1,4 +1,3 @@ -# $Id: pqf.properties,v 1.9 2003-12-18 13:17:16 mike Exp $ # # Propeties file to drive org.z3950.zing.cql.CQLNode's toPQF() # back-end. This specifies the interpretation of various CQL diff --git a/etc/xslt/README b/etc/xslt/README index b6918eb..0ee649f 100644 --- a/etc/xslt/README +++ b/etc/xslt/README @@ -1,4 +1,3 @@ -$Id: README,v 1.2 2007-06-06 14:38:25 mike Exp $ The XSLT files in this directory are supposed to allow you to make a thin-client for SRU using only an XSLT-enabled web browser. It diff --git a/lib/README b/lib/README index 3bc0875..fdfdab7 100644 --- a/lib/README +++ b/lib/README @@ -1,4 +1,3 @@ -$Id: README,v 1.2 2002-12-09 16:29:44 mike Exp $ The library file "cql-java.jar" will appear here when you do a build in ../src/org/z3950/zing/cql. Put it on your CLASSPATH to use the diff --git a/spec/bnf b/spec/bnf index 616fa07..a49a5aa 100644 --- a/spec/bnf +++ b/spec/bnf @@ -1,4 +1,3 @@ -$Id: bnf,v 1.1 2007-06-27 23:36:19 mike Exp $ Sort of derived from http://www.loc.gov/standards/sru/cql/ diff --git a/src/main/java/org/z3950/zing/cql/CQLAndNode.java b/src/main/java/org/z3950/zing/cql/CQLAndNode.java index a1ebf76..7e39669 100644 --- a/src/main/java/org/z3950/zing/cql/CQLAndNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLAndNode.java @@ -1,4 +1,3 @@ -// $Id: CQLAndNode.java,v 1.9 2007-06-29 12:48:21 mike Exp $ package org.z3950.zing.cql; @@ -6,7 +5,6 @@ /** * Represents an AND node in a CQL parse-tree. * - * @version $Id: CQLAndNode.java,v 1.9 2007-06-29 12:48:21 mike Exp $ */ public class CQLAndNode extends CQLBooleanNode { /** diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index 06a9bc9..18c0bff 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -1,4 +1,3 @@ -// $Id: CQLBooleanNode.java,v 1.18 2007-07-03 16:03:00 mike Exp $ package org.z3950.zing.cql; import java.util.List; @@ -7,7 +6,6 @@ /** * Represents a boolean node in a CQL parse-tree. * - * @version $Id: CQLBooleanNode.java,v 1.18 2007-07-03 16:03:00 mike Exp $ */ public abstract class CQLBooleanNode extends CQLNode { diff --git a/src/main/java/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java index 8d02022..77e4fce 100644 --- a/src/main/java/org/z3950/zing/cql/CQLGenerator.java +++ b/src/main/java/org/z3950/zing/cql/CQLGenerator.java @@ -1,4 +1,3 @@ -// $Id: CQLGenerator.java,v 1.9 2007-07-03 15:41:35 mike Exp $ package org.z3950.zing.cql; import java.util.Properties; @@ -22,7 +21,6 @@ * this distribution - there is a generate_x() method * for each grammar element X. * - * @version $Id: CQLGenerator.java,v 1.9 2007-07-03 15:41:35 mike Exp $ * @see http://zing.z3950.org/cql/index.html */ diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 24dd241..e53a082 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -1,4 +1,3 @@ -// $Id: CQLLexer.java,v 1.14 2007-07-03 13:30:42 mike Exp $ package org.z3950.zing.cql; import java.io.InputStream; diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index fa263ae..8e24cf3 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -1,4 +1,3 @@ -// $Id: CQLNode.java,v 1.26 2007-07-03 13:36:03 mike Exp $ package org.z3950.zing.cql; import java.util.HashMap; @@ -11,7 +10,6 @@ /** * Represents a node in a CQL parse-tree. * - * @version $Id: CQLNode.java,v 1.26 2007-07-03 13:36:03 mike Exp $ */ public abstract class CQLNode { diff --git a/src/main/java/org/z3950/zing/cql/CQLNotNode.java b/src/main/java/org/z3950/zing/cql/CQLNotNode.java index 90346f4..4f3814c 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNotNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNotNode.java @@ -1,4 +1,3 @@ -// $Id: CQLNotNode.java,v 1.9 2007-06-29 12:48:21 mike Exp $ package org.z3950.zing.cql; @@ -6,7 +5,6 @@ /** * Represents a NOT node in a CQL parse-tree. * - * @version $Id: CQLNotNode.java,v 1.9 2007-06-29 12:48:21 mike Exp $ */ public class CQLNotNode extends CQLBooleanNode { /** diff --git a/src/main/java/org/z3950/zing/cql/CQLOrNode.java b/src/main/java/org/z3950/zing/cql/CQLOrNode.java index 67a292d..92c9dfa 100644 --- a/src/main/java/org/z3950/zing/cql/CQLOrNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLOrNode.java @@ -1,4 +1,3 @@ -// $Id: CQLOrNode.java,v 1.9 2007-06-29 12:48:21 mike Exp $ package org.z3950.zing.cql; @@ -6,7 +5,6 @@ /** * Represents an OR node in a CQL parse-tree. * - * @version $Id: CQLOrNode.java,v 1.9 2007-06-29 12:48:21 mike Exp $ */ public class CQLOrNode extends CQLBooleanNode { /** diff --git a/src/main/java/org/z3950/zing/cql/CQLParseException.java b/src/main/java/org/z3950/zing/cql/CQLParseException.java index ceb97de..ff1423f 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParseException.java +++ b/src/main/java/org/z3950/zing/cql/CQLParseException.java @@ -1,4 +1,3 @@ -// $Id: CQLParseException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; @@ -6,7 +5,6 @@ /** * Exception indicating that an error ocurred parsing CQL. * - * @version $Id: CQLParseException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ */ public class CQLParseException extends Exception { private int pos; diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 62a51b6..2509563 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -1,4 +1,3 @@ -// $Id: CQLParser.java,v 1.39 2007-08-06 15:54:48 mike Exp $ package org.z3950.zing.cql; import java.io.IOException; @@ -15,7 +14,6 @@ /** * Compiles CQL strings into parse trees of CQLNode subtypes. * - * @version $Id: CQLParser.java,v 1.39 2007-08-06 15:54:48 mike Exp $ * @see http://zing.z3950.org/cql/index.html */ diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefix.java b/src/main/java/org/z3950/zing/cql/CQLPrefix.java index cb3043f..64ed961 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefix.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefix.java @@ -1,11 +1,9 @@ -// $Id: CQLPrefix.java,v 1.5 2007-06-27 22:39:55 mike Exp $ package org.z3950.zing.cql; /** * Represents a CQL prefix mapping from short name to long identifier. * - * @version $Id: CQLPrefix.java,v 1.5 2007-06-27 22:39:55 mike Exp $ */ public class CQLPrefix { diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index 656f6e6..d3f6b74 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -1,4 +1,3 @@ -// $Id: CQLPrefixNode.java,v 1.10 2007-07-03 16:40:11 mike Exp $ package org.z3950.zing.cql; import java.util.ArrayList; @@ -9,7 +8,6 @@ /** * Represents a prefix node in a CQL parse-tree. * - * @version $Id: CQLPrefixNode.java,v 1.10 2007-07-03 16:40:11 mike Exp $ */ public class CQLPrefixNode extends CQLNode { diff --git a/src/main/java/org/z3950/zing/cql/CQLProxNode.java b/src/main/java/org/z3950/zing/cql/CQLProxNode.java index 9f1f0c3..35f1781 100644 --- a/src/main/java/org/z3950/zing/cql/CQLProxNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLProxNode.java @@ -1,4 +1,3 @@ -// $Id: CQLProxNode.java,v 1.14 2007-06-29 12:53:03 mike Exp $ package org.z3950.zing.cql; @@ -9,7 +8,6 @@ * candidate records which are sufficiently close to each other, as * specified by a set of proximity parameters. * - * @version $Id: CQLProxNode.java,v 1.14 2007-06-29 12:53:03 mike Exp $ */ public class CQLProxNode extends CQLBooleanNode { /** diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 4e9fd27..716a1e9 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -1,4 +1,3 @@ -// $Id: CQLRelation.java,v 1.19 2007-07-03 13:40:58 mike Exp $ package org.z3950.zing.cql; import java.util.List; @@ -7,7 +6,6 @@ /** * Represents a relation between a CQL index and term. * - * @version $Id: CQLRelation.java,v 1.19 2007-07-03 13:40:58 mike Exp $ */ public class CQLRelation extends CQLNode { ModifierSet ms; diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 68a4ea9..96a93e8 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -1,4 +1,3 @@ -// $Id: CQLSortNode.java,v 1.2 2008-04-11 12:05:15 mike Exp $ package org.z3950.zing.cql; import java.util.ArrayList; @@ -9,7 +8,6 @@ /** * Represents a sort node in a CQL parse-tree. * - * @version $Id: CQLSortNode.java,v 1.2 2008-04-11 12:05:15 mike Exp $ */ public class CQLSortNode extends CQLNode { /** diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index dfd0e63..a6e1772 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -1,4 +1,3 @@ -// $Id: CQLTermNode.java,v 1.28 2007-07-03 13:41:24 mike Exp $ package org.z3950.zing.cql; import java.util.ArrayList; @@ -12,7 +11,6 @@ * these must be provided - you can't have an index without a * relation or vice versa. * - * @version $Id: CQLTermNode.java,v 1.28 2007-07-03 13:41:24 mike Exp $ */ public class CQLTermNode extends CQLNode { private String index; diff --git a/src/main/java/org/z3950/zing/cql/Makefile b/src/main/java/org/z3950/zing/cql/Makefile index c318cc0..9470de2 100644 --- a/src/main/java/org/z3950/zing/cql/Makefile +++ b/src/main/java/org/z3950/zing/cql/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.18 2007-07-03 12:56:29 mike Exp $ # # Your Java compiler will require that this source directory is on the # classpath. The best way to do that is just to add the CQL-Java diff --git a/src/main/java/org/z3950/zing/cql/MissingParameterException.java b/src/main/java/org/z3950/zing/cql/MissingParameterException.java index 07873b8..c953e42 100644 --- a/src/main/java/org/z3950/zing/cql/MissingParameterException.java +++ b/src/main/java/org/z3950/zing/cql/MissingParameterException.java @@ -1,4 +1,3 @@ -// $Id: MissingParameterException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; @@ -6,7 +5,6 @@ /** * Exception indicating that a required property was not specified. * - * @version $Id: MissingParameterException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ */ public class MissingParameterException extends Exception { /** diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index 91d3a17..71232e9 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -1,4 +1,3 @@ -// $Id: Modifier.java,v 1.4 2007-07-03 13:29:34 mike Exp $ package org.z3950.zing.cql; @@ -10,7 +9,6 @@ *

* This class is used only by ModifierSet. * - * @version $Id: Modifier.java,v 1.4 2007-07-03 13:29:34 mike Exp $ */ public class Modifier { String type; diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index 7eb965f..da94b8c 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -1,4 +1,3 @@ -// $Id: ModifierSet.java,v 1.13 2007-07-03 13:30:18 mike Exp $ package org.z3950.zing.cql; import java.util.ArrayList; @@ -15,7 +14,6 @@ * zero or more type comparison value pairs, * where type, comparison and value are all strings. * - * @version $Id: ModifierSet.java,v 1.13 2007-07-03 13:30:18 mike Exp $ */ public class ModifierSet { private String base; diff --git a/src/main/java/org/z3950/zing/cql/PQFTranslationException.java b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java index 0272e84..f0d7dc2 100644 --- a/src/main/java/org/z3950/zing/cql/PQFTranslationException.java +++ b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java @@ -1,4 +1,3 @@ -// $Id: PQFTranslationException.java,v 1.1 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; @@ -6,7 +5,6 @@ /** * Base class for exceptions occurring when translating parse trees to PQF. * - * @version $Id: PQFTranslationException.java,v 1.1 2002-11-06 20:13:45 mike Exp $ */ public class PQFTranslationException extends Exception { PQFTranslationException(String s) { diff --git a/src/main/java/org/z3950/zing/cql/UnknownIndexException.java b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java index 7eabe75..01dce00 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownIndexException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java @@ -1,4 +1,3 @@ -// $Id: UnknownIndexException.java,v 1.2 2007-06-27 22:44:40 mike Exp $ package org.z3950.zing.cql; @@ -11,7 +10,6 @@ * that, because the PQF configuration doesn't know about a relation, * we throw one of these babies. * - * @version $Id: UnknownIndexException.java,v 1.2 2007-06-27 22:44:40 mike Exp $ */ public class UnknownIndexException extends PQFTranslationException { /** diff --git a/src/main/java/org/z3950/zing/cql/UnknownPositionException.java b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java index f1fc9f3..649a7d0 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownPositionException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java @@ -1,4 +1,3 @@ -// $Id: UnknownPositionException.java,v 1.2 2002-11-29 16:42:54 mike Exp $ package org.z3950.zing.cql; @@ -13,7 +12,6 @@ * configuration. If the position is not configured, we throw one of * these babies. * - * @version $Id: UnknownPositionException.java,v 1.2 2002-11-29 16:42:54 mike Exp $ */ public class UnknownPositionException extends PQFTranslationException { /** diff --git a/src/main/java/org/z3950/zing/cql/UnknownRelationException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java index 11cedb7..3a665d9 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownRelationException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java @@ -1,4 +1,3 @@ -// $Id: UnknownRelationException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; @@ -11,7 +10,6 @@ * that, because the PQF configuration doesn't know about a relation, * we throw one of these babies. * - * @version $Id: UnknownRelationException.java,v 1.2 2002-11-06 20:13:45 mike Exp $ */ public class UnknownRelationException extends PQFTranslationException { /** diff --git a/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java index 8025eb9..2d3d6f2 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java @@ -1,4 +1,3 @@ -// $Id: UnknownRelationModifierException.java,v 1.1 2002-11-06 20:13:45 mike Exp $ package org.z3950.zing.cql; @@ -11,7 +10,6 @@ * that, because the PQF configuration doesn't know about a relation modifier, * we throw one of these babies. * - * @version $Id: UnknownRelationModifierException.java,v 1.1 2002-11-06 20:13:45 mike Exp $ */ public class UnknownRelationModifierException extends PQFTranslationException { /** diff --git a/test/random/Makefile b/test/random/Makefile index d8f6a80..d3e1421 100644 --- a/test/random/Makefile +++ b/test/random/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.2 2007-06-07 16:16:15 mike Exp $ all: ../../target/cql-java-1.8.jar PATH=$(PATH):../../bin CLASSPATH=../../target/cql-java-1.8.jar ./mkrandom 100 diff --git a/test/random/README b/test/random/README index 98e7c7f..586796b 100644 --- a/test/random/README +++ b/test/random/README @@ -1,4 +1,3 @@ -$Id: README,v 1.2 2002-12-09 16:29:44 mike Exp $ In this directory, we test the integrity of the CQL-Java tools as follows: diff --git a/test/random/mkrandom b/test/random/mkrandom index 185f2c3..131e9e7 100755 --- a/test/random/mkrandom +++ b/test/random/mkrandom @@ -1,6 +1,5 @@ #!/usr/bin/perl -w -# $Id: mkrandom,v 1.2 2002-11-03 17:02:48 mike Exp $ use strict; diff --git a/test/regression/Makefile b/test/regression/Makefile index 81a3b27..5243e41 100644 --- a/test/regression/Makefile +++ b/test/regression/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.9 2002-11-28 11:56:55 mike Exp $ XMLCANONICALISER = cat # Change this to "./xmlpp.pl" if you want to check for equivalence diff --git a/test/regression/README b/test/regression/README index ec2b312..0d7b96b 100644 --- a/test/regression/README +++ b/test/regression/README @@ -1,4 +1,3 @@ -$Id: README,v 1.8 2007-06-29 13:06:07 mike Exp $ If you just don't want to think about it ---------------------------------------- diff --git a/test/regression/mkanswers b/test/regression/mkanswers index ca6eefc..16e7dd2 100755 --- a/test/regression/mkanswers +++ b/test/regression/mkanswers @@ -1,6 +1,5 @@ #!/usr/bin/perl -w -# $Id: mkanswers,v 1.5 2002-11-21 09:57:28 mike Exp $ use IO::File; use strict; diff --git a/test/regression/mktests b/test/regression/mktests index 41a1500..78057b0 100755 --- a/test/regression/mktests +++ b/test/regression/mktests @@ -1,6 +1,5 @@ #!/usr/bin/perl -w -# $Id: mktests,v 1.3 2002-11-20 22:50:45 mike Exp $ use IO::File; use strict; diff --git a/test/regression/runcanon b/test/regression/runcanon index 9c07e33..46d6a93 100755 --- a/test/regression/runcanon +++ b/test/regression/runcanon @@ -1,6 +1,5 @@ #!/usr/bin/perl -w -# $Id: runcanon,v 1.1 2007-06-29 13:05:12 mike Exp $ # # Tests that all sample queries can be rendered into idempotent # canoncial form. diff --git a/test/regression/runtests b/test/regression/runtests index 1630be9..c12cd3c 100755 --- a/test/regression/runtests +++ b/test/regression/runtests @@ -1,6 +1,5 @@ #!/usr/bin/perl -w -# $Id: runtests,v 1.12 2007-07-03 15:53:52 mike Exp $ use IO::File; use strict; diff --git a/test/regression/showtest b/test/regression/showtest index a55c143..0154d9d 100755 --- a/test/regression/showtest +++ b/test/regression/showtest @@ -1,6 +1,5 @@ #!/bin/sh -# $Id: showtest,v 1.6 2002-11-28 11:56:55 mike Exp $ if [ $# != 1 ]; then echo "Usage: $0 " >&2 From 9b2921acd159a3dcac5869ac44986c97fd0bd078 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 25 Jul 2012 11:12:10 +0200 Subject: [PATCH 083/147] Add toString --- src/main/java/org/z3950/zing/cql/CQLNode.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index 8e24cf3..a4e171d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -337,4 +337,9 @@ public static final byte[] makeQuery(CQLNode root, Properties properties) System.arraycopy(qry, 0, q, 0, offset); return q; } + + @Override + public String toString() { + return toCQL(); + } } From 2868eba4a61c9ba3e4dffa71e2c660a70fbd44bf Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Tue, 5 Mar 2013 11:06:33 +0100 Subject: [PATCH 084/147] Allow '.' to begin a word character --- pom.xml | 2 +- src/main/java/org/z3950/zing/cql/CQLLexer.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 07fdd9c..138fb9e 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ junit junit - 3.8.1 + 4.10 test diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index e53a082..5376f1d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -72,6 +72,8 @@ private class Keyword { ordinaryChar('/'); ordinaryChar('('); ordinaryChar(')'); + ordinaryChar('.'); + wordChars('.', '.'); wordChars('\'', '\''); // prevent this from introducing strings //parseNumbers(); ordinaryChar('-'); From d14e1a7b758a75d8c6a6888c8445c6d57b27154d Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Tue, 5 Mar 2013 12:38:19 +0100 Subject: [PATCH 085/147] Allow e-mails in search terms --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 5376f1d..293b45a 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -63,7 +63,7 @@ private class Keyword { CQLLexer(Reader cql, boolean lexdebug) { super(cql); - wordChars('!', '?'); // ASCII-dependency! + wordChars('!', '@'); // ASCII-dependency! wordChars('[', '`'); // ASCII-dependency! quoteChar('"'); ordinaryChar('='); From beabf8e9a3c5bd13dfafb0fb4bac0eb9fa0a90e5 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Tue, 5 Mar 2013 13:02:39 +0100 Subject: [PATCH 086/147] Allow registration of custom relations --- .../java/org/z3950/zing/cql/CQLParser.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 2509563..6bd6d01 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -8,7 +8,9 @@ import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** @@ -21,6 +23,8 @@ public class CQLParser { private CQLLexer lexer; private PositionAwareReader par; //active reader with position private int compat; // When false, implement CQL 1.2 + private final Set customRelations = new HashSet(); + public static final int V1POINT1 = 12368; public static final int V1POINT2 = 12369; public static final int V1POINT1SORT = 12370; @@ -57,6 +61,25 @@ private static void debug(String str) { System.err.println("PARSEDEBUG: " + str); } + /** + * Registers custom relation in this parser. Note that when a custom relation + * is registered the parser is no longer strictly compliant with the chosen spec. + * @param relation + * @return true if custom relation has not been registered already + */ + public boolean registerCustomRelation(String relation) { + return customRelations.add(relation); + } + + /** + * Unregisters previously registered custom relation in this instance of the parser. + * @param relation + * @return true is relation has been previously registered + */ + public boolean unregisterCustomRelation(String relation) { + return customRelations.remove(relation); + } + /** * Compiles a CQL query. *

@@ -272,7 +295,8 @@ private boolean isRelation() { lexer.sval.equals("encloses") || (lexer.sval.equals("exact") && compat != V1POINT2) || (lexer.sval.equals("scr") && compat != V1POINT2) || - (lexer.sval.equals("adj") && compat == V1POINT2))) + (lexer.sval.equals("adj") && compat == V1POINT2) || + customRelations.contains(lexer.sval))) return true; return isSymbolicRelation(); @@ -444,6 +468,7 @@ public static void main (String[] args) { } CQLParser parser = new CQLParser(compat); + parser.registerCustomRelation("@"); CQLNode root = null; try { root = parser.parse(cql); From 1d03472f13d7cf463707da0027b9c796cde27812 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Tue, 5 Mar 2013 13:24:31 +0100 Subject: [PATCH 087/147] Flag to control if keyword terms are allowed If set, parser instance is no longer fully compliant with the official CQL grammar but parsing is more strict at disallowing problematic queries. --- .../java/org/z3950/zing/cql/CQLParser.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 6bd6d01..d577cd9 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -22,12 +22,13 @@ public class CQLParser { private CQLLexer lexer; private PositionAwareReader par; //active reader with position - private int compat; // When false, implement CQL 1.2 + private final int compat; // When false, implement CQL 1.2 private final Set customRelations = new HashSet(); public static final int V1POINT1 = 12368; public static final int V1POINT2 = 12369; public static final int V1POINT1SORT = 12370; + public final boolean allowKeywordTerms; static private boolean DEBUG = false; static private boolean LEXDEBUG = false; @@ -47,13 +48,27 @@ public class CQLParser { */ public CQLParser(int compat) { this.compat = compat; + this.allowKeywordTerms = true; } - + + /** + * Official CQL grammar allows registered keywords like 'and/or/not/sortby/prox' + * to be used unquoted in terms. This constructor allows to create an instance + * of a parser that prohibits this behavior while sacrificing compatibility. + * @param compat CQL version compatibility + * @param allowKeywordTerms when false registered keywords are disallowed in unquoted terms + */ + public CQLParser(int compat, boolean allowKeywordTerms) { + this.compat = V1POINT2; + this.allowKeywordTerms = allowKeywordTerms; + } + /** * The new parser implements CQL 1.2 */ public CQLParser() { this.compat = V1POINT2; + this.allowKeywordTerms = true; } private static void debug(String str) { @@ -340,11 +355,12 @@ private String matchSymbol(String expected) // indexes, terms, prefix names and prefix identifiers. // ### Instead, we should ask the lexer whether what we // have is a keyword, and let the knowledge reside there. + (allowKeywordTerms && lexer.ttype == CQLLexer.TT_AND || lexer.ttype == CQLLexer.TT_OR || lexer.ttype == CQLLexer.TT_NOT || lexer.ttype == CQLLexer.TT_PROX || - lexer.ttype == CQLLexer.TT_SORTBY) { + lexer.ttype == CQLLexer.TT_SORTBY)) { String symbol = (lexer.ttype == CQLLexer.TT_NUMBER) ? lexer.render() : lexer.sval; match(lexer.ttype); @@ -468,7 +484,6 @@ public static void main (String[] args) { } CQLParser parser = new CQLParser(compat); - parser.registerCustomRelation("@"); CQLNode root = null; try { root = parser.parse(cql); From 2484476a3d335c4317ac4a77ee514e643864535c Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Tue, 5 Mar 2013 13:41:36 +0100 Subject: [PATCH 088/147] Update --- Changes | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Changes b/Changes index 2a0ee39..db9734b 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,13 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. +1.11 Tue 5 Mar 2013 13:38:18 CET + - Fix problem with parsing unquoted terms that begin with a '.' + - Fix problem with parsing unquoted terms that contain a '@' + - allow registration of custom relations + - optional flag to set strict-but-not-compliant mode that prohibits + unqouted keywords to be used as terms + 1.8 Fri Jul 22 18:02:41 CEST 2011 - API changes: removed direct access to internal state and introduced getters, removed usages of obsolete collections (Vector, Hashtable), From a915b449290ca33217565af4e06911ba5b09ff1b Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Tue, 5 Mar 2013 13:42:04 +0100 Subject: [PATCH 089/147] [maven-release-plugin] prepare release v1.11 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 138fb9e..d141d5f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.11-SNAPSHOT + 1.11 cql-java http://www.indexdata.com/cql-java From 8d93c492779b573b0e4384d3cb3db7a85048d6b8 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Tue, 5 Mar 2013 13:42:04 +0100 Subject: [PATCH 090/147] [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d141d5f..9883807 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.11 + 1.12-SNAPSHOT cql-java http://www.indexdata.com/cql-java From 2145a5e2293e15d1c34191b7d9245561c3b4e3e7 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 14 Mar 2014 14:23:20 +0100 Subject: [PATCH 091/147] Port regression/randomized testing to JUnit --- Makefile | 7 - docs/.gitignore | 14 -- docs/Makefile | 22 --- mkdist | 21 -- .../java/org/z3950/zing/cql/CQLParser.java | 2 +- src/main/java/org/z3950/zing/cql/Makefile | 33 ---- .../org/z3950/zing/cql/CQLParserTest.java | 182 ++++++++++++++++++ src/test/resources/generate.properties | 10 + src/test/resources/regression/01/01.cql | 1 + src/test/resources/regression/01/01.xcql | 7 + src/test/resources/regression/01/02.cql | 1 + src/test/resources/regression/01/02.xcql | 7 + src/test/resources/regression/01/03.cql | 1 + src/test/resources/regression/01/03.xcql | 7 + src/test/resources/regression/01/04.cql | 1 + src/test/resources/regression/01/04.xcql | 7 + src/test/resources/regression/01/05.cql | 1 + src/test/resources/regression/01/05.xcql | 7 + src/test/resources/regression/01/06.cql | 1 + src/test/resources/regression/01/06.xcql | 7 + src/test/resources/regression/01/07.cql | 1 + src/test/resources/regression/01/07.xcql | 7 + src/test/resources/regression/01/08.cql | 1 + src/test/resources/regression/01/08.xcql | 7 + src/test/resources/regression/01/09.cql | 1 + src/test/resources/regression/01/09.xcql | 7 + src/test/resources/regression/01/10.cql | 1 + src/test/resources/regression/01/10.xcql | 7 + src/test/resources/regression/01/11.cql | 1 + src/test/resources/regression/01/11.xcql | 7 + src/test/resources/regression/01/name | 1 + src/test/resources/regression/02/01.cql | 1 + src/test/resources/regression/02/01.xcql | 7 + src/test/resources/regression/02/02.cql | 1 + src/test/resources/regression/02/02.xcql | 7 + src/test/resources/regression/02/03.cql | 1 + src/test/resources/regression/02/03.xcql | 7 + src/test/resources/regression/02/04.cql | 1 + src/test/resources/regression/02/04.xcql | 7 + src/test/resources/regression/02/05.cql | 1 + src/test/resources/regression/02/05.xcql | 7 + src/test/resources/regression/02/06.cql | 1 + src/test/resources/regression/02/06.xcql | 7 + src/test/resources/regression/02/07.cql | 1 + src/test/resources/regression/02/07.xcql | 7 + src/test/resources/regression/02/08.cql | 1 + src/test/resources/regression/02/08.xcql | 12 ++ src/test/resources/regression/02/09.cql | 1 + src/test/resources/regression/02/09.xcql | 15 ++ src/test/resources/regression/02/10.cql | 1 + src/test/resources/regression/02/10.xcql | 7 + src/test/resources/regression/02/11.cql | 1 + src/test/resources/regression/02/11.xcql | 12 ++ src/test/resources/regression/02/12.cql | 1 + src/test/resources/regression/02/12.xcql | 7 + src/test/resources/regression/02/13.cql | 1 + src/test/resources/regression/02/13.xcql | 14 ++ src/test/resources/regression/02/14.cql | 1 + src/test/resources/regression/02/14.xcql | 17 ++ src/test/resources/regression/02/15.cql | 1 + src/test/resources/regression/02/15.xcql | 7 + src/test/resources/regression/02/16.cql | 1 + src/test/resources/regression/02/16.xcql | 7 + src/test/resources/regression/02/17.cql | 1 + src/test/resources/regression/02/17.xcql | 7 + src/test/resources/regression/02/name | 1 + src/test/resources/regression/03/01.cql | 1 + src/test/resources/regression/03/01.xcql | 23 +++ src/test/resources/regression/03/02.cql | 1 + src/test/resources/regression/03/02.xcql | 23 +++ src/test/resources/regression/03/03.cql | 1 + src/test/resources/regression/03/03.xcql | 23 +++ src/test/resources/regression/03/04.cql | 1 + src/test/resources/regression/03/04.xcql | 23 +++ src/test/resources/regression/03/05.cql | 1 + src/test/resources/regression/03/05.xcql | 23 +++ src/test/resources/regression/03/06.cql | 1 + src/test/resources/regression/03/06.xcql | 23 +++ src/test/resources/regression/03/07.cql | 1 + src/test/resources/regression/03/07.xcql | 23 +++ src/test/resources/regression/03/08.cql | 1 + src/test/resources/regression/03/08.xcql | 23 +++ src/test/resources/regression/03/09.cql | 1 + src/test/resources/regression/03/09.xcql | 55 ++++++ src/test/resources/regression/03/name | 1 + src/test/resources/regression/04/01.cql | 1 + src/test/resources/regression/04/01.xcql | 23 +++ src/test/resources/regression/04/02.cql | 1 + src/test/resources/regression/04/02.xcql | 28 +++ src/test/resources/regression/04/name | 1 + src/test/resources/regression/05/01.cql | 1 + src/test/resources/regression/05/01.xcql | 23 +++ src/test/resources/regression/05/02.cql | 1 + src/test/resources/regression/05/02.xcql | 38 ++++ src/test/resources/regression/05/03.cql | 1 + src/test/resources/regression/05/03.xcql | 30 +++ src/test/resources/regression/05/04.cql | 1 + src/test/resources/regression/05/04.xcql | 30 +++ src/test/resources/regression/05/05.cql | 1 + src/test/resources/regression/05/05.xcql | 30 +++ src/test/resources/regression/05/06.cql | 1 + src/test/resources/regression/05/06.xcql | 35 ++++ src/test/resources/regression/05/07.cql | 1 + src/test/resources/regression/05/07.xcql | 23 +++ src/test/resources/regression/05/08.cql | 1 + src/test/resources/regression/05/08.xcql | 28 +++ src/test/resources/regression/05/09.cql | 1 + src/test/resources/regression/05/09.xcql | 30 +++ src/test/resources/regression/05/name | 1 + src/test/resources/regression/06/01.cql | 1 + src/test/resources/regression/06/01.xcql | 7 + src/test/resources/regression/06/02.cql | 1 + src/test/resources/regression/06/02.xcql | 7 + src/test/resources/regression/06/03.cql | 1 + src/test/resources/regression/06/03.xcql | 7 + src/test/resources/regression/06/04.cql | 1 + src/test/resources/regression/06/04.xcql | 7 + src/test/resources/regression/06/05.cql | 1 + src/test/resources/regression/06/05.xcql | 7 + src/test/resources/regression/06/06.cql | 1 + src/test/resources/regression/06/06.xcql | 7 + src/test/resources/regression/06/name | 1 + src/test/resources/regression/07/01.cql | 1 + src/test/resources/regression/07/01.xcql | 55 ++++++ src/test/resources/regression/07/02.cql | 1 + src/test/resources/regression/07/02.xcql | 55 ++++++ src/test/resources/regression/07/03.cql | 1 + src/test/resources/regression/07/03.xcql | 55 ++++++ src/test/resources/regression/07/name | 1 + src/test/resources/regression/08/01.cql | 1 + src/test/resources/regression/08/01.xcql | 13 ++ src/test/resources/regression/08/02.cql | 1 + src/test/resources/regression/08/02.xcql | 12 ++ src/test/resources/regression/08/03.cql | 1 + src/test/resources/regression/08/03.xcql | 33 ++++ src/test/resources/regression/08/name | 1 + src/test/resources/regression/09/01.cql | 1 + src/test/resources/regression/09/01.xcql | 39 ++++ src/test/resources/regression/09/02.cql | 1 + src/test/resources/regression/09/02.xcql | 7 + src/test/resources/regression/09/03.cql | 1 + src/test/resources/regression/09/03.xcql | 7 + src/test/resources/regression/09/04.cql | 1 + src/test/resources/regression/09/04.xcql | 16 ++ src/test/resources/regression/09/05.cql | 1 + src/test/resources/regression/09/05.xcql | 12 ++ src/test/resources/regression/09/06.cql | 1 + src/test/resources/regression/09/06.xcql | 18 ++ src/test/resources/regression/09/name | 1 + src/test/resources/regression/10/01.cql | 1 + src/test/resources/regression/10/01.xcql | 12 ++ src/test/resources/regression/10/02.cql | 1 + src/test/resources/regression/10/02.xcql | 28 +++ src/test/resources/regression/10/03.cql | 1 + src/test/resources/regression/10/03.xcql | 12 ++ src/test/resources/regression/10/04.cql | 1 + src/test/resources/regression/10/04.xcql | 17 ++ src/test/resources/regression/10/05.cql | 1 + src/test/resources/regression/10/05.xcql | 17 ++ src/test/resources/regression/10/06.cql | 1 + src/test/resources/regression/10/06.xcql | 20 ++ src/test/resources/regression/10/07.cql | 1 + src/test/resources/regression/10/07.xcql | 15 ++ src/test/resources/regression/10/08.cql | 1 + src/test/resources/regression/10/08.xcql | 17 ++ src/test/resources/regression/10/09.cql | 1 + src/test/resources/regression/10/09.xcql | 19 ++ src/test/resources/regression/10/10.cql | 1 + src/test/resources/regression/10/10.xcql | 18 ++ src/test/resources/regression/10/11.cql | 1 + src/test/resources/regression/10/11.xcql | 38 ++++ src/test/resources/regression/10/12.cql | 1 + src/test/resources/regression/10/12.xcql | 18 ++ src/test/resources/regression/10/13.cql | 1 + src/test/resources/regression/10/13.xcql | 18 ++ src/test/resources/regression/10/14.cql | 1 + src/test/resources/regression/10/14.xcql | 34 ++++ src/test/resources/regression/10/15.cql | 1 + src/test/resources/regression/10/15.xcql | 22 +++ src/test/resources/regression/10/16.cql | 1 + src/test/resources/regression/10/16.xcql | 40 ++++ src/test/resources/regression/10/name | 1 + 182 files changed, 1782 insertions(+), 98 deletions(-) delete mode 100644 Makefile delete mode 100644 docs/.gitignore delete mode 100644 docs/Makefile delete mode 100755 mkdist delete mode 100644 src/main/java/org/z3950/zing/cql/Makefile create mode 100644 src/test/java/org/z3950/zing/cql/CQLParserTest.java create mode 100644 src/test/resources/generate.properties create mode 100644 src/test/resources/regression/01/01.cql create mode 100644 src/test/resources/regression/01/01.xcql create mode 100644 src/test/resources/regression/01/02.cql create mode 100644 src/test/resources/regression/01/02.xcql create mode 100644 src/test/resources/regression/01/03.cql create mode 100644 src/test/resources/regression/01/03.xcql create mode 100644 src/test/resources/regression/01/04.cql create mode 100644 src/test/resources/regression/01/04.xcql create mode 100644 src/test/resources/regression/01/05.cql create mode 100644 src/test/resources/regression/01/05.xcql create mode 100644 src/test/resources/regression/01/06.cql create mode 100644 src/test/resources/regression/01/06.xcql create mode 100644 src/test/resources/regression/01/07.cql create mode 100644 src/test/resources/regression/01/07.xcql create mode 100644 src/test/resources/regression/01/08.cql create mode 100644 src/test/resources/regression/01/08.xcql create mode 100644 src/test/resources/regression/01/09.cql create mode 100644 src/test/resources/regression/01/09.xcql create mode 100644 src/test/resources/regression/01/10.cql create mode 100644 src/test/resources/regression/01/10.xcql create mode 100644 src/test/resources/regression/01/11.cql create mode 100644 src/test/resources/regression/01/11.xcql create mode 100644 src/test/resources/regression/01/name create mode 100644 src/test/resources/regression/02/01.cql create mode 100644 src/test/resources/regression/02/01.xcql create mode 100644 src/test/resources/regression/02/02.cql create mode 100644 src/test/resources/regression/02/02.xcql create mode 100644 src/test/resources/regression/02/03.cql create mode 100644 src/test/resources/regression/02/03.xcql create mode 100644 src/test/resources/regression/02/04.cql create mode 100644 src/test/resources/regression/02/04.xcql create mode 100644 src/test/resources/regression/02/05.cql create mode 100644 src/test/resources/regression/02/05.xcql create mode 100644 src/test/resources/regression/02/06.cql create mode 100644 src/test/resources/regression/02/06.xcql create mode 100644 src/test/resources/regression/02/07.cql create mode 100644 src/test/resources/regression/02/07.xcql create mode 100644 src/test/resources/regression/02/08.cql create mode 100644 src/test/resources/regression/02/08.xcql create mode 100644 src/test/resources/regression/02/09.cql create mode 100644 src/test/resources/regression/02/09.xcql create mode 100644 src/test/resources/regression/02/10.cql create mode 100644 src/test/resources/regression/02/10.xcql create mode 100644 src/test/resources/regression/02/11.cql create mode 100644 src/test/resources/regression/02/11.xcql create mode 100644 src/test/resources/regression/02/12.cql create mode 100644 src/test/resources/regression/02/12.xcql create mode 100644 src/test/resources/regression/02/13.cql create mode 100644 src/test/resources/regression/02/13.xcql create mode 100644 src/test/resources/regression/02/14.cql create mode 100644 src/test/resources/regression/02/14.xcql create mode 100644 src/test/resources/regression/02/15.cql create mode 100644 src/test/resources/regression/02/15.xcql create mode 100644 src/test/resources/regression/02/16.cql create mode 100644 src/test/resources/regression/02/16.xcql create mode 100644 src/test/resources/regression/02/17.cql create mode 100644 src/test/resources/regression/02/17.xcql create mode 100644 src/test/resources/regression/02/name create mode 100644 src/test/resources/regression/03/01.cql create mode 100644 src/test/resources/regression/03/01.xcql create mode 100644 src/test/resources/regression/03/02.cql create mode 100644 src/test/resources/regression/03/02.xcql create mode 100644 src/test/resources/regression/03/03.cql create mode 100644 src/test/resources/regression/03/03.xcql create mode 100644 src/test/resources/regression/03/04.cql create mode 100644 src/test/resources/regression/03/04.xcql create mode 100644 src/test/resources/regression/03/05.cql create mode 100644 src/test/resources/regression/03/05.xcql create mode 100644 src/test/resources/regression/03/06.cql create mode 100644 src/test/resources/regression/03/06.xcql create mode 100644 src/test/resources/regression/03/07.cql create mode 100644 src/test/resources/regression/03/07.xcql create mode 100644 src/test/resources/regression/03/08.cql create mode 100644 src/test/resources/regression/03/08.xcql create mode 100644 src/test/resources/regression/03/09.cql create mode 100644 src/test/resources/regression/03/09.xcql create mode 100644 src/test/resources/regression/03/name create mode 100644 src/test/resources/regression/04/01.cql create mode 100644 src/test/resources/regression/04/01.xcql create mode 100644 src/test/resources/regression/04/02.cql create mode 100644 src/test/resources/regression/04/02.xcql create mode 100644 src/test/resources/regression/04/name create mode 100644 src/test/resources/regression/05/01.cql create mode 100644 src/test/resources/regression/05/01.xcql create mode 100644 src/test/resources/regression/05/02.cql create mode 100644 src/test/resources/regression/05/02.xcql create mode 100644 src/test/resources/regression/05/03.cql create mode 100644 src/test/resources/regression/05/03.xcql create mode 100644 src/test/resources/regression/05/04.cql create mode 100644 src/test/resources/regression/05/04.xcql create mode 100644 src/test/resources/regression/05/05.cql create mode 100644 src/test/resources/regression/05/05.xcql create mode 100644 src/test/resources/regression/05/06.cql create mode 100644 src/test/resources/regression/05/06.xcql create mode 100644 src/test/resources/regression/05/07.cql create mode 100644 src/test/resources/regression/05/07.xcql create mode 100644 src/test/resources/regression/05/08.cql create mode 100644 src/test/resources/regression/05/08.xcql create mode 100644 src/test/resources/regression/05/09.cql create mode 100644 src/test/resources/regression/05/09.xcql create mode 100644 src/test/resources/regression/05/name create mode 100644 src/test/resources/regression/06/01.cql create mode 100644 src/test/resources/regression/06/01.xcql create mode 100644 src/test/resources/regression/06/02.cql create mode 100644 src/test/resources/regression/06/02.xcql create mode 100644 src/test/resources/regression/06/03.cql create mode 100644 src/test/resources/regression/06/03.xcql create mode 100644 src/test/resources/regression/06/04.cql create mode 100644 src/test/resources/regression/06/04.xcql create mode 100644 src/test/resources/regression/06/05.cql create mode 100644 src/test/resources/regression/06/05.xcql create mode 100644 src/test/resources/regression/06/06.cql create mode 100644 src/test/resources/regression/06/06.xcql create mode 100644 src/test/resources/regression/06/name create mode 100644 src/test/resources/regression/07/01.cql create mode 100644 src/test/resources/regression/07/01.xcql create mode 100644 src/test/resources/regression/07/02.cql create mode 100644 src/test/resources/regression/07/02.xcql create mode 100644 src/test/resources/regression/07/03.cql create mode 100644 src/test/resources/regression/07/03.xcql create mode 100644 src/test/resources/regression/07/name create mode 100644 src/test/resources/regression/08/01.cql create mode 100644 src/test/resources/regression/08/01.xcql create mode 100644 src/test/resources/regression/08/02.cql create mode 100644 src/test/resources/regression/08/02.xcql create mode 100644 src/test/resources/regression/08/03.cql create mode 100644 src/test/resources/regression/08/03.xcql create mode 100644 src/test/resources/regression/08/name create mode 100644 src/test/resources/regression/09/01.cql create mode 100644 src/test/resources/regression/09/01.xcql create mode 100644 src/test/resources/regression/09/02.cql create mode 100644 src/test/resources/regression/09/02.xcql create mode 100644 src/test/resources/regression/09/03.cql create mode 100644 src/test/resources/regression/09/03.xcql create mode 100644 src/test/resources/regression/09/04.cql create mode 100644 src/test/resources/regression/09/04.xcql create mode 100644 src/test/resources/regression/09/05.cql create mode 100644 src/test/resources/regression/09/05.xcql create mode 100644 src/test/resources/regression/09/06.cql create mode 100644 src/test/resources/regression/09/06.xcql create mode 100644 src/test/resources/regression/09/name create mode 100644 src/test/resources/regression/10/01.cql create mode 100644 src/test/resources/regression/10/01.xcql create mode 100644 src/test/resources/regression/10/02.cql create mode 100644 src/test/resources/regression/10/02.xcql create mode 100644 src/test/resources/regression/10/03.cql create mode 100644 src/test/resources/regression/10/03.xcql create mode 100644 src/test/resources/regression/10/04.cql create mode 100644 src/test/resources/regression/10/04.xcql create mode 100644 src/test/resources/regression/10/05.cql create mode 100644 src/test/resources/regression/10/05.xcql create mode 100644 src/test/resources/regression/10/06.cql create mode 100644 src/test/resources/regression/10/06.xcql create mode 100644 src/test/resources/regression/10/07.cql create mode 100644 src/test/resources/regression/10/07.xcql create mode 100644 src/test/resources/regression/10/08.cql create mode 100644 src/test/resources/regression/10/08.xcql create mode 100644 src/test/resources/regression/10/09.cql create mode 100644 src/test/resources/regression/10/09.xcql create mode 100644 src/test/resources/regression/10/10.cql create mode 100644 src/test/resources/regression/10/10.xcql create mode 100644 src/test/resources/regression/10/11.cql create mode 100644 src/test/resources/regression/10/11.xcql create mode 100644 src/test/resources/regression/10/12.cql create mode 100644 src/test/resources/regression/10/12.xcql create mode 100644 src/test/resources/regression/10/13.cql create mode 100644 src/test/resources/regression/10/13.xcql create mode 100644 src/test/resources/regression/10/14.cql create mode 100644 src/test/resources/regression/10/14.xcql create mode 100644 src/test/resources/regression/10/15.cql create mode 100644 src/test/resources/regression/10/15.xcql create mode 100644 src/test/resources/regression/10/16.cql create mode 100644 src/test/resources/regression/10/16.xcql create mode 100644 src/test/resources/regression/10/name diff --git a/Makefile b/Makefile deleted file mode 100644 index 0308585..0000000 --- a/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -**make-default**: - ./Build - -clean: - ./Build clean - diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index c796f0b..0000000 --- a/docs/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -allclasses-frame.html -allclasses-noframe.html -constant-values.html -deprecated-list.html -help-doc.html -index-all.html -index.html -org -overview-tree.html -package-list -packages.html -serialized-form.html -stylesheet.css -resources diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 36ce6b8..0000000 --- a/docs/Makefile +++ /dev/null @@ -1,22 +0,0 @@ - -all: overview-tree.html - -overview-tree.html: ../src/main/java/org/z3950/zing/cql/*.java - nice javadoc -classpath ../src/main/java \ - -author -version -windowtitle cql-java org.z3950.zing.cql - -clean: - rm -rf allclasses-frame.html \ - allclasses-noframe.html \ - deprecated-list.html \ - help-doc.html \ - index-all.html \ - index.html \ - org \ - overview-tree.html \ - package-list \ - packages.html \ - serialized-form.html \ - constant-values.html \ - stylesheet.css \ - resources diff --git a/mkdist b/mkdist deleted file mode 100755 index fb065f8..0000000 --- a/mkdist +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# mkdist - make a distribution of the CQL-Java software - -version=`cat VERSION` -distdir=cql-java-$version -distfile=$distdir.tar.gz -tmpdir=/tmp/$distdir -echo "Building $distdir" -trap "rm -rf $tmpdir" 1 2 15 # 0 -cp -rp . $tmpdir -cd $tmpdir -find . \( -name CVS -o -name .cvsignore \) -print | xargs rm -rf -rm -rf archive mkdist etc/xslt .git target -( cd src/main/java/org/z3950/zing/cql && make && make clean ) -( cd docs && make ) -( cd test/regression && make distclean ) -cd .. -tar cf - $distdir | gzip -9v > $distfile -rm -rf $tmpdir -echo "Made /tmp/$distfile" diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index d577cd9..72a39a3 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -59,7 +59,7 @@ public CQLParser(int compat) { * @param allowKeywordTerms when false registered keywords are disallowed in unquoted terms */ public CQLParser(int compat, boolean allowKeywordTerms) { - this.compat = V1POINT2; + this.compat = compat; this.allowKeywordTerms = allowKeywordTerms; } diff --git a/src/main/java/org/z3950/zing/cql/Makefile b/src/main/java/org/z3950/zing/cql/Makefile deleted file mode 100644 index 9470de2..0000000 --- a/src/main/java/org/z3950/zing/cql/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# -# Your Java compiler will require that this source directory is on the -# classpath. The best way to do that is just to add the CQL-Java -# distribution's "src" subdirectory to your CLASSPATH environment -# variable, like this: -# CLASSPATH=$CLASSPATH:/where/ever/you/unpacked/it/cql-java-VERSION/src - -OBJ = Utils.class \ - CQLNode.class CQLTermNode.class CQLBooleanNode.class \ - CQLAndNode.class CQLOrNode.class CQLNotNode.class \ - CQLProxNode.class CQLPrefixNode.class CQLSortNode.class \ - CQLPrefix.class \ - CQLRelation.class Modifier.class ModifierSet.class \ - CQLParser.class CQLLexer.class CQLGenerator.class \ - CQLParseException.class MissingParameterException.class \ - PQFTranslationException.class \ - UnknownIndexException.class UnknownRelationException.class \ - UnknownRelationModifierException.class UnknownPositionException.class - -JARPATH = ../../../lib/cql-java.jar -JAR = ../../../../../../$(JARPATH) -$(JAR): $(OBJ) - cd ../../../..; jar cf $(JARPATH) org/z3950/zing/cql/*.class - -%.class: %.java - javac -Xlint:unchecked *.java - -test: $(JAR) - cd ../../../../../../../test/regression && make - -clean: - rm -f $(OBJ) 'CQLLexer$$Keyword.class' - diff --git a/src/test/java/org/z3950/zing/cql/CQLParserTest.java b/src/test/java/org/z3950/zing/cql/CQLParserTest.java new file mode 100644 index 0000000..7e258e0 --- /dev/null +++ b/src/test/java/org/z3950/zing/cql/CQLParserTest.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 1995-2014, Index Datassss + * All rights reserved. + * See the file LICENSE for details. + */ +package org.z3950.zing.cql; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLDecoder; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +import static java.lang.System.out; +import java.util.Properties; + +/** + * + * @author jakub + */ +public class CQLParserTest { + public CQLParserTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + /** + * Test of main method, of class CQLParser. + */ + @Test + public void testRegressionQueries() throws IOException { + System.out.println("Testing the parser using pre-canned regression queries..."); + //we might be running the test from within the jar + //list all resource dirs, then traverse them + String[] dirs = getResourceListing(this.getClass(), "regression"); + for (String dir : dirs) { + String files[] = getResourceListing(this.getClass(), "regression/" + dir); + for (String file : files) { + if (!file.endsWith(".cql")) continue; + out.println("Parsing "+dir+"/"+file); + InputStream is = this.getClass().getResourceAsStream("/regression/"+dir+"/"+file); + BufferedReader reader = null, reader2 = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + String input = reader.readLine(); + out.println("Query: "+input); + CQLParser parser = new CQLParser(); + CQLNode parsed = parser.parse(input); + String xcql = parsed.toXCQL(); + out.println("Parsed:"); + out.println(xcql); + //read the expected xcql output + String prefix = file.substring(0, file.length()-4); + reader2 = new BufferedReader(new InputStreamReader( + this.getClass().getResourceAsStream("/regression/"+dir+"/"+prefix+".xcql"))); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader2.readLine()) != null) { + sb.append(line).append("\n"); + } + String expected = sb.toString(); + out.println("Expected: "); + out.println(expected); + assertEquals("Assertion failure for "+dir+"/"+file, expected, xcql); + } catch (CQLParseException pe) { + fail("Parsing failed with: "+pe.toString()); + } finally { + if (reader != null) reader.close(); + if (reader2 != null) reader2.close(); + } + } + } + } + + @Test + public void testRandomQueries() throws IOException, MissingParameterException { + out.println("Testing the parser using 100 randomly generated queries..."); + Properties params = new Properties(); + InputStream is = getClass().getResourceAsStream("/generate.properties"); + if (is == null) + fail("Cannot locate generate.properties"); + params.load(is); + is.close(); + CQLGenerator generator = new CQLGenerator(params); + for (int i=0; i<100; i++) { + CQLNode random = generator.generate(); + String expected = random.toCQL(); + out.println("Generated query: "+expected); + CQLParser parser = new CQLParser(); + try { + CQLNode parsed = parser.parse(expected); + String result = parsed.toCQL(); + assertEquals(expected, result); + } catch (CQLParseException pe) { + fail("Generated query failed to parse: "+pe.getMessage()); + } + } + } + + + //helper methods follow + //TODO move to masterkey-common + + @SuppressWarnings("rawtypes") + public static String[] getResourceListing(Class clazz, String path) throws + IOException { + URL dirURL = clazz.getClassLoader().getResource(path); + if (dirURL != null && dirURL.getProtocol().equals("file")) { + /* A file path: easy enough */ + try { + return new File(dirURL.toURI()).list(); + } catch (URISyntaxException use) { + throw new UnsupportedOperationException(use); + } + } + + if (dirURL == null) { + /* + * In case of a jar file, we can't actually find a directory. + * Have to assume the same jar as clazz. + */ + String me = clazz.getName().replace(".", "/") + ".class"; + dirURL = clazz.getClassLoader().getResource(me); + } + + if (dirURL.getProtocol().equals("jar")) { + /* A JAR path */ + String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf( + "!")); //strip out only the JAR file + JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8")); + Enumeration entries = jar.entries(); //gives ALL entries in jar + Set result = new HashSet(); //avoid duplicates in case it is a subdirectory + while (entries.hasMoreElements()) { + String name = entries.nextElement().getName(); + if (name.startsWith(path)) { //filter according to the path + String entry = name.substring(path.length()); + int checkSubdir = entry.indexOf("/"); + if (checkSubdir >= 0) { + // if it is a subdirectory, we just return the directory name + entry = entry.substring(0, checkSubdir); + } + result.add(entry); + } + } + return result.toArray(new String[result.size()]); + } + + throw new UnsupportedOperationException("Cannot list files for URL " + + dirURL); + } +} \ No newline at end of file diff --git a/src/test/resources/generate.properties b/src/test/resources/generate.properties new file mode 100644 index 0000000..409f872 --- /dev/null +++ b/src/test/resources/generate.properties @@ -0,0 +1,10 @@ +# +# Propeties file to drive the org.z3950.zing.cql.CQLGenerator +# test-harness. See that class's documentation for the semantics of +# these properties. +# +complexQuery=0.4 +complexClause=0.4 +equalsRelation=0.5 +numericRelation=0.7 +proxOp=0.0 diff --git a/src/test/resources/regression/01/01.cql b/src/test/resources/regression/01/01.cql new file mode 100644 index 0000000..5d5b306 --- /dev/null +++ b/src/test/resources/regression/01/01.cql @@ -0,0 +1 @@ +cat \ No newline at end of file diff --git a/src/test/resources/regression/01/01.xcql b/src/test/resources/regression/01/01.xcql new file mode 100644 index 0000000..48aee99 --- /dev/null +++ b/src/test/resources/regression/01/01.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + cat + diff --git a/src/test/resources/regression/01/02.cql b/src/test/resources/regression/01/02.cql new file mode 100644 index 0000000..d579091 --- /dev/null +++ b/src/test/resources/regression/01/02.cql @@ -0,0 +1 @@ +"cat" \ No newline at end of file diff --git a/src/test/resources/regression/01/02.xcql b/src/test/resources/regression/01/02.xcql new file mode 100644 index 0000000..48aee99 --- /dev/null +++ b/src/test/resources/regression/01/02.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + cat + diff --git a/src/test/resources/regression/01/03.cql b/src/test/resources/regression/01/03.cql new file mode 100644 index 0000000..dac67a1 --- /dev/null +++ b/src/test/resources/regression/01/03.cql @@ -0,0 +1 @@ +comp.os.linux \ No newline at end of file diff --git a/src/test/resources/regression/01/03.xcql b/src/test/resources/regression/01/03.xcql new file mode 100644 index 0000000..af191d3 --- /dev/null +++ b/src/test/resources/regression/01/03.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + comp.os.linux + diff --git a/src/test/resources/regression/01/04.cql b/src/test/resources/regression/01/04.cql new file mode 100644 index 0000000..b665f17 --- /dev/null +++ b/src/test/resources/regression/01/04.cql @@ -0,0 +1 @@ +xml:element \ No newline at end of file diff --git a/src/test/resources/regression/01/04.xcql b/src/test/resources/regression/01/04.xcql new file mode 100644 index 0000000..4141430 --- /dev/null +++ b/src/test/resources/regression/01/04.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + xml:element + diff --git a/src/test/resources/regression/01/05.cql b/src/test/resources/regression/01/05.cql new file mode 100644 index 0000000..c9b128e --- /dev/null +++ b/src/test/resources/regression/01/05.cql @@ -0,0 +1 @@ +"" \ No newline at end of file diff --git a/src/test/resources/regression/01/05.xcql b/src/test/resources/regression/01/05.xcql new file mode 100644 index 0000000..6ec410e --- /dev/null +++ b/src/test/resources/regression/01/05.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + <xml:element> + diff --git a/src/test/resources/regression/01/06.cql b/src/test/resources/regression/01/06.cql new file mode 100644 index 0000000..79b87e7 --- /dev/null +++ b/src/test/resources/regression/01/06.cql @@ -0,0 +1 @@ +"=" \ No newline at end of file diff --git a/src/test/resources/regression/01/06.xcql b/src/test/resources/regression/01/06.xcql new file mode 100644 index 0000000..da69755 --- /dev/null +++ b/src/test/resources/regression/01/06.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + = + diff --git a/src/test/resources/regression/01/07.cql b/src/test/resources/regression/01/07.cql new file mode 100644 index 0000000..34442aa --- /dev/null +++ b/src/test/resources/regression/01/07.cql @@ -0,0 +1 @@ +"prox/distance<3/unit=word" \ No newline at end of file diff --git a/src/test/resources/regression/01/07.xcql b/src/test/resources/regression/01/07.xcql new file mode 100644 index 0000000..851a5c1 --- /dev/null +++ b/src/test/resources/regression/01/07.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + prox/distance<3/unit=word + diff --git a/src/test/resources/regression/01/08.cql b/src/test/resources/regression/01/08.cql new file mode 100644 index 0000000..f6f67a9 --- /dev/null +++ b/src/test/resources/regression/01/08.cql @@ -0,0 +1 @@ +("cat") \ No newline at end of file diff --git a/src/test/resources/regression/01/08.xcql b/src/test/resources/regression/01/08.xcql new file mode 100644 index 0000000..48aee99 --- /dev/null +++ b/src/test/resources/regression/01/08.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + cat + diff --git a/src/test/resources/regression/01/09.cql b/src/test/resources/regression/01/09.cql new file mode 100644 index 0000000..ab149fc --- /dev/null +++ b/src/test/resources/regression/01/09.cql @@ -0,0 +1 @@ +((dog)) \ No newline at end of file diff --git a/src/test/resources/regression/01/09.xcql b/src/test/resources/regression/01/09.xcql new file mode 100644 index 0000000..d41b39e --- /dev/null +++ b/src/test/resources/regression/01/09.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + dog + diff --git a/src/test/resources/regression/01/10.cql b/src/test/resources/regression/01/10.cql new file mode 100644 index 0000000..baa6044 --- /dev/null +++ b/src/test/resources/regression/01/10.cql @@ -0,0 +1 @@ +all \ No newline at end of file diff --git a/src/test/resources/regression/01/10.xcql b/src/test/resources/regression/01/10.xcql new file mode 100644 index 0000000..c5ac7f6 --- /dev/null +++ b/src/test/resources/regression/01/10.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + all + diff --git a/src/test/resources/regression/01/11.cql b/src/test/resources/regression/01/11.cql new file mode 100644 index 0000000..91c2bee --- /dev/null +++ b/src/test/resources/regression/01/11.cql @@ -0,0 +1 @@ +prox \ No newline at end of file diff --git a/src/test/resources/regression/01/11.xcql b/src/test/resources/regression/01/11.xcql new file mode 100644 index 0000000..88da9eb --- /dev/null +++ b/src/test/resources/regression/01/11.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + prox + diff --git a/src/test/resources/regression/01/name b/src/test/resources/regression/01/name new file mode 100644 index 0000000..dc563f2 --- /dev/null +++ b/src/test/resources/regression/01/name @@ -0,0 +1 @@ +Simple \ No newline at end of file diff --git a/src/test/resources/regression/02/01.cql b/src/test/resources/regression/02/01.cql new file mode 100644 index 0000000..fea9bed --- /dev/null +++ b/src/test/resources/regression/02/01.cql @@ -0,0 +1 @@ +title = "fish" \ No newline at end of file diff --git a/src/test/resources/regression/02/01.xcql b/src/test/resources/regression/02/01.xcql new file mode 100644 index 0000000..be3c9c1 --- /dev/null +++ b/src/test/resources/regression/02/01.xcql @@ -0,0 +1,7 @@ + + title + + = + + fish + diff --git a/src/test/resources/regression/02/02.cql b/src/test/resources/regression/02/02.cql new file mode 100644 index 0000000..2ae47ba --- /dev/null +++ b/src/test/resources/regression/02/02.cql @@ -0,0 +1 @@ +title == fish diff --git a/src/test/resources/regression/02/02.xcql b/src/test/resources/regression/02/02.xcql new file mode 100644 index 0000000..fd085e3 --- /dev/null +++ b/src/test/resources/regression/02/02.xcql @@ -0,0 +1,7 @@ + + title + + == + + fish + diff --git a/src/test/resources/regression/02/03.cql b/src/test/resources/regression/02/03.cql new file mode 100644 index 0000000..553d2b8 --- /dev/null +++ b/src/test/resources/regression/02/03.cql @@ -0,0 +1 @@ +title any fish \ No newline at end of file diff --git a/src/test/resources/regression/02/03.xcql b/src/test/resources/regression/02/03.xcql new file mode 100644 index 0000000..62521be --- /dev/null +++ b/src/test/resources/regression/02/03.xcql @@ -0,0 +1,7 @@ + + title + + any + + fish + diff --git a/src/test/resources/regression/02/04.cql b/src/test/resources/regression/02/04.cql new file mode 100644 index 0000000..f0f4f19 --- /dev/null +++ b/src/test/resources/regression/02/04.cql @@ -0,0 +1 @@ +title all fish \ No newline at end of file diff --git a/src/test/resources/regression/02/04.xcql b/src/test/resources/regression/02/04.xcql new file mode 100644 index 0000000..646c973 --- /dev/null +++ b/src/test/resources/regression/02/04.xcql @@ -0,0 +1,7 @@ + + title + + all + + fish + diff --git a/src/test/resources/regression/02/05.cql b/src/test/resources/regression/02/05.cql new file mode 100644 index 0000000..f20b1df --- /dev/null +++ b/src/test/resources/regression/02/05.cql @@ -0,0 +1 @@ +title > 9 \ No newline at end of file diff --git a/src/test/resources/regression/02/05.xcql b/src/test/resources/regression/02/05.xcql new file mode 100644 index 0000000..92411c4 --- /dev/null +++ b/src/test/resources/regression/02/05.xcql @@ -0,0 +1,7 @@ + + title + + > + + 9 + diff --git a/src/test/resources/regression/02/06.cql b/src/test/resources/regression/02/06.cql new file mode 100644 index 0000000..e081346 --- /dev/null +++ b/src/test/resources/regression/02/06.cql @@ -0,0 +1 @@ +title >= 23 \ No newline at end of file diff --git a/src/test/resources/regression/02/06.xcql b/src/test/resources/regression/02/06.xcql new file mode 100644 index 0000000..6702471 --- /dev/null +++ b/src/test/resources/regression/02/06.xcql @@ -0,0 +1,7 @@ + + title + + >= + + 23 + diff --git a/src/test/resources/regression/02/07.cql b/src/test/resources/regression/02/07.cql new file mode 100644 index 0000000..2c774e0 --- /dev/null +++ b/src/test/resources/regression/02/07.cql @@ -0,0 +1 @@ +dc.title any "fish chips" \ No newline at end of file diff --git a/src/test/resources/regression/02/07.xcql b/src/test/resources/regression/02/07.xcql new file mode 100644 index 0000000..ba4ac78 --- /dev/null +++ b/src/test/resources/regression/02/07.xcql @@ -0,0 +1,7 @@ + + dc.title + + any + + fish chips + diff --git a/src/test/resources/regression/02/08.cql b/src/test/resources/regression/02/08.cql new file mode 100644 index 0000000..acc6a7d --- /dev/null +++ b/src/test/resources/regression/02/08.cql @@ -0,0 +1 @@ +dc.title any/stem fish \ No newline at end of file diff --git a/src/test/resources/regression/02/08.xcql b/src/test/resources/regression/02/08.xcql new file mode 100644 index 0000000..1576778 --- /dev/null +++ b/src/test/resources/regression/02/08.xcql @@ -0,0 +1,12 @@ + + dc.title + + any + + + stem + + + + fish + diff --git a/src/test/resources/regression/02/09.cql b/src/test/resources/regression/02/09.cql new file mode 100644 index 0000000..fff4f2a --- /dev/null +++ b/src/test/resources/regression/02/09.cql @@ -0,0 +1 @@ +dc.fish all/stem/fuzzy "fish chips" \ No newline at end of file diff --git a/src/test/resources/regression/02/09.xcql b/src/test/resources/regression/02/09.xcql new file mode 100644 index 0000000..9f8abff --- /dev/null +++ b/src/test/resources/regression/02/09.xcql @@ -0,0 +1,15 @@ + + dc.fish + + all + + + stem + + + fuzzy + + + + fish chips + diff --git a/src/test/resources/regression/02/10.cql b/src/test/resources/regression/02/10.cql new file mode 100644 index 0000000..2723119 --- /dev/null +++ b/src/test/resources/regression/02/10.cql @@ -0,0 +1 @@ +(title any frog) \ No newline at end of file diff --git a/src/test/resources/regression/02/10.xcql b/src/test/resources/regression/02/10.xcql new file mode 100644 index 0000000..d7dfe7a --- /dev/null +++ b/src/test/resources/regression/02/10.xcql @@ -0,0 +1,7 @@ + + title + + any + + frog + diff --git a/src/test/resources/regression/02/11.cql b/src/test/resources/regression/02/11.cql new file mode 100644 index 0000000..7c42dc6 --- /dev/null +++ b/src/test/resources/regression/02/11.cql @@ -0,0 +1 @@ +((dc.title any/stem "frog pond")) \ No newline at end of file diff --git a/src/test/resources/regression/02/11.xcql b/src/test/resources/regression/02/11.xcql new file mode 100644 index 0000000..726a36e --- /dev/null +++ b/src/test/resources/regression/02/11.xcql @@ -0,0 +1,12 @@ + + dc.title + + any + + + stem + + + + frog pond + diff --git a/src/test/resources/regression/02/12.cql b/src/test/resources/regression/02/12.cql new file mode 100644 index 0000000..dd8106c --- /dev/null +++ b/src/test/resources/regression/02/12.cql @@ -0,0 +1 @@ +dc.title any "fish frog chicken" \ No newline at end of file diff --git a/src/test/resources/regression/02/12.xcql b/src/test/resources/regression/02/12.xcql new file mode 100644 index 0000000..b4bcf3b --- /dev/null +++ b/src/test/resources/regression/02/12.xcql @@ -0,0 +1,7 @@ + + dc.title + + any + + fish frog chicken + diff --git a/src/test/resources/regression/02/13.cql b/src/test/resources/regression/02/13.cql new file mode 100644 index 0000000..d290d65 --- /dev/null +++ b/src/test/resources/regression/02/13.cql @@ -0,0 +1 @@ +dc.title =/rel.algorithm=CORI squid \ No newline at end of file diff --git a/src/test/resources/regression/02/13.xcql b/src/test/resources/regression/02/13.xcql new file mode 100644 index 0000000..6f3c011 --- /dev/null +++ b/src/test/resources/regression/02/13.xcql @@ -0,0 +1,14 @@ + + dc.title + + = + + + rel.algorithm + = + CORI + + + + squid + diff --git a/src/test/resources/regression/02/14.cql b/src/test/resources/regression/02/14.cql new file mode 100644 index 0000000..58d2b9b --- /dev/null +++ b/src/test/resources/regression/02/14.cql @@ -0,0 +1 @@ +author any/f.foo/b.bar>1 "sanderson taylor" \ No newline at end of file diff --git a/src/test/resources/regression/02/14.xcql b/src/test/resources/regression/02/14.xcql new file mode 100644 index 0000000..c833d26 --- /dev/null +++ b/src/test/resources/regression/02/14.xcql @@ -0,0 +1,17 @@ + + author + + any + + + f.foo + + + b.bar + > + 1 + + + + sanderson taylor + diff --git a/src/test/resources/regression/02/15.cql b/src/test/resources/regression/02/15.cql new file mode 100644 index 0000000..c427e26 --- /dev/null +++ b/src/test/resources/regression/02/15.cql @@ -0,0 +1 @@ +numberOfLegs <= 4 \ No newline at end of file diff --git a/src/test/resources/regression/02/15.xcql b/src/test/resources/regression/02/15.xcql new file mode 100644 index 0000000..3a23abe --- /dev/null +++ b/src/test/resources/regression/02/15.xcql @@ -0,0 +1,7 @@ + + numberOfLegs + + <= + + 4 + diff --git a/src/test/resources/regression/02/16.cql b/src/test/resources/regression/02/16.cql new file mode 100644 index 0000000..eb65cd2 --- /dev/null +++ b/src/test/resources/regression/02/16.cql @@ -0,0 +1 @@ +numberOfLegs <> 4 \ No newline at end of file diff --git a/src/test/resources/regression/02/16.xcql b/src/test/resources/regression/02/16.xcql new file mode 100644 index 0000000..0e8eccd --- /dev/null +++ b/src/test/resources/regression/02/16.xcql @@ -0,0 +1,7 @@ + + numberOfLegs + + <> + + 4 + diff --git a/src/test/resources/regression/02/17.cql b/src/test/resources/regression/02/17.cql new file mode 100644 index 0000000..2249148 --- /dev/null +++ b/src/test/resources/regression/02/17.cql @@ -0,0 +1 @@ +title == jaws \ No newline at end of file diff --git a/src/test/resources/regression/02/17.xcql b/src/test/resources/regression/02/17.xcql new file mode 100644 index 0000000..b2587ff --- /dev/null +++ b/src/test/resources/regression/02/17.xcql @@ -0,0 +1,7 @@ + + title + + == + + jaws + diff --git a/src/test/resources/regression/02/name b/src/test/resources/regression/02/name new file mode 100644 index 0000000..d9e175e --- /dev/null +++ b/src/test/resources/regression/02/name @@ -0,0 +1 @@ +Index Relation Term \ No newline at end of file diff --git a/src/test/resources/regression/03/01.cql b/src/test/resources/regression/03/01.cql new file mode 100644 index 0000000..a47d816 --- /dev/null +++ b/src/test/resources/regression/03/01.cql @@ -0,0 +1 @@ +cat or dog \ No newline at end of file diff --git a/src/test/resources/regression/03/01.xcql b/src/test/resources/regression/03/01.xcql new file mode 100644 index 0000000..fc1b678 --- /dev/null +++ b/src/test/resources/regression/03/01.xcql @@ -0,0 +1,23 @@ + + + or + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + dog + + + diff --git a/src/test/resources/regression/03/02.cql b/src/test/resources/regression/03/02.cql new file mode 100644 index 0000000..7bfe969 --- /dev/null +++ b/src/test/resources/regression/03/02.cql @@ -0,0 +1 @@ +cat and fish \ No newline at end of file diff --git a/src/test/resources/regression/03/02.xcql b/src/test/resources/regression/03/02.xcql new file mode 100644 index 0000000..55ae66a --- /dev/null +++ b/src/test/resources/regression/03/02.xcql @@ -0,0 +1,23 @@ + + + and + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + fish + + + diff --git a/src/test/resources/regression/03/03.cql b/src/test/resources/regression/03/03.cql new file mode 100644 index 0000000..28e500a --- /dev/null +++ b/src/test/resources/regression/03/03.cql @@ -0,0 +1 @@ +cat not frog \ No newline at end of file diff --git a/src/test/resources/regression/03/03.xcql b/src/test/resources/regression/03/03.xcql new file mode 100644 index 0000000..2f4f6c0 --- /dev/null +++ b/src/test/resources/regression/03/03.xcql @@ -0,0 +1,23 @@ + + + not + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + frog + + + diff --git a/src/test/resources/regression/03/04.cql b/src/test/resources/regression/03/04.cql new file mode 100644 index 0000000..eb88011 --- /dev/null +++ b/src/test/resources/regression/03/04.cql @@ -0,0 +1 @@ +(cat not frog) \ No newline at end of file diff --git a/src/test/resources/regression/03/04.xcql b/src/test/resources/regression/03/04.xcql new file mode 100644 index 0000000..2f4f6c0 --- /dev/null +++ b/src/test/resources/regression/03/04.xcql @@ -0,0 +1,23 @@ + + + not + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + frog + + + diff --git a/src/test/resources/regression/03/05.cql b/src/test/resources/regression/03/05.cql new file mode 100644 index 0000000..436176b --- /dev/null +++ b/src/test/resources/regression/03/05.cql @@ -0,0 +1 @@ +"cat" not "fish food" \ No newline at end of file diff --git a/src/test/resources/regression/03/05.xcql b/src/test/resources/regression/03/05.xcql new file mode 100644 index 0000000..9ad0700 --- /dev/null +++ b/src/test/resources/regression/03/05.xcql @@ -0,0 +1,23 @@ + + + not + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + fish food + + + diff --git a/src/test/resources/regression/03/06.cql b/src/test/resources/regression/03/06.cql new file mode 100644 index 0000000..9c30208 --- /dev/null +++ b/src/test/resources/regression/03/06.cql @@ -0,0 +1 @@ +xml and "prox///" \ No newline at end of file diff --git a/src/test/resources/regression/03/06.xcql b/src/test/resources/regression/03/06.xcql new file mode 100644 index 0000000..7b8dae8 --- /dev/null +++ b/src/test/resources/regression/03/06.xcql @@ -0,0 +1,23 @@ + + + and + + + + cql.serverChoice + + = + + xml + + + + + cql.serverChoice + + = + + prox/// + + + diff --git a/src/test/resources/regression/03/07.cql b/src/test/resources/regression/03/07.cql new file mode 100644 index 0000000..1c01ad9 --- /dev/null +++ b/src/test/resources/regression/03/07.cql @@ -0,0 +1 @@ +fred and any \ No newline at end of file diff --git a/src/test/resources/regression/03/07.xcql b/src/test/resources/regression/03/07.xcql new file mode 100644 index 0000000..5e0076e --- /dev/null +++ b/src/test/resources/regression/03/07.xcql @@ -0,0 +1,23 @@ + + + and + + + + cql.serverChoice + + = + + fred + + + + + cql.serverChoice + + = + + any + + + diff --git a/src/test/resources/regression/03/08.cql b/src/test/resources/regression/03/08.cql new file mode 100644 index 0000000..f37768b --- /dev/null +++ b/src/test/resources/regression/03/08.cql @@ -0,0 +1 @@ +((fred or all)) \ No newline at end of file diff --git a/src/test/resources/regression/03/08.xcql b/src/test/resources/regression/03/08.xcql new file mode 100644 index 0000000..f080d4b --- /dev/null +++ b/src/test/resources/regression/03/08.xcql @@ -0,0 +1,23 @@ + + + or + + + + cql.serverChoice + + = + + fred + + + + + cql.serverChoice + + = + + all + + + diff --git a/src/test/resources/regression/03/09.cql b/src/test/resources/regression/03/09.cql new file mode 100644 index 0000000..545400b --- /dev/null +++ b/src/test/resources/regression/03/09.cql @@ -0,0 +1 @@ +a or b and c not d \ No newline at end of file diff --git a/src/test/resources/regression/03/09.xcql b/src/test/resources/regression/03/09.xcql new file mode 100644 index 0000000..4f3ade7 --- /dev/null +++ b/src/test/resources/regression/03/09.xcql @@ -0,0 +1,55 @@ + + + not + + + + + and + + + + + or + + + + cql.serverChoice + + = + + a + + + + + cql.serverChoice + + = + + b + + + + + + + cql.serverChoice + + = + + c + + + + + + + cql.serverChoice + + = + + d + + + diff --git a/src/test/resources/regression/03/name b/src/test/resources/regression/03/name new file mode 100644 index 0000000..7dd2e3d --- /dev/null +++ b/src/test/resources/regression/03/name @@ -0,0 +1 @@ +Simple Boolean \ No newline at end of file diff --git a/src/test/resources/regression/04/01.cql b/src/test/resources/regression/04/01.cql new file mode 100644 index 0000000..046c5e4 --- /dev/null +++ b/src/test/resources/regression/04/01.cql @@ -0,0 +1 @@ +bath.author any fish and dc.title all "cat dog" \ No newline at end of file diff --git a/src/test/resources/regression/04/01.xcql b/src/test/resources/regression/04/01.xcql new file mode 100644 index 0000000..6f3ec27 --- /dev/null +++ b/src/test/resources/regression/04/01.xcql @@ -0,0 +1,23 @@ + + + and + + + + bath.author + + any + + fish + + + + + dc.title + + all + + cat dog + + + diff --git a/src/test/resources/regression/04/02.cql b/src/test/resources/regression/04/02.cql new file mode 100644 index 0000000..f8372df --- /dev/null +++ b/src/test/resources/regression/04/02.cql @@ -0,0 +1 @@ +(title any/stem "fish dog" or and) \ No newline at end of file diff --git a/src/test/resources/regression/04/02.xcql b/src/test/resources/regression/04/02.xcql new file mode 100644 index 0000000..0dcb869 --- /dev/null +++ b/src/test/resources/regression/04/02.xcql @@ -0,0 +1,28 @@ + + + or + + + + title + + any + + + stem + + + + fish dog + + + + + cql.serverChoice + + = + + and + + + diff --git a/src/test/resources/regression/04/name b/src/test/resources/regression/04/name new file mode 100644 index 0000000..9bafd2c --- /dev/null +++ b/src/test/resources/regression/04/name @@ -0,0 +1 @@ +I/R/T plus Boolean \ No newline at end of file diff --git a/src/test/resources/regression/05/01.cql b/src/test/resources/regression/05/01.cql new file mode 100644 index 0000000..18c09ef --- /dev/null +++ b/src/test/resources/regression/05/01.cql @@ -0,0 +1 @@ +cat prox hat \ No newline at end of file diff --git a/src/test/resources/regression/05/01.xcql b/src/test/resources/regression/05/01.xcql new file mode 100644 index 0000000..406d103 --- /dev/null +++ b/src/test/resources/regression/05/01.xcql @@ -0,0 +1,23 @@ + + + prox + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + hat + + + diff --git a/src/test/resources/regression/05/02.cql b/src/test/resources/regression/05/02.cql new file mode 100644 index 0000000..aa05edd --- /dev/null +++ b/src/test/resources/regression/05/02.cql @@ -0,0 +1 @@ +cat prox/distance=3/unit=word/ordered hat \ No newline at end of file diff --git a/src/test/resources/regression/05/02.xcql b/src/test/resources/regression/05/02.xcql new file mode 100644 index 0000000..f09ab0b --- /dev/null +++ b/src/test/resources/regression/05/02.xcql @@ -0,0 +1,38 @@ + + + prox + + + distance + = + 3 + + + unit + = + word + + + ordered + + + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + hat + + + diff --git a/src/test/resources/regression/05/03.cql b/src/test/resources/regression/05/03.cql new file mode 100644 index 0000000..13a0574 --- /dev/null +++ b/src/test/resources/regression/05/03.cql @@ -0,0 +1 @@ +cat prox/distance<3 hat \ No newline at end of file diff --git a/src/test/resources/regression/05/03.xcql b/src/test/resources/regression/05/03.xcql new file mode 100644 index 0000000..25c5377 --- /dev/null +++ b/src/test/resources/regression/05/03.xcql @@ -0,0 +1,30 @@ + + + prox + + + distance + < + 3 + + + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + hat + + + diff --git a/src/test/resources/regression/05/04.cql b/src/test/resources/regression/05/04.cql new file mode 100644 index 0000000..53ca6c8 --- /dev/null +++ b/src/test/resources/regression/05/04.cql @@ -0,0 +1 @@ +"fish food" prox/unit=sentence and \ No newline at end of file diff --git a/src/test/resources/regression/05/04.xcql b/src/test/resources/regression/05/04.xcql new file mode 100644 index 0000000..a6e2198 --- /dev/null +++ b/src/test/resources/regression/05/04.xcql @@ -0,0 +1,30 @@ + + + prox + + + unit + = + sentence + + + + + + cql.serverChoice + + = + + fish food + + + + + cql.serverChoice + + = + + and + + + diff --git a/src/test/resources/regression/05/05.cql b/src/test/resources/regression/05/05.cql new file mode 100644 index 0000000..18d574d --- /dev/null +++ b/src/test/resources/regression/05/05.cql @@ -0,0 +1 @@ +title all "chips frog" prox/distance<=5 exact \ No newline at end of file diff --git a/src/test/resources/regression/05/05.xcql b/src/test/resources/regression/05/05.xcql new file mode 100644 index 0000000..a59341f --- /dev/null +++ b/src/test/resources/regression/05/05.xcql @@ -0,0 +1,30 @@ + + + prox + + + distance + <= + 5 + + + + + + title + + all + + chips frog + + + + + cql.serverChoice + + = + + exact + + + diff --git a/src/test/resources/regression/05/06.cql b/src/test/resources/regression/05/06.cql new file mode 100644 index 0000000..e9ae9fd --- /dev/null +++ b/src/test/resources/regression/05/06.cql @@ -0,0 +1 @@ +(dc.author == "jones" prox/distance>5/unit=element title >= "smith") \ No newline at end of file diff --git a/src/test/resources/regression/05/06.xcql b/src/test/resources/regression/05/06.xcql new file mode 100644 index 0000000..4ffea29 --- /dev/null +++ b/src/test/resources/regression/05/06.xcql @@ -0,0 +1,35 @@ + + + prox + + + distance + > + 5 + + + unit + = + element + + + + + + dc.author + + == + + jones + + + + + title + + >= + + smith + + + diff --git a/src/test/resources/regression/05/07.cql b/src/test/resources/regression/05/07.cql new file mode 100644 index 0000000..fb65e0f --- /dev/null +++ b/src/test/resources/regression/05/07.cql @@ -0,0 +1 @@ +((cat prox hat)) \ No newline at end of file diff --git a/src/test/resources/regression/05/07.xcql b/src/test/resources/regression/05/07.xcql new file mode 100644 index 0000000..406d103 --- /dev/null +++ b/src/test/resources/regression/05/07.xcql @@ -0,0 +1,23 @@ + + + prox + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + hat + + + diff --git a/src/test/resources/regression/05/08.cql b/src/test/resources/regression/05/08.cql new file mode 100644 index 0000000..24a51b2 --- /dev/null +++ b/src/test/resources/regression/05/08.cql @@ -0,0 +1 @@ +a and/rel.SumOfScores b \ No newline at end of file diff --git a/src/test/resources/regression/05/08.xcql b/src/test/resources/regression/05/08.xcql new file mode 100644 index 0000000..b46dcfd --- /dev/null +++ b/src/test/resources/regression/05/08.xcql @@ -0,0 +1,28 @@ + + + and + + + rel.sumofscores + + + + + + cql.serverChoice + + = + + a + + + + + cql.serverChoice + + = + + b + + + diff --git a/src/test/resources/regression/05/09.cql b/src/test/resources/regression/05/09.cql new file mode 100644 index 0000000..2cd14ce --- /dev/null +++ b/src/test/resources/regression/05/09.cql @@ -0,0 +1 @@ +a and/rel.algorithm=CORI b \ No newline at end of file diff --git a/src/test/resources/regression/05/09.xcql b/src/test/resources/regression/05/09.xcql new file mode 100644 index 0000000..1dc3602 --- /dev/null +++ b/src/test/resources/regression/05/09.xcql @@ -0,0 +1,30 @@ + + + and + + + rel.algorithm + = + CORI + + + + + + cql.serverChoice + + = + + a + + + + + cql.serverChoice + + = + + b + + + diff --git a/src/test/resources/regression/05/name b/src/test/resources/regression/05/name new file mode 100644 index 0000000..4c6e65c --- /dev/null +++ b/src/test/resources/regression/05/name @@ -0,0 +1 @@ +Prox \ No newline at end of file diff --git a/src/test/resources/regression/06/01.cql b/src/test/resources/regression/06/01.cql new file mode 100644 index 0000000..b428b8f --- /dev/null +++ b/src/test/resources/regression/06/01.cql @@ -0,0 +1 @@ +(cat^) \ No newline at end of file diff --git a/src/test/resources/regression/06/01.xcql b/src/test/resources/regression/06/01.xcql new file mode 100644 index 0000000..0dcc5fb --- /dev/null +++ b/src/test/resources/regression/06/01.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + cat^ + diff --git a/src/test/resources/regression/06/02.cql b/src/test/resources/regression/06/02.cql new file mode 100644 index 0000000..d579091 --- /dev/null +++ b/src/test/resources/regression/06/02.cql @@ -0,0 +1 @@ +"cat" \ No newline at end of file diff --git a/src/test/resources/regression/06/02.xcql b/src/test/resources/regression/06/02.xcql new file mode 100644 index 0000000..48aee99 --- /dev/null +++ b/src/test/resources/regression/06/02.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + cat + diff --git a/src/test/resources/regression/06/03.cql b/src/test/resources/regression/06/03.cql new file mode 100644 index 0000000..d482955 --- /dev/null +++ b/src/test/resources/regression/06/03.cql @@ -0,0 +1 @@ +"^cat says \"fish\"" \ No newline at end of file diff --git a/src/test/resources/regression/06/03.xcql b/src/test/resources/regression/06/03.xcql new file mode 100644 index 0000000..9db40ae --- /dev/null +++ b/src/test/resources/regression/06/03.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + ^cat says "fish" + diff --git a/src/test/resources/regression/06/04.cql b/src/test/resources/regression/06/04.cql new file mode 100644 index 0000000..ce842d2 --- /dev/null +++ b/src/test/resources/regression/06/04.cql @@ -0,0 +1 @@ +"cat*fish" \ No newline at end of file diff --git a/src/test/resources/regression/06/04.xcql b/src/test/resources/regression/06/04.xcql new file mode 100644 index 0000000..ee38b0e --- /dev/null +++ b/src/test/resources/regression/06/04.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + cat*fish + diff --git a/src/test/resources/regression/06/05.cql b/src/test/resources/regression/06/05.cql new file mode 100644 index 0000000..21ad338 --- /dev/null +++ b/src/test/resources/regression/06/05.cql @@ -0,0 +1 @@ +cat?dog \ No newline at end of file diff --git a/src/test/resources/regression/06/05.xcql b/src/test/resources/regression/06/05.xcql new file mode 100644 index 0000000..dc59539 --- /dev/null +++ b/src/test/resources/regression/06/05.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + cat?dog + diff --git a/src/test/resources/regression/06/06.cql b/src/test/resources/regression/06/06.cql new file mode 100644 index 0000000..0cfced3 --- /dev/null +++ b/src/test/resources/regression/06/06.cql @@ -0,0 +1 @@ +(("^cat*fishdog\"horse?")) \ No newline at end of file diff --git a/src/test/resources/regression/06/06.xcql b/src/test/resources/regression/06/06.xcql new file mode 100644 index 0000000..9d38695 --- /dev/null +++ b/src/test/resources/regression/06/06.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + ^cat*fishdog"horse? + diff --git a/src/test/resources/regression/06/name b/src/test/resources/regression/06/name new file mode 100644 index 0000000..6e12768 --- /dev/null +++ b/src/test/resources/regression/06/name @@ -0,0 +1 @@ +Special Characters \ No newline at end of file diff --git a/src/test/resources/regression/07/01.cql b/src/test/resources/regression/07/01.cql new file mode 100644 index 0000000..2e2ea08 --- /dev/null +++ b/src/test/resources/regression/07/01.cql @@ -0,0 +1 @@ +(((cat or dog) or horse) and frog) \ No newline at end of file diff --git a/src/test/resources/regression/07/01.xcql b/src/test/resources/regression/07/01.xcql new file mode 100644 index 0000000..3338a9f --- /dev/null +++ b/src/test/resources/regression/07/01.xcql @@ -0,0 +1,55 @@ + + + and + + + + + or + + + + + or + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + dog + + + + + + + cql.serverChoice + + = + + horse + + + + + + + cql.serverChoice + + = + + frog + + + diff --git a/src/test/resources/regression/07/02.cql b/src/test/resources/regression/07/02.cql new file mode 100644 index 0000000..ce2ba87 --- /dev/null +++ b/src/test/resources/regression/07/02.cql @@ -0,0 +1 @@ +(cat and dog) or (horse and frog) \ No newline at end of file diff --git a/src/test/resources/regression/07/02.xcql b/src/test/resources/regression/07/02.xcql new file mode 100644 index 0000000..1324889 --- /dev/null +++ b/src/test/resources/regression/07/02.xcql @@ -0,0 +1,55 @@ + + + or + + + + + and + + + + cql.serverChoice + + = + + cat + + + + + cql.serverChoice + + = + + dog + + + + + + + + and + + + + cql.serverChoice + + = + + horse + + + + + cql.serverChoice + + = + + frog + + + + + diff --git a/src/test/resources/regression/07/03.cql b/src/test/resources/regression/07/03.cql new file mode 100644 index 0000000..99d3e25 --- /dev/null +++ b/src/test/resources/regression/07/03.cql @@ -0,0 +1 @@ +(cat and (horse or frog)) and chips \ No newline at end of file diff --git a/src/test/resources/regression/07/03.xcql b/src/test/resources/regression/07/03.xcql new file mode 100644 index 0000000..202af98 --- /dev/null +++ b/src/test/resources/regression/07/03.xcql @@ -0,0 +1,55 @@ + + + and + + + + + and + + + + cql.serverChoice + + = + + cat + + + + + + or + + + + cql.serverChoice + + = + + horse + + + + + cql.serverChoice + + = + + frog + + + + + + + + + cql.serverChoice + + = + + chips + + + diff --git a/src/test/resources/regression/07/name b/src/test/resources/regression/07/name new file mode 100644 index 0000000..b8a913e --- /dev/null +++ b/src/test/resources/regression/07/name @@ -0,0 +1 @@ +Nesting Parentheses \ No newline at end of file diff --git a/src/test/resources/regression/08/01.cql b/src/test/resources/regression/08/01.cql new file mode 100644 index 0000000..665568f --- /dev/null +++ b/src/test/resources/regression/08/01.cql @@ -0,0 +1 @@ +> foo="http://www.loc.gov/zing/cql/dc-indexes/" dc.title="fish" \ No newline at end of file diff --git a/src/test/resources/regression/08/01.xcql b/src/test/resources/regression/08/01.xcql new file mode 100644 index 0000000..4e2d548 --- /dev/null +++ b/src/test/resources/regression/08/01.xcql @@ -0,0 +1,13 @@ + + + + foo + http://www.loc.gov/zing/cql/dc-indexes/ + + + dc.title + + = + + fish + diff --git a/src/test/resources/regression/08/02.cql b/src/test/resources/regression/08/02.cql new file mode 100644 index 0000000..f5bf9b0 --- /dev/null +++ b/src/test/resources/regression/08/02.cql @@ -0,0 +1 @@ +> "http://www.loc.gov/zing/cql/dc-indexes/" title="fish" \ No newline at end of file diff --git a/src/test/resources/regression/08/02.xcql b/src/test/resources/regression/08/02.xcql new file mode 100644 index 0000000..63ce6ad --- /dev/null +++ b/src/test/resources/regression/08/02.xcql @@ -0,0 +1,12 @@ + + + + http://www.loc.gov/zing/cql/dc-indexes/ + + + title + + = + + fish + diff --git a/src/test/resources/regression/08/03.cql b/src/test/resources/regression/08/03.cql new file mode 100644 index 0000000..f75c2fc --- /dev/null +++ b/src/test/resources/regression/08/03.cql @@ -0,0 +1 @@ +> foo="http://www.loc.gov/zing/cql/dc-indexes" > ccg = "http://srw.o-r-g.org/cql/indexSets/ccg/" foo.title="fish" and ccg.force=3 \ No newline at end of file diff --git a/src/test/resources/regression/08/03.xcql b/src/test/resources/regression/08/03.xcql new file mode 100644 index 0000000..025c7c9 --- /dev/null +++ b/src/test/resources/regression/08/03.xcql @@ -0,0 +1,33 @@ + + + + foo + http://www.loc.gov/zing/cql/dc-indexes + + + ccg + http://srw.o-r-g.org/cql/indexSets/ccg/ + + + + and + + + + foo.title + + = + + fish + + + + + ccg.force + + = + + 3 + + + diff --git a/src/test/resources/regression/08/name b/src/test/resources/regression/08/name new file mode 100644 index 0000000..d37a456 --- /dev/null +++ b/src/test/resources/regression/08/name @@ -0,0 +1 @@ +Prefix Maps \ No newline at end of file diff --git a/src/test/resources/regression/09/01.cql b/src/test/resources/regression/09/01.cql new file mode 100644 index 0000000..cda5565 --- /dev/null +++ b/src/test/resources/regression/09/01.cql @@ -0,0 +1 @@ +any or all:stem and all contains any prox proxfuzzy \ No newline at end of file diff --git a/src/test/resources/regression/09/01.xcql b/src/test/resources/regression/09/01.xcql new file mode 100644 index 0000000..f721ed0 --- /dev/null +++ b/src/test/resources/regression/09/01.xcql @@ -0,0 +1,39 @@ + + + and + + + + + or + + + + cql.serverChoice + + = + + any + + + + + cql.serverChoice + + = + + all:stem + + + + + + + all contains + + any + + prox proxfuzzy + + + diff --git a/src/test/resources/regression/09/02.cql b/src/test/resources/regression/09/02.cql new file mode 100644 index 0000000..3026808 --- /dev/null +++ b/src/test/resources/regression/09/02.cql @@ -0,0 +1 @@ +(((((((((any))))))))) \ No newline at end of file diff --git a/src/test/resources/regression/09/02.xcql b/src/test/resources/regression/09/02.xcql new file mode 100644 index 0000000..dd7c8f0 --- /dev/null +++ b/src/test/resources/regression/09/02.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + any + diff --git a/src/test/resources/regression/09/03.cql b/src/test/resources/regression/09/03.cql new file mode 100644 index 0000000..3cc762b --- /dev/null +++ b/src/test/resources/regression/09/03.cql @@ -0,0 +1 @@ +"" \ No newline at end of file diff --git a/src/test/resources/regression/09/03.xcql b/src/test/resources/regression/09/03.xcql new file mode 100644 index 0000000..1eeff16 --- /dev/null +++ b/src/test/resources/regression/09/03.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + + diff --git a/src/test/resources/regression/09/04.cql b/src/test/resources/regression/09/04.cql new file mode 100644 index 0000000..d2fba11 --- /dev/null +++ b/src/test/resources/regression/09/04.cql @@ -0,0 +1 @@ +> any > any = exact any > any \ No newline at end of file diff --git a/src/test/resources/regression/09/04.xcql b/src/test/resources/regression/09/04.xcql new file mode 100644 index 0000000..aed8eca --- /dev/null +++ b/src/test/resources/regression/09/04.xcql @@ -0,0 +1,16 @@ + + + + any + + + any + exact + + + any + + > + + any + diff --git a/src/test/resources/regression/09/05.cql b/src/test/resources/regression/09/05.cql new file mode 100644 index 0000000..9fbc491 --- /dev/null +++ b/src/test/resources/regression/09/05.cql @@ -0,0 +1 @@ +sortby sortby sortby \ No newline at end of file diff --git a/src/test/resources/regression/09/05.xcql b/src/test/resources/regression/09/05.xcql new file mode 100644 index 0000000..578af0f --- /dev/null +++ b/src/test/resources/regression/09/05.xcql @@ -0,0 +1,12 @@ + + cql.serverChoice + + = + + sortby + + + sortby + + + diff --git a/src/test/resources/regression/09/06.cql b/src/test/resources/regression/09/06.cql new file mode 100644 index 0000000..c1c8282 --- /dev/null +++ b/src/test/resources/regression/09/06.cql @@ -0,0 +1 @@ +sortby sortby sortby sortby sortby \ No newline at end of file diff --git a/src/test/resources/regression/09/06.xcql b/src/test/resources/regression/09/06.xcql new file mode 100644 index 0000000..2e136b5 --- /dev/null +++ b/src/test/resources/regression/09/06.xcql @@ -0,0 +1,18 @@ + + cql.serverChoice + + = + + sortby + + + sortby + + + sortby + + + sortby + + + diff --git a/src/test/resources/regression/09/name b/src/test/resources/regression/09/name new file mode 100644 index 0000000..ed65cdb --- /dev/null +++ b/src/test/resources/regression/09/name @@ -0,0 +1 @@ +Lame Searches \ No newline at end of file diff --git a/src/test/resources/regression/10/01.cql b/src/test/resources/regression/10/01.cql new file mode 100644 index 0000000..c45d250 --- /dev/null +++ b/src/test/resources/regression/10/01.cql @@ -0,0 +1 @@ +kernighan sortby title \ No newline at end of file diff --git a/src/test/resources/regression/10/01.xcql b/src/test/resources/regression/10/01.xcql new file mode 100644 index 0000000..0c8cc74 --- /dev/null +++ b/src/test/resources/regression/10/01.xcql @@ -0,0 +1,12 @@ + + cql.serverChoice + + = + + kernighan + + + title + + + diff --git a/src/test/resources/regression/10/02.cql b/src/test/resources/regression/10/02.cql new file mode 100644 index 0000000..606ba50 --- /dev/null +++ b/src/test/resources/regression/10/02.cql @@ -0,0 +1 @@ +kernighan and ritchie sortby title \ No newline at end of file diff --git a/src/test/resources/regression/10/02.xcql b/src/test/resources/regression/10/02.xcql new file mode 100644 index 0000000..dbd6407 --- /dev/null +++ b/src/test/resources/regression/10/02.xcql @@ -0,0 +1,28 @@ + + + and + + + + cql.serverChoice + + = + + kernighan + + + + + cql.serverChoice + + = + + ritchie + + + + + title + + + diff --git a/src/test/resources/regression/10/03.cql b/src/test/resources/regression/10/03.cql new file mode 100644 index 0000000..beae0f5 --- /dev/null +++ b/src/test/resources/regression/10/03.cql @@ -0,0 +1 @@ +dc.creator=kernighan sortby dc.title \ No newline at end of file diff --git a/src/test/resources/regression/10/03.xcql b/src/test/resources/regression/10/03.xcql new file mode 100644 index 0000000..eaef782 --- /dev/null +++ b/src/test/resources/regression/10/03.xcql @@ -0,0 +1,12 @@ + + dc.creator + + = + + kernighan + + + dc.title + + + diff --git a/src/test/resources/regression/10/04.cql b/src/test/resources/regression/10/04.cql new file mode 100644 index 0000000..28ef4c4 --- /dev/null +++ b/src/test/resources/regression/10/04.cql @@ -0,0 +1 @@ +dc.creator=kernighan sortby numberOfLegs/cql.number \ No newline at end of file diff --git a/src/test/resources/regression/10/04.xcql b/src/test/resources/regression/10/04.xcql new file mode 100644 index 0000000..3a32884 --- /dev/null +++ b/src/test/resources/regression/10/04.xcql @@ -0,0 +1,17 @@ + + dc.creator + + = + + kernighan + + + numberOfLegs + + + cql.number + + + + + diff --git a/src/test/resources/regression/10/05.cql b/src/test/resources/regression/10/05.cql new file mode 100644 index 0000000..d263a12 --- /dev/null +++ b/src/test/resources/regression/10/05.cql @@ -0,0 +1 @@ +dc.creator=kernighan sortby dc.title/sort.respectCase \ No newline at end of file diff --git a/src/test/resources/regression/10/05.xcql b/src/test/resources/regression/10/05.xcql new file mode 100644 index 0000000..5821b04 --- /dev/null +++ b/src/test/resources/regression/10/05.xcql @@ -0,0 +1,17 @@ + + dc.creator + + = + + kernighan + + + dc.title + + + sort.respectcase + + + + + diff --git a/src/test/resources/regression/10/06.cql b/src/test/resources/regression/10/06.cql new file mode 100644 index 0000000..ead9f79 --- /dev/null +++ b/src/test/resources/regression/10/06.cql @@ -0,0 +1 @@ +dc.creator=kernighan sortby dc.title/sort.respectCase/sort.descending \ No newline at end of file diff --git a/src/test/resources/regression/10/06.xcql b/src/test/resources/regression/10/06.xcql new file mode 100644 index 0000000..8d232b2 --- /dev/null +++ b/src/test/resources/regression/10/06.xcql @@ -0,0 +1,20 @@ + + dc.creator + + = + + kernighan + + + dc.title + + + sort.respectcase + + + sort.descending + + + + + diff --git a/src/test/resources/regression/10/07.cql b/src/test/resources/regression/10/07.cql new file mode 100644 index 0000000..3495ee0 --- /dev/null +++ b/src/test/resources/regression/10/07.cql @@ -0,0 +1 @@ +dc.creator=kernighan sortby dc.date dc.title \ No newline at end of file diff --git a/src/test/resources/regression/10/07.xcql b/src/test/resources/regression/10/07.xcql new file mode 100644 index 0000000..13737ee --- /dev/null +++ b/src/test/resources/regression/10/07.xcql @@ -0,0 +1,15 @@ + + dc.creator + + = + + kernighan + + + dc.date + + + dc.title + + + diff --git a/src/test/resources/regression/10/08.cql b/src/test/resources/regression/10/08.cql new file mode 100644 index 0000000..27e5a1c --- /dev/null +++ b/src/test/resources/regression/10/08.cql @@ -0,0 +1 @@ +dc.creator=kernighan sortby dc.date/sort.missingOmit \ No newline at end of file diff --git a/src/test/resources/regression/10/08.xcql b/src/test/resources/regression/10/08.xcql new file mode 100644 index 0000000..bcf2a8f --- /dev/null +++ b/src/test/resources/regression/10/08.xcql @@ -0,0 +1,17 @@ + + dc.creator + + = + + kernighan + + + dc.date + + + sort.missingomit + + + + + diff --git a/src/test/resources/regression/10/09.cql b/src/test/resources/regression/10/09.cql new file mode 100644 index 0000000..fc41d84 --- /dev/null +++ b/src/test/resources/regression/10/09.cql @@ -0,0 +1 @@ +dc.creator=kernighan sortby dc.date/sort.missingValue=1970 \ No newline at end of file diff --git a/src/test/resources/regression/10/09.xcql b/src/test/resources/regression/10/09.xcql new file mode 100644 index 0000000..8a60d51 --- /dev/null +++ b/src/test/resources/regression/10/09.xcql @@ -0,0 +1,19 @@ + + dc.creator + + = + + kernighan + + + dc.date + + + sort.missingvalue + = + 1970 + + + + + diff --git a/src/test/resources/regression/10/10.cql b/src/test/resources/regression/10/10.cql new file mode 100644 index 0000000..1f9b830 --- /dev/null +++ b/src/test/resources/regression/10/10.cql @@ -0,0 +1 @@ +>dc="http://deepcustard.org/1.0" blah sortby dc.custardDepth \ No newline at end of file diff --git a/src/test/resources/regression/10/10.xcql b/src/test/resources/regression/10/10.xcql new file mode 100644 index 0000000..cb97df6 --- /dev/null +++ b/src/test/resources/regression/10/10.xcql @@ -0,0 +1,18 @@ + + + + dc + http://deepcustard.org/1.0 + + + cql.serverChoice + + = + + blah + + + dc.custardDepth + + + diff --git a/src/test/resources/regression/10/11.cql b/src/test/resources/regression/10/11.cql new file mode 100644 index 0000000..216ec56 --- /dev/null +++ b/src/test/resources/regression/10/11.cql @@ -0,0 +1 @@ +>ns1="http://uri1" >ns2="http://uri2" whatever sortby ns1.key/a/b/c=1 ns2.key2 \ No newline at end of file diff --git a/src/test/resources/regression/10/11.xcql b/src/test/resources/regression/10/11.xcql new file mode 100644 index 0000000..ba2abe7 --- /dev/null +++ b/src/test/resources/regression/10/11.xcql @@ -0,0 +1,38 @@ + + + + ns1 + http://uri1 + + + ns2 + http://uri2 + + + cql.serverChoice + + = + + whatever + + + ns1.key + + + a + + + b + + + c + = + 1 + + + + + ns2.key2 + + + diff --git a/src/test/resources/regression/10/12.cql b/src/test/resources/regression/10/12.cql new file mode 100644 index 0000000..e73b2f7 --- /dev/null +++ b/src/test/resources/regression/10/12.cql @@ -0,0 +1 @@ +(>dc=x b=c) sortby d \ No newline at end of file diff --git a/src/test/resources/regression/10/12.xcql b/src/test/resources/regression/10/12.xcql new file mode 100644 index 0000000..06b0ac2 --- /dev/null +++ b/src/test/resources/regression/10/12.xcql @@ -0,0 +1,18 @@ + + + + dc + x + + + b + + = + + c + + + d + + + diff --git a/src/test/resources/regression/10/13.cql b/src/test/resources/regression/10/13.cql new file mode 100644 index 0000000..60694b0 --- /dev/null +++ b/src/test/resources/regression/10/13.cql @@ -0,0 +1 @@ +b=(>dc=x c) sortby d \ No newline at end of file diff --git a/src/test/resources/regression/10/13.xcql b/src/test/resources/regression/10/13.xcql new file mode 100644 index 0000000..06b0ac2 --- /dev/null +++ b/src/test/resources/regression/10/13.xcql @@ -0,0 +1,18 @@ + + + + dc + x + + + b + + = + + c + + + d + + + diff --git a/src/test/resources/regression/10/14.cql b/src/test/resources/regression/10/14.cql new file mode 100644 index 0000000..5a6f6c5 --- /dev/null +++ b/src/test/resources/regression/10/14.cql @@ -0,0 +1 @@ +(>dc=x c1 and c2) sortby d \ No newline at end of file diff --git a/src/test/resources/regression/10/14.xcql b/src/test/resources/regression/10/14.xcql new file mode 100644 index 0000000..4f9f6d2 --- /dev/null +++ b/src/test/resources/regression/10/14.xcql @@ -0,0 +1,34 @@ + + + + dc + x + + + + and + + + + cql.serverChoice + + = + + c1 + + + + + cql.serverChoice + + = + + c2 + + + + + d + + + diff --git a/src/test/resources/regression/10/15.cql b/src/test/resources/regression/10/15.cql new file mode 100644 index 0000000..9931696 --- /dev/null +++ b/src/test/resources/regression/10/15.cql @@ -0,0 +1 @@ +>dc="http://deepcustard.org" (>dc="http://dublincore.org" dc.title=jaws) sortby dc.custardDepth \ No newline at end of file diff --git a/src/test/resources/regression/10/15.xcql b/src/test/resources/regression/10/15.xcql new file mode 100644 index 0000000..fb278bc --- /dev/null +++ b/src/test/resources/regression/10/15.xcql @@ -0,0 +1,22 @@ + + + + dc + http://deepcustard.org + + + dc + http://dublincore.org + + + dc.title + + = + + jaws + + + dc.custardDepth + + + diff --git a/src/test/resources/regression/10/16.cql b/src/test/resources/regression/10/16.cql new file mode 100644 index 0000000..eab4136 --- /dev/null +++ b/src/test/resources/regression/10/16.cql @@ -0,0 +1 @@ +>dc="http://deepcustard.org" (fish or >dc="http://dublincore.org" dc.title=jaws) sortby dc.custardDepth \ No newline at end of file diff --git a/src/test/resources/regression/10/16.xcql b/src/test/resources/regression/10/16.xcql new file mode 100644 index 0000000..42b01d6 --- /dev/null +++ b/src/test/resources/regression/10/16.xcql @@ -0,0 +1,40 @@ + + + + dc + http://deepcustard.org + + + + or + + + + cql.serverChoice + + = + + fish + + + + + + + dc + http://dublincore.org + + + dc.title + + = + + jaws + + + + + dc.custardDepth + + + diff --git a/src/test/resources/regression/10/name b/src/test/resources/regression/10/name new file mode 100644 index 0000000..02e6bb6 --- /dev/null +++ b/src/test/resources/regression/10/name @@ -0,0 +1 @@ +Sorting \ No newline at end of file From 07b6f6798434a0fa1d1d5d4e7e90ee76232ad9d3 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 14 Mar 2014 14:26:50 +0100 Subject: [PATCH 092/147] Clean-up, docs --- Build | 8 -------- bin/CQLGenerator | 5 ----- bin/CQLLexer | 5 ----- bin/CQLParser | 5 ----- etc/generate.properties | 10 ---------- .../java/org/z3950/zing/cql/CQLParserTest.java | 14 +++++++++++++- 6 files changed, 13 insertions(+), 34 deletions(-) delete mode 100755 Build delete mode 100755 bin/CQLGenerator delete mode 100755 bin/CQLLexer delete mode 100755 bin/CQLParser delete mode 100644 etc/generate.properties diff --git a/Build b/Build deleted file mode 100755 index 87facee..0000000 --- a/Build +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - - -: ${MAKE=make} -for dir in src/main/java/org/z3950/zing/cql test/regression docs; do - echo "=== Building in $dir ===" - ( cd $dir; $MAKE ${@+"$@"} ) -done diff --git a/bin/CQLGenerator b/bin/CQLGenerator deleted file mode 100755 index 55de086..0000000 --- a/bin/CQLGenerator +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# Trivial script to invoke the CQLGenerator test-harness - -java org.z3950.zing.cql.CQLGenerator ${@+"$@"} diff --git a/bin/CQLLexer b/bin/CQLLexer deleted file mode 100755 index c07e566..0000000 --- a/bin/CQLLexer +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# Trivial script to invoke the CQLLexer test-harness - -java org.z3950.zing.cql.CQLLexer ${@+"$@"} diff --git a/bin/CQLParser b/bin/CQLParser deleted file mode 100755 index 26a52b1..0000000 --- a/bin/CQLParser +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# Trivial script to invoke the CQLParser test-harness - -java org.z3950.zing.cql.CQLParser ${@+"$@"} diff --git a/etc/generate.properties b/etc/generate.properties deleted file mode 100644 index 409f872..0000000 --- a/etc/generate.properties +++ /dev/null @@ -1,10 +0,0 @@ -# -# Propeties file to drive the org.z3950.zing.cql.CQLGenerator -# test-harness. See that class's documentation for the semantics of -# these properties. -# -complexQuery=0.4 -complexClause=0.4 -equalsRelation=0.5 -numericRelation=0.7 -proxOp=0.0 diff --git a/src/test/java/org/z3950/zing/cql/CQLParserTest.java b/src/test/java/org/z3950/zing/cql/CQLParserTest.java index 7e258e0..61b112b 100644 --- a/src/test/java/org/z3950/zing/cql/CQLParserTest.java +++ b/src/test/java/org/z3950/zing/cql/CQLParserTest.java @@ -103,6 +103,19 @@ public void testRegressionQueries() throws IOException { } } + /** + * Test the integrity of the parser as follows: + * - Generate a random tree with CQLGenerator + * - Serialize it + * - Canonicalise it by running through the parser + * - Compare the before-and-after versions. + * Since the CQLGenerator output is in canonical form anyway, the + * before-and-after versions should be identical. This process exercises + * the comprehensiveness and bullet-proofing of the parser, as well as + * the accuracy of the rendering. + * @throws IOException + * @throws MissingParameterException + */ @Test public void testRandomQueries() throws IOException, MissingParameterException { out.println("Testing the parser using 100 randomly generated queries..."); @@ -128,7 +141,6 @@ public void testRandomQueries() throws IOException, MissingParameterException { } } - //helper methods follow //TODO move to masterkey-common From 56c5ab26a8d9cee0abc4083087a3ec17fdec907b Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 14 Mar 2014 15:04:39 +0100 Subject: [PATCH 093/147] Add tests for failures --- .../org/z3950/zing/cql/CQLParserTest.java | 35 +++++++++++-------- src/test/resources/regression/11/01.cql | 1 + src/test/resources/regression/11/01.xcql | 1 + src/test/resources/regression/11/02.cql | 1 + src/test/resources/regression/11/02.xcql | 1 + .../resources/regression/11/03.cql.disabled | 1 + .../resources/regression/11/04.cql.disabled | 1 + src/test/resources/regression/11/05.cql | 1 + src/test/resources/regression/11/05.xcql | 1 + src/test/resources/regression/11/06.cql | 1 + src/test/resources/regression/11/06.xcql | 1 + src/test/resources/regression/11/07.cql | 1 + src/test/resources/regression/11/07.xcql | 1 + src/test/resources/regression/11/08.cql | 1 + src/test/resources/regression/11/08.xcql | 1 + .../resources/regression/11/09.cql.disabled | 1 + .../resources/regression/11/10.cql.disabled | 1 + src/test/resources/regression/11/11.cql | 1 + src/test/resources/regression/11/11.xcql | 1 + src/test/resources/regression/11/12.cql | 1 + src/test/resources/regression/11/12.xcql | 29 +++++++++++++++ src/test/resources/regression/11/name | 1 + 22 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 src/test/resources/regression/11/01.cql create mode 100644 src/test/resources/regression/11/01.xcql create mode 100644 src/test/resources/regression/11/02.cql create mode 100644 src/test/resources/regression/11/02.xcql create mode 100644 src/test/resources/regression/11/03.cql.disabled create mode 100644 src/test/resources/regression/11/04.cql.disabled create mode 100644 src/test/resources/regression/11/05.cql create mode 100644 src/test/resources/regression/11/05.xcql create mode 100644 src/test/resources/regression/11/06.cql create mode 100644 src/test/resources/regression/11/06.xcql create mode 100644 src/test/resources/regression/11/07.cql create mode 100644 src/test/resources/regression/11/07.xcql create mode 100644 src/test/resources/regression/11/08.cql create mode 100644 src/test/resources/regression/11/08.xcql create mode 100644 src/test/resources/regression/11/09.cql.disabled create mode 100644 src/test/resources/regression/11/10.cql.disabled create mode 100644 src/test/resources/regression/11/11.cql create mode 100644 src/test/resources/regression/11/11.xcql create mode 100644 src/test/resources/regression/11/12.cql create mode 100644 src/test/resources/regression/11/12.xcql create mode 100644 src/test/resources/regression/11/name diff --git a/src/test/java/org/z3950/zing/cql/CQLParserTest.java b/src/test/java/org/z3950/zing/cql/CQLParserTest.java index 61b112b..2566e13 100644 --- a/src/test/java/org/z3950/zing/cql/CQLParserTest.java +++ b/src/test/java/org/z3950/zing/cql/CQLParserTest.java @@ -75,26 +75,33 @@ public void testRegressionQueries() throws IOException { reader = new BufferedReader(new InputStreamReader(is)); String input = reader.readLine(); out.println("Query: "+input); - CQLParser parser = new CQLParser(); - CQLNode parsed = parser.parse(input); - String xcql = parsed.toXCQL(); + String result; + try { + CQLParser parser = new CQLParser(); + CQLNode parsed = parser.parse(input); + result = parsed.toXCQL(); + } catch (CQLParseException pe) { + result = pe.getMessage() + "\n"; + } out.println("Parsed:"); - out.println(xcql); + out.println(result); //read the expected xcql output + String expected = ""; String prefix = file.substring(0, file.length()-4); - reader2 = new BufferedReader(new InputStreamReader( - this.getClass().getResourceAsStream("/regression/"+dir+"/"+prefix+".xcql"))); - StringBuilder sb = new StringBuilder(); - String line; - while ((line = reader2.readLine()) != null) { - sb.append(line).append("\n"); + InputStream is2 = this.getClass() + .getResourceAsStream("/regression/"+dir+"/"+prefix+".xcql"); + if (is2 != null) { + reader2 = new BufferedReader(new InputStreamReader(is2)); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader2.readLine()) != null) { + sb.append(line).append("\n"); + } + expected = sb.toString(); } - String expected = sb.toString(); out.println("Expected: "); out.println(expected); - assertEquals("Assertion failure for "+dir+"/"+file, expected, xcql); - } catch (CQLParseException pe) { - fail("Parsing failed with: "+pe.toString()); + assertEquals("Assertion failure for "+dir+"/"+file, expected, result); } finally { if (reader != null) reader.close(); if (reader2 != null) reader2.close(); diff --git a/src/test/resources/regression/11/01.cql b/src/test/resources/regression/11/01.cql new file mode 100644 index 0000000..5d56655 --- /dev/null +++ b/src/test/resources/regression/11/01.cql @@ -0,0 +1 @@ +cat or diff --git a/src/test/resources/regression/11/01.xcql b/src/test/resources/regression/11/01.xcql new file mode 100644 index 0000000..03b04df --- /dev/null +++ b/src/test/resources/regression/11/01.xcql @@ -0,0 +1 @@ +expected index or term, got EOF diff --git a/src/test/resources/regression/11/02.cql b/src/test/resources/regression/11/02.cql new file mode 100644 index 0000000..200021d --- /dev/null +++ b/src/test/resources/regression/11/02.cql @@ -0,0 +1 @@ +index any diff --git a/src/test/resources/regression/11/02.xcql b/src/test/resources/regression/11/02.xcql new file mode 100644 index 0000000..03b04df --- /dev/null +++ b/src/test/resources/regression/11/02.xcql @@ -0,0 +1 @@ +expected index or term, got EOF diff --git a/src/test/resources/regression/11/03.cql.disabled b/src/test/resources/regression/11/03.cql.disabled new file mode 100644 index 0000000..daf9170 --- /dev/null +++ b/src/test/resources/regression/11/03.cql.disabled @@ -0,0 +1 @@ +index any/wrong term diff --git a/src/test/resources/regression/11/04.cql.disabled b/src/test/resources/regression/11/04.cql.disabled new file mode 100644 index 0000000..d7a7241 --- /dev/null +++ b/src/test/resources/regression/11/04.cql.disabled @@ -0,0 +1 @@ +a prox/wrong b diff --git a/src/test/resources/regression/11/05.cql b/src/test/resources/regression/11/05.cql new file mode 100644 index 0000000..6a452c1 --- /dev/null +++ b/src/test/resources/regression/11/05.cql @@ -0,0 +1 @@ +() diff --git a/src/test/resources/regression/11/05.xcql b/src/test/resources/regression/11/05.xcql new file mode 100644 index 0000000..9acb4e1 --- /dev/null +++ b/src/test/resources/regression/11/05.xcql @@ -0,0 +1 @@ +expected index or term, got ')' diff --git a/src/test/resources/regression/11/06.cql b/src/test/resources/regression/11/06.cql new file mode 100644 index 0000000..96c10c2 --- /dev/null +++ b/src/test/resources/regression/11/06.cql @@ -0,0 +1 @@ +(a diff --git a/src/test/resources/regression/11/06.xcql b/src/test/resources/regression/11/06.xcql new file mode 100644 index 0000000..1a03f39 --- /dev/null +++ b/src/test/resources/regression/11/06.xcql @@ -0,0 +1 @@ +expected ')', got EOF diff --git a/src/test/resources/regression/11/07.cql b/src/test/resources/regression/11/07.cql new file mode 100644 index 0000000..31a777d --- /dev/null +++ b/src/test/resources/regression/11/07.cql @@ -0,0 +1 @@ +ndex any fish) diff --git a/src/test/resources/regression/11/07.xcql b/src/test/resources/regression/11/07.xcql new file mode 100644 index 0000000..ad3588c --- /dev/null +++ b/src/test/resources/regression/11/07.xcql @@ -0,0 +1 @@ +junk after end: ')' diff --git a/src/test/resources/regression/11/08.cql b/src/test/resources/regression/11/08.cql new file mode 100644 index 0000000..6eaf1dc --- /dev/null +++ b/src/test/resources/regression/11/08.cql @@ -0,0 +1 @@ +(cat any dog or ()) diff --git a/src/test/resources/regression/11/08.xcql b/src/test/resources/regression/11/08.xcql new file mode 100644 index 0000000..9acb4e1 --- /dev/null +++ b/src/test/resources/regression/11/08.xcql @@ -0,0 +1 @@ +expected index or term, got ')' diff --git a/src/test/resources/regression/11/09.cql.disabled b/src/test/resources/regression/11/09.cql.disabled new file mode 100644 index 0000000..ba04d90 --- /dev/null +++ b/src/test/resources/regression/11/09.cql.disabled @@ -0,0 +1 @@ +title = ("illegal parentheses") diff --git a/src/test/resources/regression/11/10.cql.disabled b/src/test/resources/regression/11/10.cql.disabled new file mode 100644 index 0000000..3381e47 --- /dev/null +++ b/src/test/resources/regression/11/10.cql.disabled @@ -0,0 +1 @@ +"quoted" any "illegal quotes" diff --git a/src/test/resources/regression/11/11.cql b/src/test/resources/regression/11/11.cql new file mode 100644 index 0000000..ab692e6 --- /dev/null +++ b/src/test/resources/regression/11/11.cql @@ -0,0 +1 @@ +> illegal="urn:missingQuery" diff --git a/src/test/resources/regression/11/11.xcql b/src/test/resources/regression/11/11.xcql new file mode 100644 index 0000000..03b04df --- /dev/null +++ b/src/test/resources/regression/11/11.xcql @@ -0,0 +1 @@ +expected index or term, got EOF diff --git a/src/test/resources/regression/11/12.cql b/src/test/resources/regression/11/12.cql new file mode 100644 index 0000000..fa804d8 --- /dev/null +++ b/src/test/resources/regression/11/12.cql @@ -0,0 +1 @@ +"fish" and > illegal="urn:invalidPrefixLocation" "chips" diff --git a/src/test/resources/regression/11/12.xcql b/src/test/resources/regression/11/12.xcql new file mode 100644 index 0000000..cfa7186 --- /dev/null +++ b/src/test/resources/regression/11/12.xcql @@ -0,0 +1,29 @@ + + + and + + + + cql.serverChoice + + = + + fish + + + + + + + illegal + urn:invalidPrefixLocation + + + cql.serverChoice + + = + + chips + + + diff --git a/src/test/resources/regression/11/name b/src/test/resources/regression/11/name new file mode 100644 index 0000000..2e6da96 --- /dev/null +++ b/src/test/resources/regression/11/name @@ -0,0 +1 @@ +FAILURES From 277aa21b21ccafbb392f58ba30390040bdb47c94 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 14 Mar 2014 17:19:54 +0100 Subject: [PATCH 094/147] Rewrite lexer to comply with CQL spec Add test more tests --- .../java/org/z3950/zing/cql/CQLLexer.java | 281 +++--------------- .../org/z3950/zing/cql/CQLLexerSimple.java | 173 +++++++++++ .../java/org/z3950/zing/cql/CQLParser.java | 162 +++++----- .../z3950/zing/cql/PositionAwareReader.java | 107 ------- src/test/resources/regression/12/01.cql | 1 + src/test/resources/regression/12/01.xcql | 7 + src/test/resources/regression/12/name | 1 + 7 files changed, 287 insertions(+), 445 deletions(-) create mode 100644 src/main/java/org/z3950/zing/cql/CQLLexerSimple.java delete mode 100644 src/main/java/org/z3950/zing/cql/PositionAwareReader.java create mode 100644 src/test/resources/regression/12/01.cql create mode 100644 src/test/resources/regression/12/01.xcql create mode 100644 src/test/resources/regression/12/name diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 293b45a..2247fd0 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -1,247 +1,40 @@ - +/* + * Copyright (c) 1995-2014, Index Datassss + * All rights reserved. + * See the file LICENSE for details. + */ package org.z3950.zing.cql; -import java.io.InputStream; -import java.io.Reader; -import java.io.StreamTokenizer; -import java.io.StringReader; - - -// This is a semi-trivial subclass for java.io.StreamTokenizer that: -// * Has a halfDecentPushBack() method that actually works -// * Includes a render() method -// * Knows about the multi-character tokens "<=", ">=" and "<>" -// * Recognises a set of keywords as tokens in their own right -// * Includes some primitive debugging-output facilities -// It's used only by CQLParser. -// -class CQLLexer extends StreamTokenizer { - // New publicly visible token-types - public final static int TT_LE = 1000; // The "<=" relation - public final static int TT_GE = 1001; // The ">=" relation - public final static int TT_NE = 1002; // The "<>" relation - public final static int TT_EQEQ = 1003; // The "==" relation - public final static int TT_AND = 1004; // The "and" boolean - public final static int TT_OR = 1005; // The "or" boolean - public final static int TT_NOT = 1006; // The "not" boolean - public final static int TT_PROX = 1007; // The "prox" boolean - public final static int TT_SORTBY = 1008; // The "sortby" operator - - // Support for keywords. It would be nice to compile this linear - // list into a Hashtable, but it's hard to store ints as hash - // values, and next to impossible to use them as hash keys. So - // we'll just scan the (very short) list every time we need to do - // a lookup. - private class Keyword { - int token; - String keyword; - Keyword(int token, String keyword) { - this.token = token; - this.keyword = keyword; - } - } - // This should logically be static, but Java won't allow it :-P - private Keyword[] keywords = { - new Keyword(TT_AND, "and"), - new Keyword(TT_OR, "or"), - new Keyword(TT_NOT, "not"), - new Keyword(TT_PROX, "prox"), - new Keyword(TT_SORTBY, "sortby"), - }; - - // For halfDecentPushBack() and the code at the top of nextToken() - private static int TT_UNDEFINED = -1000; - private int saved_ttype = TT_UNDEFINED; - private double saved_nval; - private String saved_sval; - - // Controls debugging output - private static boolean DEBUG; - - CQLLexer(String cql, boolean lexdebug) { - this(new StringReader(cql), lexdebug); - } - - CQLLexer(Reader cql, boolean lexdebug) { - super(cql); - wordChars('!', '@'); // ASCII-dependency! - wordChars('[', '`'); // ASCII-dependency! - quoteChar('"'); - ordinaryChar('='); - ordinaryChar('<'); - ordinaryChar('>'); - ordinaryChar('/'); - ordinaryChar('('); - ordinaryChar(')'); - ordinaryChar('.'); - wordChars('.', '.'); - wordChars('\'', '\''); // prevent this from introducing strings - //parseNumbers(); - ordinaryChar('-'); - wordChars('-', '-'); - ordinaryChars('0', '9'); - wordChars('0', '9'); - DEBUG = lexdebug; - } - - private static void debug(String str) { - if (DEBUG) - System.err.println("LEXDEBUG: " + str); - } - - // I don't honestly understand why we need this, but the - // documentation for java.io.StreamTokenizer.pushBack() is pretty - // vague about its semantics, and it seems to me that they could - // be summed up as "it doesn't work". This version has the very - // clear semantics "pretend I didn't call nextToken() just then". - // - private void halfDecentPushBack() { - saved_ttype = ttype; - saved_nval = nval; - saved_sval = sval; - } - - @Override - public int nextToken() throws java.io.IOException { - if (saved_ttype != TT_UNDEFINED) { - ttype = saved_ttype; - nval = saved_nval; - sval = saved_sval; - saved_ttype = TT_UNDEFINED; - debug("using saved ttype=" + ttype + ", " + - "nval=" + nval + ", sval='" + sval + "'"); - return ttype; - } - - underlyingNextToken(); - if (ttype == '<') { - debug("token starts with '<' ..."); - underlyingNextToken(); - if (ttype == '=') { - debug("token continues with '=' - it's '<='"); - ttype = TT_LE; - } else if (ttype == '>') { - debug("token continues with '>' - it's '<>'"); - ttype = TT_NE; - } else { - debug("next token is " + render() + " (pushed back)"); - halfDecentPushBack(); - ttype = '<'; - debug("AFTER: ttype is now " + ttype + " - " + render()); - } - } else if (ttype == '>') { - debug("token starts with '>' ..."); - underlyingNextToken(); - if (ttype == '=') { - debug("token continues with '=' - it's '>='"); - ttype = TT_GE; - } else { - debug("next token is " + render() + " (pushed back)"); - halfDecentPushBack(); - ttype = '>'; - debug("AFTER: ttype is now " + ttype + " - " + render()); - } - } else if (ttype == '=') { - debug("token starts with '=' ..."); - underlyingNextToken(); - if (ttype == '=') { - debug("token continues with '=' - it's '=='"); - ttype = TT_EQEQ; - } else { - debug("next token is " + render() + " (pushed back)"); - halfDecentPushBack(); - ttype = '='; - debug("AFTER: ttype is now " + ttype + " - " + render()); - } - } - - debug("done nextToken(): ttype=" + ttype + ", " + - "nval=" + nval + ", " + "sval='" + sval + "'" + - " (" + render() + ")"); - - return ttype; - } - - // It's important to do keyword recognition here at the lowest - // level, otherwise when one of these words follows "<" or ">" - // (which can be the beginning of multi-character tokens) it gets - // pushed back as a string, and its keywordiness is not - // recognised. - // - public int underlyingNextToken() throws java.io.IOException { - super.nextToken(); - if (ttype == TT_WORD) - for (int i = 0; i < keywords.length; i++) - if (sval.equalsIgnoreCase(keywords[i].keyword)) - ttype = keywords[i].token; - - return ttype; - } - - // Simpler interface for the usual case: current token with quoting - String render() { - return render(ttype, true); - } - - String render(int token, boolean quoteChars) { - if (token == TT_EOF) { - return "EOF"; - } else if (token == TT_NUMBER) { - if ((double) nval == (int) nval) { - return new Integer((int) nval).toString(); - } else { - return new Double((double) nval).toString(); - } - } else if (token == TT_WORD) { - return "word: " + sval; - } else if (token == '"') { - return "string: \"" + sval + "\""; - } else if (token == TT_LE) { - return "<="; - } else if (token == TT_GE) { - return ">="; - } else if (token == TT_NE) { - return "<>"; - } else if (token == TT_EQEQ) { - return "=="; - } - - // Check whether its associated with one of the keywords - for (int i = 0; i < keywords.length; i++) - if (token == keywords[i].token) - return keywords[i].keyword; - - // Otherwise it must be a single character, such as '(' or '/'. - String res = String.valueOf((char) token); - if (quoteChars) res = "'" + res + "'"; - return res; - } - - public static void main(String[] args) throws Exception { - if (args.length > 1) { - System.err.println("Usage: CQLLexer []"); - System.err.println("If unspecified, query is read from stdin"); - System.exit(1); - } - - String cql; - if (args.length == 1) { - cql = args[0]; - } else { - byte[] bytes = new byte[10000]; - try { - // Read in the whole of standard input in one go - int nbytes = System.in.read(bytes); - } catch (java.io.IOException ex) { - System.err.println("Can't read query: " + ex.getMessage()); - System.exit(2); - } - cql = new String(bytes); - } - CQLLexer lexer = new CQLLexer(cql, true); - int token; - while ((token = lexer.nextToken()) != TT_EOF) { - // Nothing to do: debug() statements render tokens for us - } - } +/** + * + * @author jakub + */ +public interface CQLLexer { + + public static final int TT_EOF = -1; + public static final int TT_WORD = -3; + public static final int TT_NOTHING = -4; + + public final static int TT_LE = 1000; // The "<=" relation + public final static int TT_GE = 1001; // The ">=" relation + public final static int TT_NE = 1002; // The "<>" relation + public final static int TT_EQEQ = 1003; // The "==" relation + public final static int TT_AND = 1004; // The "and" boolean + public final static int TT_OR = 1005; // The "or" boolean + public final static int TT_NOT = 1006; // The "not" boolean + public final static int TT_PROX = 1007; // The "prox" boolean + public final static int TT_SORTBY = 1008; // The "sortby" operator + + public void move(); + + public String value(); + + public int what(); + + public String render(); + + public String render(int what, boolean quote); + + public int pos(); + } diff --git a/src/main/java/org/z3950/zing/cql/CQLLexerSimple.java b/src/main/java/org/z3950/zing/cql/CQLLexerSimple.java new file mode 100644 index 0000000..80931cc --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/CQLLexerSimple.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 1995-2014, Index Datassss + * All rights reserved. + * See the file LICENSE for details. + */ +package org.z3950.zing.cql; + +/** + * + * @author jakub + */ +public class CQLLexerSimple implements CQLLexer { + private String qs; + private int qi; + private int ql; + private int what = TT_NOTHING; + private String val; + private String lval; + private StringBuilder buf = new StringBuilder(); + + public CQLLexerSimple(String cql, boolean debug) { + qs = cql; + ql = cql.length(); + } + + @Override + public void move() { + //eat whitespace + while (qi < ql && strchr(" \t\r\n", qs.charAt(qi))) + qi++; + //eof + if (qi == ql) { + what = TT_EOF; + return; + } + //current char + char c = qs.charAt(qi); + //separators + if (strchr("()/", c)) { + what = c; + qi++; + //comparitor + } else if (strchr("<>=", c)) { + what = c; + qi++; + //two-char comparitor + if (qi < ql) { + char d = qs.charAt(qi); + String comp = String.valueOf((char) c) + String.valueOf((char) d); + if (comp.equals("==")) { + what = TT_EQEQ; + qi++; + } + else if (comp.equals("<=")) { + what = TT_LE; + qi++; + } + else if (comp.equals(">=")) { + what = TT_GE; + qi++; + } + else if (comp.equals("<>")) { + what = TT_NE; + qi++; + } + } + //quoted string + } else if (strchr("\"", c)) { //no single-quotes + what = '"'; + //remember quote char + char mark = c; + qi++; + boolean escaped = false; + buf.setLength(0); //reset buffer + while (qi < ql) { + if (!escaped && qs.charAt(qi) == mark) //terminator + break; + if (escaped && strchr("*?^\\", qs.charAt(qi))) //no escaping for d-quote + buf.append("\\"); + if (!escaped && qs.charAt(qi) == '\\') { //escape-char + escaped = true; + qi++; + continue; + } + escaped = false; //reset escape + buf.append(qs.charAt(qi)); + qi++; + } + val = buf.toString(); + lval = val.toLowerCase(); + if (qi < ql) + qi++; + else //unterminated + what = TT_EOF; //notify error + //unquoted string + } else { + what = TT_WORD; + buf.setLength(0); //reset buffer + while (qi < ql + && !strchr("()/<>= \t\r\n", qs.charAt(qi))) { + buf.append(qs.charAt(qi)); + qi++; + } + val = buf.toString(); + lval = val.toLowerCase(); + if (lval.equals("or")) what = TT_OR; + else if (lval.equals("and")) what = TT_AND; + else if (lval.equals("not")) what = TT_NOT; + else if (lval.equals("prox")) what = TT_PROX; + else if (lval.equals("sortby")) what = TT_SORTBY; + } + } + + private boolean strchr(String s, char ch) { + return s.indexOf(ch) >= 0; + } + + @Override + public String value() { + return val; + } + + @Override + public int what() { + return what; + } + + @Override + public String render() { + return render(what, true); + } + + @Override + public String render(int token, boolean quoteChars) { + switch (token) { + case TT_EOF: + return "EOF"; + case TT_WORD: + return "word: " + val; + case '"': + return "string: \"" + val + "\""; + case TT_LE: + return "<="; + case TT_GE: + return ">="; + case TT_NE: + return "<>"; + case TT_EQEQ: + return "=="; + case TT_AND: + return "and"; + case TT_NOT: + return "not"; + case TT_OR: + return "or"; + case TT_PROX: + return "prox"; + case TT_SORTBY: + return "sortby"; + default: + //a single character, such as '(' or '/' or relation + String res = String.valueOf((char) token); + if (quoteChars) + res = "'" + res + "'"; + return res; + } + } + + @Override + public int pos() { + return qi; + } +} diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 72a39a3..c373f09 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -21,7 +21,6 @@ */ public class CQLParser { private CQLLexer lexer; - private PositionAwareReader par; //active reader with position private final int compat; // When false, implement CQL 1.2 private final Set customRelations = new HashSet(); @@ -94,26 +93,6 @@ public boolean registerCustomRelation(String relation) { public boolean unregisterCustomRelation(String relation) { return customRelations.remove(relation); } - - /** - * Compiles a CQL query. - *

- * The resulting parse tree may be further processed by hand (see - * the individual node-types' documentation for details on the - * data structure) or, more often, simply rendered out in the - * desired form using one of the back-ends. toCQL() - * returns a decompiled CQL query equivalent to the one that was - * compiled in the first place; toXCQL() returns an - * XML snippet representing the query; and toPQF() - * returns the query rendered in Index Data's Prefix Query - * Format. - * - * @param cql The query - * @return A CQLNode object which is the root of a parse - * tree representing the query. */ - public CQLNode parse(String cql) throws CQLParseException, IOException { - return parse(new StringReader(cql)); - } /** * Compiles a CQL query. @@ -131,18 +110,17 @@ public CQLNode parse(String cql) throws CQLParseException, IOException { * @param cql The query * @return A CQLNode object which is the root of a parse * tree representing the query. */ - public CQLNode parse(Reader cql) + public CQLNode parse(String cql) throws CQLParseException, IOException { - par = new PositionAwareReader(cql); - lexer = new CQLLexer(par, LEXDEBUG); + lexer = new CQLLexerSimple(cql, LEXDEBUG); - lexer.nextToken(); + lexer.move(); debug("about to parseQuery()"); CQLNode root = parseTopLevelPrefixes("cql.serverChoice", new CQLRelation(compat == V1POINT2 ? "=" : "scr")); - if (lexer.ttype != CQLLexer.TT_EOF) + if (lexer.what() != CQLLexer.TT_EOF) throw new CQLParseException("junk after end: " + lexer.render(), - par.getPosition()); + lexer.pos()); return root; } @@ -151,25 +129,25 @@ private CQLNode parseTopLevelPrefixes(String index, CQLRelation relation) throws CQLParseException, IOException { debug("top-level prefix mapping"); - if (lexer.ttype == '>') { + if (lexer.what() == '>') { return parsePrefix(index, relation, true); } CQLNode node = parseQuery(index, relation); if ((compat == V1POINT2 || compat == V1POINT1SORT) && - lexer.ttype == CQLLexer.TT_SORTBY) { - match(lexer.ttype); + lexer.what() == CQLLexer.TT_SORTBY) { + match(lexer.what()); debug("sortspec"); CQLSortNode sortnode = new CQLSortNode(node); - while (lexer.ttype != CQLLexer.TT_EOF) { + while (lexer.what() != CQLLexer.TT_EOF) { String sortindex = matchSymbol("sort index"); ModifierSet ms = gatherModifiers(sortindex); sortnode.addSortIndex(ms); } if (sortnode.keys.size() == 0) { - throw new CQLParseException("no sort keys", par.getPosition()); + throw new CQLParseException("no sort keys", lexer.pos()); } node = sortnode; @@ -183,15 +161,15 @@ private CQLNode parseQuery(String index, CQLRelation relation) debug("in parseQuery()"); CQLNode term = parseTerm(index, relation); - while (lexer.ttype != CQLLexer.TT_EOF && - lexer.ttype != ')' && - lexer.ttype != CQLLexer.TT_SORTBY) { - if (lexer.ttype == CQLLexer.TT_AND || - lexer.ttype == CQLLexer.TT_OR || - lexer.ttype == CQLLexer.TT_NOT || - lexer.ttype == CQLLexer.TT_PROX) { - int type = lexer.ttype; - String val = lexer.sval; + while (lexer.what() != CQLLexer.TT_EOF && + lexer.what() != ')' && + lexer.what() != CQLLexer.TT_SORTBY) { + if (lexer.what() == CQLLexer.TT_AND || + lexer.what() == CQLLexer.TT_OR || + lexer.what() == CQLLexer.TT_NOT || + lexer.what() == CQLLexer.TT_PROX) { + int type = lexer.what(); + String val = lexer.value(); match(type); ModifierSet ms = gatherModifiers(val); CQLNode term2 = parseTerm(index, relation); @@ -201,7 +179,7 @@ private CQLNode parseQuery(String index, CQLRelation relation) new CQLProxNode(term, term2, ms)); } else { throw new CQLParseException("expected boolean, got " + - lexer.render(), par.getPosition()); + lexer.render(), lexer.pos()); } } @@ -214,21 +192,21 @@ private ModifierSet gatherModifiers(String base) debug("in gatherModifiers()"); ModifierSet ms = new ModifierSet(base); - while (lexer.ttype == '/') { + while (lexer.what() == '/') { match('/'); - if (lexer.ttype != CQLLexer.TT_WORD) + if (lexer.what() != CQLLexer.TT_WORD) throw new CQLParseException("expected modifier, " + "got " + lexer.render(), - par.getPosition()); - String type = lexer.sval.toLowerCase(); - match(lexer.ttype); + lexer.pos()); + String type = lexer.value().toLowerCase(); + match(lexer.what()); if (!isSymbolicRelation()) { // It's a simple modifier consisting of type only ms.addModifier(type); } else { // It's a complex modifier of the form type=value - String comparision = lexer.render(lexer.ttype, false); - match(lexer.ttype); + String comparision = lexer.render(lexer.what(), false); + match(lexer.what()); String value = matchSymbol("modifier value"); ms.addModifier(type, comparision, value); } @@ -243,20 +221,20 @@ private CQLNode parseTerm(String index, CQLRelation relation) String word; while (true) { - if (lexer.ttype == '(') { + if (lexer.what() == '(') { debug("parenthesised term"); match('('); CQLNode expr = parseQuery(index, relation); match(')'); return expr; - } else if (lexer.ttype == '>') { + } else if (lexer.what() == '>') { return parsePrefix(index, relation, false); } debug("non-parenthesised term"); word = matchSymbol("index or term"); - while (lexer.ttype == CQLLexer.TT_WORD && !isRelation()) { - word = word + " " + lexer.sval; + while (lexer.what() == CQLLexer.TT_WORD && !isRelation()) { + word = word + " " + lexer.value(); match(CQLLexer.TT_WORD); } @@ -264,10 +242,10 @@ private CQLNode parseTerm(String index, CQLRelation relation) break; index = word; - String relstr = (lexer.ttype == CQLLexer.TT_WORD ? - lexer.sval : lexer.render(lexer.ttype, false)); + String relstr = (lexer.what() == CQLLexer.TT_WORD ? + lexer.value() : lexer.render(lexer.what(), false)); relation = new CQLRelation(relstr); - match(lexer.ttype); + match(lexer.what()); ModifierSet ms = gatherModifiers(relstr); relation.ms = ms; debug("index='" + index + ", " + @@ -287,7 +265,7 @@ private CQLNode parsePrefix(String index, CQLRelation relation, match('>'); String name = null; String identifier = matchSymbol("prefix-name"); - if (lexer.ttype == '=') { + if (lexer.what() == '=') { match('='); name = identifier; identifier = matchSymbol("prefix-identifer"); @@ -300,75 +278,71 @@ private CQLNode parsePrefix(String index, CQLRelation relation, } private boolean isRelation() { - debug("isRelation: checking ttype=" + lexer.ttype + + debug("isRelation: checking what()=" + lexer.what() + " (" + lexer.render() + ")"); - if (lexer.ttype == CQLLexer.TT_WORD && - (lexer.sval.indexOf('.') >= 0 || - lexer.sval.equals("any") || - lexer.sval.equals("all") || - lexer.sval.equals("within") || - lexer.sval.equals("encloses") || - (lexer.sval.equals("exact") && compat != V1POINT2) || - (lexer.sval.equals("scr") && compat != V1POINT2) || - (lexer.sval.equals("adj") && compat == V1POINT2) || - customRelations.contains(lexer.sval))) + if (lexer.what() == CQLLexer.TT_WORD && + (lexer.value().indexOf('.') >= 0 || + lexer.value().equals("any") || + lexer.value().equals("all") || + lexer.value().equals("within") || + lexer.value().equals("encloses") || + (lexer.value().equals("exact") && compat != V1POINT2) || + (lexer.value().equals("scr") && compat != V1POINT2) || + (lexer.value().equals("adj") && compat == V1POINT2) || + customRelations.contains(lexer.value()))) return true; return isSymbolicRelation(); } private boolean isSymbolicRelation() { - debug("isSymbolicRelation: checking ttype=" + lexer.ttype + + debug("isSymbolicRelation: checking what()=" + lexer.what() + " (" + lexer.render() + ")"); - return (lexer.ttype == '<' || - lexer.ttype == '>' || - lexer.ttype == '=' || - lexer.ttype == CQLLexer.TT_LE || - lexer.ttype == CQLLexer.TT_GE || - lexer.ttype == CQLLexer.TT_NE || - lexer.ttype == CQLLexer.TT_EQEQ); + return (lexer.what() == '<' || + lexer.what() == '>' || + lexer.what() == '=' || + lexer.what() == CQLLexer.TT_LE || + lexer.what() == CQLLexer.TT_GE || + lexer.what() == CQLLexer.TT_NE || + lexer.what() == CQLLexer.TT_EQEQ); } private void match(int token) throws CQLParseException, IOException { debug("in match(" + lexer.render(token, true) + ")"); - if (lexer.ttype != token) + if (lexer.what() != token) throw new CQLParseException("expected " + lexer.render(token, true) + ", " + "got " + lexer.render(), - par.getPosition()); - int tmp = lexer.nextToken(); - debug("match() got token=" + lexer.ttype + ", " + - "nval=" + lexer.nval + ", sval='" + lexer.sval + "'" + - " (tmp=" + tmp + ")"); + lexer.pos()); + lexer.move(); + debug("match() got token=" + lexer.what() + ", value()='" + lexer.value() + "'"); } private String matchSymbol(String expected) throws CQLParseException, IOException { debug("in matchSymbol()"); - if (lexer.ttype == CQLLexer.TT_WORD || - lexer.ttype == CQLLexer.TT_NUMBER || - lexer.ttype == '"' || + if (lexer.what() == CQLLexer.TT_WORD || + lexer.what() == '"' || // The following is a complete list of keywords. Because // they're listed here, they can be used unquoted as // indexes, terms, prefix names and prefix identifiers. // ### Instead, we should ask the lexer whether what we // have is a keyword, and let the knowledge reside there. (allowKeywordTerms && - lexer.ttype == CQLLexer.TT_AND || - lexer.ttype == CQLLexer.TT_OR || - lexer.ttype == CQLLexer.TT_NOT || - lexer.ttype == CQLLexer.TT_PROX || - lexer.ttype == CQLLexer.TT_SORTBY)) { - String symbol = (lexer.ttype == CQLLexer.TT_NUMBER) ? - lexer.render() : lexer.sval; - match(lexer.ttype); + lexer.what() == CQLLexer.TT_AND || + lexer.what() == CQLLexer.TT_OR || + lexer.what() == CQLLexer.TT_NOT || + lexer.what() == CQLLexer.TT_PROX || + lexer.what() == CQLLexer.TT_SORTBY)) { + String symbol = lexer.value(); + match(lexer.what()); return symbol; } throw new CQLParseException("expected " + expected + ", " + - "got " + lexer.render(), par.getPosition()); + "got " + lexer.render(), lexer.pos()); } diff --git a/src/main/java/org/z3950/zing/cql/PositionAwareReader.java b/src/main/java/org/z3950/zing/cql/PositionAwareReader.java deleted file mode 100644 index b3294c0..0000000 --- a/src/main/java/org/z3950/zing/cql/PositionAwareReader.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 1995-2012, Index Data - * All rights reserved. - * See the file LICENSE for details. - */ -package org.z3950.zing.cql; - -import java.io.IOException; -import java.io.Reader; -import java.nio.CharBuffer; - -/** - * Reader proxy to count how many characters has been read so far. - * @author jakub - */ -public class PositionAwareReader extends Reader { - protected Reader reader; - protected int pos = -1; - - public PositionAwareReader(Reader reader) { - this.reader = reader; - } - - /* - * Position of the last read character or -1 if either reading from an empty - * stream or no 'read' has been invoked for this reader. - */ - public int getPosition() { - return pos; - } - - @Override - public void mark(int readAheadLimit) throws IOException { - reader.mark(readAheadLimit); - } - - @Override - public boolean markSupported() { - return reader.markSupported(); - } - - @Override - public int read() throws IOException { - int c = reader.read(); - if (c != -1) pos++; - return c; - } - - @Override - public int read(char[] cbuf) throws IOException { - int c = reader.read(cbuf); - if (c != -1) pos+=c; - return c; - } - - @Override - public int read(CharBuffer target) throws IOException { - int c = reader.read(target); - if (c != -1) pos+=c; - return c; - } - - @Override - public int read(char[] cbuf, int off, int len) throws IOException { - int c = reader.read(cbuf, off, len); - if (c != -1) pos+=c; - return c; - } - - @Override - public boolean ready() throws IOException { - return reader.ready(); - } - - @Override - public long skip(long n) throws IOException { - return reader.skip(n); - } - - @Override - public void close() throws IOException { - reader.close(); - } - - @Override - public void reset() throws IOException { - reader.reset(); - } - - //override object methods, to be on the safe-side - - @Override - public boolean equals(Object obj) { - return reader.equals(obj); - } - - @Override - public String toString() { - return reader.toString(); - } - - @Override - public int hashCode() { - return reader.hashCode(); - } - -} diff --git a/src/test/resources/regression/12/01.cql b/src/test/resources/regression/12/01.cql new file mode 100644 index 0000000..d8ec47d --- /dev/null +++ b/src/test/resources/regression/12/01.cql @@ -0,0 +1 @@ +"te\rm\*\?\^" diff --git a/src/test/resources/regression/12/01.xcql b/src/test/resources/regression/12/01.xcql new file mode 100644 index 0000000..c9fc4b6 --- /dev/null +++ b/src/test/resources/regression/12/01.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + term\*\?\^ + diff --git a/src/test/resources/regression/12/name b/src/test/resources/regression/12/name new file mode 100644 index 0000000..09d34d3 --- /dev/null +++ b/src/test/resources/regression/12/name @@ -0,0 +1 @@ +wildcards From 3b57522c8045948fd3a67abcfede06dc19f03df4 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 14 Mar 2014 18:55:10 +0100 Subject: [PATCH 095/147] Clean up --- lib/.gitignore | 1 - lib/README | 4 ---- 2 files changed, 5 deletions(-) delete mode 100644 lib/.gitignore delete mode 100644 lib/README diff --git a/lib/.gitignore b/lib/.gitignore deleted file mode 100644 index 9950dc8..0000000 --- a/lib/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cql-java.jar diff --git a/lib/README b/lib/README deleted file mode 100644 index fdfdab7..0000000 --- a/lib/README +++ /dev/null @@ -1,4 +0,0 @@ - -The library file "cql-java.jar" will appear here when you do a build -in ../src/org/z3950/zing/cql. Put it on your CLASSPATH to use the -CQL-Java utilities. From 3e0fb8b9f1ab75567dd8725d8ec7421b7e60b4ab Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 14 Mar 2014 19:01:20 +0100 Subject: [PATCH 096/147] Predictable jar name --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 9883807..fb56a31 100644 --- a/pom.xml +++ b/pom.xml @@ -63,6 +63,7 @@ + cql-java org.apache.maven.wagon From e8fe6bf38f213b30a2849b02251ec5475b1c032b Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 14 Mar 2014 19:03:07 +0100 Subject: [PATCH 097/147] Re-add fixed binaries --- bin/CQLGenerator | 7 +++++++ bin/CQLLexer | 7 +++++++ bin/CQLParser | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100755 bin/CQLGenerator create mode 100755 bin/CQLLexer create mode 100755 bin/CQLParser diff --git a/bin/CQLGenerator b/bin/CQLGenerator new file mode 100755 index 0000000..80182aa --- /dev/null +++ b/bin/CQLGenerator @@ -0,0 +1,7 @@ +#!/bin/sh + +# Trivial script to invoke the CQLGenerator test-harness +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +JAR=$DIR/../target/cql-java.jar + +java -cp $JAR org.z3950.zing.cql.CQLGenerator ${@+"$@"} diff --git a/bin/CQLLexer b/bin/CQLLexer new file mode 100755 index 0000000..8310fb7 --- /dev/null +++ b/bin/CQLLexer @@ -0,0 +1,7 @@ +#!/bin/sh + +# Trivial script to invoke the CQLLexer test-harness +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +JAR=$DIR/../target/cql-java.jar + +java -cp $JAR org.z3950.zing.cql.CQLLexer ${@+"$@"} diff --git a/bin/CQLParser b/bin/CQLParser new file mode 100755 index 0000000..c5a384f --- /dev/null +++ b/bin/CQLParser @@ -0,0 +1,7 @@ +#!/bin/sh + +# Trivial script to invoke the CQLParser test-harness +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +JAR=$DIR/../target/cql-java.jar + +java -cp $JAR org.z3950.zing.cql.CQLParser ${@+"$@"} From d48bccaed9308a737cdfa55ba555891d0ad85b87 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 14 Mar 2014 19:11:02 +0100 Subject: [PATCH 098/147] Re-add CQLLexer#main --- .../java/org/z3950/zing/cql/CQLLexer.java | 216 +++++++++++++++--- .../org/z3950/zing/cql/CQLLexerSimple.java | 173 -------------- .../java/org/z3950/zing/cql/CQLParser.java | 58 ++--- .../java/org/z3950/zing/cql/CQLTokenizer.java | 40 ++++ 4 files changed, 258 insertions(+), 229 deletions(-) delete mode 100644 src/main/java/org/z3950/zing/cql/CQLLexerSimple.java create mode 100644 src/main/java/org/z3950/zing/cql/CQLTokenizer.java diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 2247fd0..2c867ea 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -9,32 +9,194 @@ * * @author jakub */ -public interface CQLLexer { - - public static final int TT_EOF = -1; - public static final int TT_WORD = -3; - public static final int TT_NOTHING = -4; - - public final static int TT_LE = 1000; // The "<=" relation - public final static int TT_GE = 1001; // The ">=" relation - public final static int TT_NE = 1002; // The "<>" relation - public final static int TT_EQEQ = 1003; // The "==" relation - public final static int TT_AND = 1004; // The "and" boolean - public final static int TT_OR = 1005; // The "or" boolean - public final static int TT_NOT = 1006; // The "not" boolean - public final static int TT_PROX = 1007; // The "prox" boolean - public final static int TT_SORTBY = 1008; // The "sortby" operator - - public void move(); - - public String value(); - - public int what(); - - public String render(); - - public String render(int what, boolean quote); - - public int pos(); +public class CQLLexer implements CQLTokenizer { + private String qs; + private int qi; + private int ql; + private int what = TT_NOTHING; + private String val; + private String lval; + private StringBuilder buf = new StringBuilder(); + + public CQLLexer(String cql, boolean debug) { + qs = cql; + ql = cql.length(); + } + + @Override + public void move() { + //eat whitespace + while (qi < ql && strchr(" \t\r\n", qs.charAt(qi))) + qi++; + //eof + if (qi == ql) { + what = TT_EOF; + return; + } + //current char + char c = qs.charAt(qi); + //separators + if (strchr("()/", c)) { + what = c; + qi++; + //comparitor + } else if (strchr("<>=", c)) { + what = c; + qi++; + //two-char comparitor + if (qi < ql) { + char d = qs.charAt(qi); + String comp = String.valueOf((char) c) + String.valueOf((char) d); + if (comp.equals("==")) { + what = TT_EQEQ; + qi++; + } + else if (comp.equals("<=")) { + what = TT_LE; + qi++; + } + else if (comp.equals(">=")) { + what = TT_GE; + qi++; + } + else if (comp.equals("<>")) { + what = TT_NE; + qi++; + } + } + //quoted string + } else if (strchr("\"", c)) { //no single-quotes + what = '"'; + //remember quote char + char mark = c; + qi++; + boolean escaped = false; + buf.setLength(0); //reset buffer + while (qi < ql) { + if (!escaped && qs.charAt(qi) == mark) //terminator + break; + if (escaped && strchr("*?^\\", qs.charAt(qi))) //no escaping for d-quote + buf.append("\\"); + if (!escaped && qs.charAt(qi) == '\\') { //escape-char + escaped = true; + qi++; + continue; + } + escaped = false; //reset escape + buf.append(qs.charAt(qi)); + qi++; + } + val = buf.toString(); + lval = val.toLowerCase(); + if (qi < ql) + qi++; + else //unterminated + what = TT_EOF; //notify error + //unquoted string + } else { + what = TT_WORD; + buf.setLength(0); //reset buffer + while (qi < ql + && !strchr("()/<>= \t\r\n", qs.charAt(qi))) { + buf.append(qs.charAt(qi)); + qi++; + } + val = buf.toString(); + lval = val.toLowerCase(); + if (lval.equals("or")) what = TT_OR; + else if (lval.equals("and")) what = TT_AND; + else if (lval.equals("not")) what = TT_NOT; + else if (lval.equals("prox")) what = TT_PROX; + else if (lval.equals("sortby")) what = TT_SORTBY; + } + } + + private boolean strchr(String s, char ch) { + return s.indexOf(ch) >= 0; + } + + @Override + public String value() { + return val; + } + + @Override + public int what() { + return what; + } + + @Override + public String render() { + return render(what, true); + } + + @Override + public String render(int token, boolean quoteChars) { + switch (token) { + case TT_EOF: + return "EOF"; + case TT_WORD: + return "word: " + val; + case '"': + return "string: \"" + val + "\""; + case TT_LE: + return "<="; + case TT_GE: + return ">="; + case TT_NE: + return "<>"; + case TT_EQEQ: + return "=="; + case TT_AND: + return "and"; + case TT_NOT: + return "not"; + case TT_OR: + return "or"; + case TT_PROX: + return "prox"; + case TT_SORTBY: + return "sortby"; + default: + //a single character, such as '(' or '/' or relation + String res = String.valueOf((char) token); + if (quoteChars) + res = "'" + res + "'"; + return res; + } + } + + @Override + public int pos() { + return qi; + } + public static void main(String[] args) throws Exception { + if (args.length > 1) { + System.err.println("Usage: CQLLexer []"); + System.err.println("If unspecified, query is read from stdin"); + System.exit(1); + } + + String cql; + if (args.length == 1) { + cql = args[0]; + } else { + byte[] bytes = new byte[10000]; + try { + // Read in the whole of standard input in one go + int nbytes = System.in.read(bytes); + } catch (java.io.IOException ex) { + System.err.println("Can't read query: " + ex.getMessage()); + System.exit(2); + } + cql = new String(bytes); + } + + CQLTokenizer lexer = new CQLLexer(cql, true); + while ((lexer.what()) != TT_EOF) { + lexer.move(); + System.out.println(lexer.render()); + } + } } diff --git a/src/main/java/org/z3950/zing/cql/CQLLexerSimple.java b/src/main/java/org/z3950/zing/cql/CQLLexerSimple.java deleted file mode 100644 index 80931cc..0000000 --- a/src/main/java/org/z3950/zing/cql/CQLLexerSimple.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 1995-2014, Index Datassss - * All rights reserved. - * See the file LICENSE for details. - */ -package org.z3950.zing.cql; - -/** - * - * @author jakub - */ -public class CQLLexerSimple implements CQLLexer { - private String qs; - private int qi; - private int ql; - private int what = TT_NOTHING; - private String val; - private String lval; - private StringBuilder buf = new StringBuilder(); - - public CQLLexerSimple(String cql, boolean debug) { - qs = cql; - ql = cql.length(); - } - - @Override - public void move() { - //eat whitespace - while (qi < ql && strchr(" \t\r\n", qs.charAt(qi))) - qi++; - //eof - if (qi == ql) { - what = TT_EOF; - return; - } - //current char - char c = qs.charAt(qi); - //separators - if (strchr("()/", c)) { - what = c; - qi++; - //comparitor - } else if (strchr("<>=", c)) { - what = c; - qi++; - //two-char comparitor - if (qi < ql) { - char d = qs.charAt(qi); - String comp = String.valueOf((char) c) + String.valueOf((char) d); - if (comp.equals("==")) { - what = TT_EQEQ; - qi++; - } - else if (comp.equals("<=")) { - what = TT_LE; - qi++; - } - else if (comp.equals(">=")) { - what = TT_GE; - qi++; - } - else if (comp.equals("<>")) { - what = TT_NE; - qi++; - } - } - //quoted string - } else if (strchr("\"", c)) { //no single-quotes - what = '"'; - //remember quote char - char mark = c; - qi++; - boolean escaped = false; - buf.setLength(0); //reset buffer - while (qi < ql) { - if (!escaped && qs.charAt(qi) == mark) //terminator - break; - if (escaped && strchr("*?^\\", qs.charAt(qi))) //no escaping for d-quote - buf.append("\\"); - if (!escaped && qs.charAt(qi) == '\\') { //escape-char - escaped = true; - qi++; - continue; - } - escaped = false; //reset escape - buf.append(qs.charAt(qi)); - qi++; - } - val = buf.toString(); - lval = val.toLowerCase(); - if (qi < ql) - qi++; - else //unterminated - what = TT_EOF; //notify error - //unquoted string - } else { - what = TT_WORD; - buf.setLength(0); //reset buffer - while (qi < ql - && !strchr("()/<>= \t\r\n", qs.charAt(qi))) { - buf.append(qs.charAt(qi)); - qi++; - } - val = buf.toString(); - lval = val.toLowerCase(); - if (lval.equals("or")) what = TT_OR; - else if (lval.equals("and")) what = TT_AND; - else if (lval.equals("not")) what = TT_NOT; - else if (lval.equals("prox")) what = TT_PROX; - else if (lval.equals("sortby")) what = TT_SORTBY; - } - } - - private boolean strchr(String s, char ch) { - return s.indexOf(ch) >= 0; - } - - @Override - public String value() { - return val; - } - - @Override - public int what() { - return what; - } - - @Override - public String render() { - return render(what, true); - } - - @Override - public String render(int token, boolean quoteChars) { - switch (token) { - case TT_EOF: - return "EOF"; - case TT_WORD: - return "word: " + val; - case '"': - return "string: \"" + val + "\""; - case TT_LE: - return "<="; - case TT_GE: - return ">="; - case TT_NE: - return "<>"; - case TT_EQEQ: - return "=="; - case TT_AND: - return "and"; - case TT_NOT: - return "not"; - case TT_OR: - return "or"; - case TT_PROX: - return "prox"; - case TT_SORTBY: - return "sortby"; - default: - //a single character, such as '(' or '/' or relation - String res = String.valueOf((char) token); - if (quoteChars) - res = "'" + res + "'"; - return res; - } - } - - @Override - public int pos() { - return qi; - } -} diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index c373f09..31bd7fb 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -20,7 +20,7 @@ * >http://zing.z3950.org/cql/index.html */ public class CQLParser { - private CQLLexer lexer; + private CQLTokenizer lexer; private final int compat; // When false, implement CQL 1.2 private final Set customRelations = new HashSet(); @@ -112,13 +112,13 @@ public boolean unregisterCustomRelation(String relation) { * tree representing the query. */ public CQLNode parse(String cql) throws CQLParseException, IOException { - lexer = new CQLLexerSimple(cql, LEXDEBUG); + lexer = new CQLLexer(cql, LEXDEBUG); lexer.move(); debug("about to parseQuery()"); CQLNode root = parseTopLevelPrefixes("cql.serverChoice", new CQLRelation(compat == V1POINT2 ? "=" : "scr")); - if (lexer.what() != CQLLexer.TT_EOF) + if (lexer.what() != CQLTokenizer.TT_EOF) throw new CQLParseException("junk after end: " + lexer.render(), lexer.pos()); @@ -135,12 +135,12 @@ private CQLNode parseTopLevelPrefixes(String index, CQLRelation relation) CQLNode node = parseQuery(index, relation); if ((compat == V1POINT2 || compat == V1POINT1SORT) && - lexer.what() == CQLLexer.TT_SORTBY) { + lexer.what() == CQLTokenizer.TT_SORTBY) { match(lexer.what()); debug("sortspec"); CQLSortNode sortnode = new CQLSortNode(node); - while (lexer.what() != CQLLexer.TT_EOF) { + while (lexer.what() != CQLTokenizer.TT_EOF) { String sortindex = matchSymbol("sort index"); ModifierSet ms = gatherModifiers(sortindex); sortnode.addSortIndex(ms); @@ -161,21 +161,21 @@ private CQLNode parseQuery(String index, CQLRelation relation) debug("in parseQuery()"); CQLNode term = parseTerm(index, relation); - while (lexer.what() != CQLLexer.TT_EOF && + while (lexer.what() != CQLTokenizer.TT_EOF && lexer.what() != ')' && - lexer.what() != CQLLexer.TT_SORTBY) { - if (lexer.what() == CQLLexer.TT_AND || - lexer.what() == CQLLexer.TT_OR || - lexer.what() == CQLLexer.TT_NOT || - lexer.what() == CQLLexer.TT_PROX) { + lexer.what() != CQLTokenizer.TT_SORTBY) { + if (lexer.what() == CQLTokenizer.TT_AND || + lexer.what() == CQLTokenizer.TT_OR || + lexer.what() == CQLTokenizer.TT_NOT || + lexer.what() == CQLTokenizer.TT_PROX) { int type = lexer.what(); String val = lexer.value(); match(type); ModifierSet ms = gatherModifiers(val); CQLNode term2 = parseTerm(index, relation); - term = ((type == CQLLexer.TT_AND) ? new CQLAndNode(term, term2, ms) : - (type == CQLLexer.TT_OR) ? new CQLOrNode (term, term2, ms) : - (type == CQLLexer.TT_NOT) ? new CQLNotNode(term, term2, ms) : + term = ((type == CQLTokenizer.TT_AND) ? new CQLAndNode(term, term2, ms) : + (type == CQLTokenizer.TT_OR) ? new CQLOrNode (term, term2, ms) : + (type == CQLTokenizer.TT_NOT) ? new CQLNotNode(term, term2, ms) : new CQLProxNode(term, term2, ms)); } else { throw new CQLParseException("expected boolean, got " + @@ -194,7 +194,7 @@ private ModifierSet gatherModifiers(String base) ModifierSet ms = new ModifierSet(base); while (lexer.what() == '/') { match('/'); - if (lexer.what() != CQLLexer.TT_WORD) + if (lexer.what() != CQLTokenizer.TT_WORD) throw new CQLParseException("expected modifier, " + "got " + lexer.render(), lexer.pos()); @@ -233,16 +233,16 @@ private CQLNode parseTerm(String index, CQLRelation relation) debug("non-parenthesised term"); word = matchSymbol("index or term"); - while (lexer.what() == CQLLexer.TT_WORD && !isRelation()) { + while (lexer.what() == CQLTokenizer.TT_WORD && !isRelation()) { word = word + " " + lexer.value(); - match(CQLLexer.TT_WORD); + match(CQLTokenizer.TT_WORD); } if (!isRelation()) break; index = word; - String relstr = (lexer.what() == CQLLexer.TT_WORD ? + String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? lexer.value() : lexer.render(lexer.what(), false)); relation = new CQLRelation(relstr); match(lexer.what()); @@ -280,7 +280,7 @@ private CQLNode parsePrefix(String index, CQLRelation relation, private boolean isRelation() { debug("isRelation: checking what()=" + lexer.what() + " (" + lexer.render() + ")"); - if (lexer.what() == CQLLexer.TT_WORD && + if (lexer.what() == CQLTokenizer.TT_WORD && (lexer.value().indexOf('.') >= 0 || lexer.value().equals("any") || lexer.value().equals("all") || @@ -301,10 +301,10 @@ private boolean isSymbolicRelation() { return (lexer.what() == '<' || lexer.what() == '>' || lexer.what() == '=' || - lexer.what() == CQLLexer.TT_LE || - lexer.what() == CQLLexer.TT_GE || - lexer.what() == CQLLexer.TT_NE || - lexer.what() == CQLLexer.TT_EQEQ); + lexer.what() == CQLTokenizer.TT_LE || + lexer.what() == CQLTokenizer.TT_GE || + lexer.what() == CQLTokenizer.TT_NE || + lexer.what() == CQLTokenizer.TT_EQEQ); } private void match(int token) @@ -323,7 +323,7 @@ private String matchSymbol(String expected) throws CQLParseException, IOException { debug("in matchSymbol()"); - if (lexer.what() == CQLLexer.TT_WORD || + if (lexer.what() == CQLTokenizer.TT_WORD || lexer.what() == '"' || // The following is a complete list of keywords. Because // they're listed here, they can be used unquoted as @@ -331,11 +331,11 @@ private String matchSymbol(String expected) // ### Instead, we should ask the lexer whether what we // have is a keyword, and let the knowledge reside there. (allowKeywordTerms && - lexer.what() == CQLLexer.TT_AND || - lexer.what() == CQLLexer.TT_OR || - lexer.what() == CQLLexer.TT_NOT || - lexer.what() == CQLLexer.TT_PROX || - lexer.what() == CQLLexer.TT_SORTBY)) { + lexer.what() == CQLTokenizer.TT_AND || + lexer.what() == CQLTokenizer.TT_OR || + lexer.what() == CQLTokenizer.TT_NOT || + lexer.what() == CQLTokenizer.TT_PROX || + lexer.what() == CQLTokenizer.TT_SORTBY)) { String symbol = lexer.value(); match(lexer.what()); return symbol; diff --git a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java new file mode 100644 index 0000000..4ab0702 --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1995-2014, Index Datassss + * All rights reserved. + * See the file LICENSE for details. + */ +package org.z3950.zing.cql; + +/** + * + * @author jakub + */ +public interface CQLTokenizer { + + public static final int TT_EOF = -1; + public static final int TT_WORD = -3; + public static final int TT_NOTHING = -4; + + public final static int TT_LE = 1000; // The "<=" relation + public final static int TT_GE = 1001; // The ">=" relation + public final static int TT_NE = 1002; // The "<>" relation + public final static int TT_EQEQ = 1003; // The "==" relation + public final static int TT_AND = 1004; // The "and" boolean + public final static int TT_OR = 1005; // The "or" boolean + public final static int TT_NOT = 1006; // The "not" boolean + public final static int TT_PROX = 1007; // The "prox" boolean + public final static int TT_SORTBY = 1008; // The "sortby" operator + + public void move(); + + public String value(); + + public int what(); + + public String render(); + + public String render(int what, boolean quote); + + public int pos(); + +} From 03ef3621fa8624d56eef1f85274de365ddafed90 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Sat, 15 Mar 2014 16:08:37 +0100 Subject: [PATCH 099/147] More clean up, update readme --- Changes | 4 ++++ README | 23 +++++++++++-------- VERSION | 2 +- .../java/org/z3950/zing/cql/CQLLexer.java | 2 +- {test => util}/random/Makefile | 0 {test => util}/random/README | 0 {test => util}/random/mkrandom | 0 {test => util}/regression/Makefile | 0 {test => util}/regression/README | 0 {test => util}/regression/mkanswers | 0 {test => util}/regression/mktests | 0 {test => util}/regression/queries.raw | 0 {test => util}/regression/runcanon | 0 {test => util}/regression/runtests | 0 .../regression/sections/01/.gitignore | 0 {test => util}/regression/sections/01/01.xcql | 0 {test => util}/regression/sections/01/02.xcql | 0 {test => util}/regression/sections/01/03.xcql | 0 {test => util}/regression/sections/01/04.xcql | 0 {test => util}/regression/sections/01/05.xcql | 0 {test => util}/regression/sections/01/06.xcql | 0 {test => util}/regression/sections/01/07.xcql | 0 {test => util}/regression/sections/01/08.xcql | 0 {test => util}/regression/sections/01/09.xcql | 0 {test => util}/regression/sections/01/10.xcql | 0 {test => util}/regression/sections/01/11.xcql | 0 .../regression/sections/02/.gitignore | 0 {test => util}/regression/sections/02/01.xcql | 0 {test => util}/regression/sections/02/02.xcql | 0 {test => util}/regression/sections/02/03.xcql | 0 {test => util}/regression/sections/02/04.xcql | 0 {test => util}/regression/sections/02/05.xcql | 0 {test => util}/regression/sections/02/06.xcql | 0 {test => util}/regression/sections/02/07.xcql | 0 {test => util}/regression/sections/02/08.xcql | 0 {test => util}/regression/sections/02/09.xcql | 0 {test => util}/regression/sections/02/10.xcql | 0 {test => util}/regression/sections/02/11.xcql | 0 {test => util}/regression/sections/02/12.xcql | 0 {test => util}/regression/sections/02/13.xcql | 0 {test => util}/regression/sections/02/14.xcql | 0 {test => util}/regression/sections/02/15.xcql | 0 {test => util}/regression/sections/02/16.xcql | 0 {test => util}/regression/sections/02/17.xcql | 0 .../regression/sections/03/.gitignore | 0 {test => util}/regression/sections/03/01.xcql | 0 {test => util}/regression/sections/03/02.xcql | 0 {test => util}/regression/sections/03/03.xcql | 0 {test => util}/regression/sections/03/04.xcql | 0 {test => util}/regression/sections/03/05.xcql | 0 {test => util}/regression/sections/03/06.xcql | 0 {test => util}/regression/sections/03/07.xcql | 0 {test => util}/regression/sections/03/08.xcql | 0 {test => util}/regression/sections/03/09.xcql | 0 .../regression/sections/04/.gitignore | 0 {test => util}/regression/sections/04/01.xcql | 0 {test => util}/regression/sections/04/02.xcql | 0 .../regression/sections/05/.gitignore | 0 {test => util}/regression/sections/05/01.xcql | 0 {test => util}/regression/sections/05/02.xcql | 0 {test => util}/regression/sections/05/03.xcql | 0 {test => util}/regression/sections/05/04.xcql | 0 {test => util}/regression/sections/05/05.xcql | 0 {test => util}/regression/sections/05/06.xcql | 0 {test => util}/regression/sections/05/07.xcql | 0 {test => util}/regression/sections/05/08.xcql | 0 {test => util}/regression/sections/05/09.xcql | 0 .../regression/sections/06/.gitignore | 0 {test => util}/regression/sections/06/01.xcql | 0 {test => util}/regression/sections/06/02.xcql | 0 {test => util}/regression/sections/06/03.xcql | 0 {test => util}/regression/sections/06/04.xcql | 0 {test => util}/regression/sections/06/05.xcql | 0 {test => util}/regression/sections/06/06.xcql | 0 .../regression/sections/07/.gitignore | 0 {test => util}/regression/sections/07/01.xcql | 0 {test => util}/regression/sections/07/02.xcql | 0 {test => util}/regression/sections/07/03.xcql | 0 .../regression/sections/08/.gitignore | 0 {test => util}/regression/sections/08/01.xcql | 0 {test => util}/regression/sections/08/02.xcql | 0 {test => util}/regression/sections/08/03.xcql | 0 .../regression/sections/09/.gitignore | 0 {test => util}/regression/sections/09/01.xcql | 0 {test => util}/regression/sections/09/02.xcql | 0 {test => util}/regression/sections/09/03.xcql | 0 {test => util}/regression/sections/09/04.xcql | 0 {test => util}/regression/sections/09/05.xcql | 0 {test => util}/regression/sections/09/06.xcql | 0 .../regression/sections/10/.gitignore | 0 {test => util}/regression/sections/10/01.xcql | 0 {test => util}/regression/sections/10/02.xcql | 0 {test => util}/regression/sections/10/03.xcql | 0 {test => util}/regression/sections/10/04.xcql | 0 {test => util}/regression/sections/10/05.xcql | 0 {test => util}/regression/sections/10/06.xcql | 0 {test => util}/regression/sections/10/07.xcql | 0 {test => util}/regression/sections/10/08.xcql | 0 {test => util}/regression/sections/10/09.xcql | 0 {test => util}/regression/sections/10/10.xcql | 0 {test => util}/regression/sections/10/11.xcql | 0 {test => util}/regression/sections/10/12.xcql | 0 {test => util}/regression/sections/10/13.xcql | 0 {test => util}/regression/sections/10/14.xcql | 0 {test => util}/regression/sections/10/15.xcql | 0 {test => util}/regression/sections/10/16.xcql | 0 {test => util}/regression/showtest | 0 {test => util}/regression/xmlpp.pl | 0 108 files changed, 19 insertions(+), 12 deletions(-) rename {test => util}/random/Makefile (100%) rename {test => util}/random/README (100%) rename {test => util}/random/mkrandom (100%) rename {test => util}/regression/Makefile (100%) rename {test => util}/regression/README (100%) rename {test => util}/regression/mkanswers (100%) rename {test => util}/regression/mktests (100%) rename {test => util}/regression/queries.raw (100%) rename {test => util}/regression/runcanon (100%) rename {test => util}/regression/runtests (100%) rename {test => util}/regression/sections/01/.gitignore (100%) rename {test => util}/regression/sections/01/01.xcql (100%) rename {test => util}/regression/sections/01/02.xcql (100%) rename {test => util}/regression/sections/01/03.xcql (100%) rename {test => util}/regression/sections/01/04.xcql (100%) rename {test => util}/regression/sections/01/05.xcql (100%) rename {test => util}/regression/sections/01/06.xcql (100%) rename {test => util}/regression/sections/01/07.xcql (100%) rename {test => util}/regression/sections/01/08.xcql (100%) rename {test => util}/regression/sections/01/09.xcql (100%) rename {test => util}/regression/sections/01/10.xcql (100%) rename {test => util}/regression/sections/01/11.xcql (100%) rename {test => util}/regression/sections/02/.gitignore (100%) rename {test => util}/regression/sections/02/01.xcql (100%) rename {test => util}/regression/sections/02/02.xcql (100%) rename {test => util}/regression/sections/02/03.xcql (100%) rename {test => util}/regression/sections/02/04.xcql (100%) rename {test => util}/regression/sections/02/05.xcql (100%) rename {test => util}/regression/sections/02/06.xcql (100%) rename {test => util}/regression/sections/02/07.xcql (100%) rename {test => util}/regression/sections/02/08.xcql (100%) rename {test => util}/regression/sections/02/09.xcql (100%) rename {test => util}/regression/sections/02/10.xcql (100%) rename {test => util}/regression/sections/02/11.xcql (100%) rename {test => util}/regression/sections/02/12.xcql (100%) rename {test => util}/regression/sections/02/13.xcql (100%) rename {test => util}/regression/sections/02/14.xcql (100%) rename {test => util}/regression/sections/02/15.xcql (100%) rename {test => util}/regression/sections/02/16.xcql (100%) rename {test => util}/regression/sections/02/17.xcql (100%) rename {test => util}/regression/sections/03/.gitignore (100%) rename {test => util}/regression/sections/03/01.xcql (100%) rename {test => util}/regression/sections/03/02.xcql (100%) rename {test => util}/regression/sections/03/03.xcql (100%) rename {test => util}/regression/sections/03/04.xcql (100%) rename {test => util}/regression/sections/03/05.xcql (100%) rename {test => util}/regression/sections/03/06.xcql (100%) rename {test => util}/regression/sections/03/07.xcql (100%) rename {test => util}/regression/sections/03/08.xcql (100%) rename {test => util}/regression/sections/03/09.xcql (100%) rename {test => util}/regression/sections/04/.gitignore (100%) rename {test => util}/regression/sections/04/01.xcql (100%) rename {test => util}/regression/sections/04/02.xcql (100%) rename {test => util}/regression/sections/05/.gitignore (100%) rename {test => util}/regression/sections/05/01.xcql (100%) rename {test => util}/regression/sections/05/02.xcql (100%) rename {test => util}/regression/sections/05/03.xcql (100%) rename {test => util}/regression/sections/05/04.xcql (100%) rename {test => util}/regression/sections/05/05.xcql (100%) rename {test => util}/regression/sections/05/06.xcql (100%) rename {test => util}/regression/sections/05/07.xcql (100%) rename {test => util}/regression/sections/05/08.xcql (100%) rename {test => util}/regression/sections/05/09.xcql (100%) rename {test => util}/regression/sections/06/.gitignore (100%) rename {test => util}/regression/sections/06/01.xcql (100%) rename {test => util}/regression/sections/06/02.xcql (100%) rename {test => util}/regression/sections/06/03.xcql (100%) rename {test => util}/regression/sections/06/04.xcql (100%) rename {test => util}/regression/sections/06/05.xcql (100%) rename {test => util}/regression/sections/06/06.xcql (100%) rename {test => util}/regression/sections/07/.gitignore (100%) rename {test => util}/regression/sections/07/01.xcql (100%) rename {test => util}/regression/sections/07/02.xcql (100%) rename {test => util}/regression/sections/07/03.xcql (100%) rename {test => util}/regression/sections/08/.gitignore (100%) rename {test => util}/regression/sections/08/01.xcql (100%) rename {test => util}/regression/sections/08/02.xcql (100%) rename {test => util}/regression/sections/08/03.xcql (100%) rename {test => util}/regression/sections/09/.gitignore (100%) rename {test => util}/regression/sections/09/01.xcql (100%) rename {test => util}/regression/sections/09/02.xcql (100%) rename {test => util}/regression/sections/09/03.xcql (100%) rename {test => util}/regression/sections/09/04.xcql (100%) rename {test => util}/regression/sections/09/05.xcql (100%) rename {test => util}/regression/sections/09/06.xcql (100%) rename {test => util}/regression/sections/10/.gitignore (100%) rename {test => util}/regression/sections/10/01.xcql (100%) rename {test => util}/regression/sections/10/02.xcql (100%) rename {test => util}/regression/sections/10/03.xcql (100%) rename {test => util}/regression/sections/10/04.xcql (100%) rename {test => util}/regression/sections/10/05.xcql (100%) rename {test => util}/regression/sections/10/06.xcql (100%) rename {test => util}/regression/sections/10/07.xcql (100%) rename {test => util}/regression/sections/10/08.xcql (100%) rename {test => util}/regression/sections/10/09.xcql (100%) rename {test => util}/regression/sections/10/10.xcql (100%) rename {test => util}/regression/sections/10/11.xcql (100%) rename {test => util}/regression/sections/10/12.xcql (100%) rename {test => util}/regression/sections/10/13.xcql (100%) rename {test => util}/regression/sections/10/14.xcql (100%) rename {test => util}/regression/sections/10/15.xcql (100%) rename {test => util}/regression/sections/10/16.xcql (100%) rename {test => util}/regression/showtest (100%) rename {test => util}/regression/xmlpp.pl (100%) diff --git a/Changes b/Changes index db9734b..d3e03e1 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,10 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. +1.12 TO BE RELEASED + - rewrite the CQL lexer to better conform to CQL spec (e.g retain escapes for wildcards, etc) + - add jUnit test cases + 1.11 Tue 5 Mar 2013 13:38:18 CET - Fix problem with parsing unquoted terms that begin with a '.' - Fix problem with parsing unquoted terms that contain a '@' diff --git a/README b/README index 0120033..e01743d 100644 --- a/README +++ b/README @@ -40,16 +40,15 @@ WHAT'S WHAT IN THIS DISTRIBUTION? VERSION The version-number of this distribution Changes History of releases LGPL-2.1 The GNU lesser GPL (see below) - Makefile, Build Files to control compilation. - src Source-code for the CQL-Java library - lib The compiled library file, "cql-java.jar" - bin Simple shell-scripts to invoke the test-harnesses - docs Documentation automatically generated by "javadoc" - test Various testing and sanity-checking frameworks + pom.xml Maven project file to control compilation. + src Source-code for the CQL-Java library and tests + target The compiled library file, "cql-java.jar" and javadoc + bin Simple shell-scripts to invoke CQL programs (parser/lexer/generator) + util Various testing and sanity-checking Perl scripts etc Other files: PQF indexes, generator properties, etc. "Installation" of this package would consist of putting the bin -directory on your PATH and lib/cql-java.jar on your CLASSPATH. +directory on your PATH and target/cql-java.jar on your CLASSPATH. SYNOPSIS @@ -88,16 +87,19 @@ Using the library in your own applications: DESCRIPTION ----------- -See the automatically generated class documentation in the "doc" +See the automatically generated class documentation in the "target" subdirectory. AUTHOR ------ -Code and documentation by Mike Taylor, Index Data - http://indexdata.com +Original code and documentation by Mike Taylor, Index Data +At present maintained by Jakub Skoczen, Index Data + + http://www.indexdata.com/cql-java http://zing.z3950.org/cql + Please email me with bug-reports, wishlist items, patches, deployment stories and, of course, large cash donations. @@ -125,5 +127,6 @@ SEE ALSO Adam Dickmeiss's CQL compiler, written in C. Rob Sanderson's CQL compiler, written in Python. +Jakub Skoczen's CQL-js compiler, written in JavaScript http://git.indexdata.com/?p=cql-js.git All the other free CQL compilers everyone's going to write :-) The "Changes" file, including the "Still to do" section. diff --git a/VERSION b/VERSION index 6259340..809bdcb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8 +1.12 diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 2c867ea..83bbe5b 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -136,7 +136,7 @@ public String render(int token, boolean quoteChars) { case TT_EOF: return "EOF"; case TT_WORD: - return "word: " + val; + return "word: '" + val + "'"; case '"': return "string: \"" + val + "\""; case TT_LE: diff --git a/test/random/Makefile b/util/random/Makefile similarity index 100% rename from test/random/Makefile rename to util/random/Makefile diff --git a/test/random/README b/util/random/README similarity index 100% rename from test/random/README rename to util/random/README diff --git a/test/random/mkrandom b/util/random/mkrandom similarity index 100% rename from test/random/mkrandom rename to util/random/mkrandom diff --git a/test/regression/Makefile b/util/regression/Makefile similarity index 100% rename from test/regression/Makefile rename to util/regression/Makefile diff --git a/test/regression/README b/util/regression/README similarity index 100% rename from test/regression/README rename to util/regression/README diff --git a/test/regression/mkanswers b/util/regression/mkanswers similarity index 100% rename from test/regression/mkanswers rename to util/regression/mkanswers diff --git a/test/regression/mktests b/util/regression/mktests similarity index 100% rename from test/regression/mktests rename to util/regression/mktests diff --git a/test/regression/queries.raw b/util/regression/queries.raw similarity index 100% rename from test/regression/queries.raw rename to util/regression/queries.raw diff --git a/test/regression/runcanon b/util/regression/runcanon similarity index 100% rename from test/regression/runcanon rename to util/regression/runcanon diff --git a/test/regression/runtests b/util/regression/runtests similarity index 100% rename from test/regression/runtests rename to util/regression/runtests diff --git a/test/regression/sections/01/.gitignore b/util/regression/sections/01/.gitignore similarity index 100% rename from test/regression/sections/01/.gitignore rename to util/regression/sections/01/.gitignore diff --git a/test/regression/sections/01/01.xcql b/util/regression/sections/01/01.xcql similarity index 100% rename from test/regression/sections/01/01.xcql rename to util/regression/sections/01/01.xcql diff --git a/test/regression/sections/01/02.xcql b/util/regression/sections/01/02.xcql similarity index 100% rename from test/regression/sections/01/02.xcql rename to util/regression/sections/01/02.xcql diff --git a/test/regression/sections/01/03.xcql b/util/regression/sections/01/03.xcql similarity index 100% rename from test/regression/sections/01/03.xcql rename to util/regression/sections/01/03.xcql diff --git a/test/regression/sections/01/04.xcql b/util/regression/sections/01/04.xcql similarity index 100% rename from test/regression/sections/01/04.xcql rename to util/regression/sections/01/04.xcql diff --git a/test/regression/sections/01/05.xcql b/util/regression/sections/01/05.xcql similarity index 100% rename from test/regression/sections/01/05.xcql rename to util/regression/sections/01/05.xcql diff --git a/test/regression/sections/01/06.xcql b/util/regression/sections/01/06.xcql similarity index 100% rename from test/regression/sections/01/06.xcql rename to util/regression/sections/01/06.xcql diff --git a/test/regression/sections/01/07.xcql b/util/regression/sections/01/07.xcql similarity index 100% rename from test/regression/sections/01/07.xcql rename to util/regression/sections/01/07.xcql diff --git a/test/regression/sections/01/08.xcql b/util/regression/sections/01/08.xcql similarity index 100% rename from test/regression/sections/01/08.xcql rename to util/regression/sections/01/08.xcql diff --git a/test/regression/sections/01/09.xcql b/util/regression/sections/01/09.xcql similarity index 100% rename from test/regression/sections/01/09.xcql rename to util/regression/sections/01/09.xcql diff --git a/test/regression/sections/01/10.xcql b/util/regression/sections/01/10.xcql similarity index 100% rename from test/regression/sections/01/10.xcql rename to util/regression/sections/01/10.xcql diff --git a/test/regression/sections/01/11.xcql b/util/regression/sections/01/11.xcql similarity index 100% rename from test/regression/sections/01/11.xcql rename to util/regression/sections/01/11.xcql diff --git a/test/regression/sections/02/.gitignore b/util/regression/sections/02/.gitignore similarity index 100% rename from test/regression/sections/02/.gitignore rename to util/regression/sections/02/.gitignore diff --git a/test/regression/sections/02/01.xcql b/util/regression/sections/02/01.xcql similarity index 100% rename from test/regression/sections/02/01.xcql rename to util/regression/sections/02/01.xcql diff --git a/test/regression/sections/02/02.xcql b/util/regression/sections/02/02.xcql similarity index 100% rename from test/regression/sections/02/02.xcql rename to util/regression/sections/02/02.xcql diff --git a/test/regression/sections/02/03.xcql b/util/regression/sections/02/03.xcql similarity index 100% rename from test/regression/sections/02/03.xcql rename to util/regression/sections/02/03.xcql diff --git a/test/regression/sections/02/04.xcql b/util/regression/sections/02/04.xcql similarity index 100% rename from test/regression/sections/02/04.xcql rename to util/regression/sections/02/04.xcql diff --git a/test/regression/sections/02/05.xcql b/util/regression/sections/02/05.xcql similarity index 100% rename from test/regression/sections/02/05.xcql rename to util/regression/sections/02/05.xcql diff --git a/test/regression/sections/02/06.xcql b/util/regression/sections/02/06.xcql similarity index 100% rename from test/regression/sections/02/06.xcql rename to util/regression/sections/02/06.xcql diff --git a/test/regression/sections/02/07.xcql b/util/regression/sections/02/07.xcql similarity index 100% rename from test/regression/sections/02/07.xcql rename to util/regression/sections/02/07.xcql diff --git a/test/regression/sections/02/08.xcql b/util/regression/sections/02/08.xcql similarity index 100% rename from test/regression/sections/02/08.xcql rename to util/regression/sections/02/08.xcql diff --git a/test/regression/sections/02/09.xcql b/util/regression/sections/02/09.xcql similarity index 100% rename from test/regression/sections/02/09.xcql rename to util/regression/sections/02/09.xcql diff --git a/test/regression/sections/02/10.xcql b/util/regression/sections/02/10.xcql similarity index 100% rename from test/regression/sections/02/10.xcql rename to util/regression/sections/02/10.xcql diff --git a/test/regression/sections/02/11.xcql b/util/regression/sections/02/11.xcql similarity index 100% rename from test/regression/sections/02/11.xcql rename to util/regression/sections/02/11.xcql diff --git a/test/regression/sections/02/12.xcql b/util/regression/sections/02/12.xcql similarity index 100% rename from test/regression/sections/02/12.xcql rename to util/regression/sections/02/12.xcql diff --git a/test/regression/sections/02/13.xcql b/util/regression/sections/02/13.xcql similarity index 100% rename from test/regression/sections/02/13.xcql rename to util/regression/sections/02/13.xcql diff --git a/test/regression/sections/02/14.xcql b/util/regression/sections/02/14.xcql similarity index 100% rename from test/regression/sections/02/14.xcql rename to util/regression/sections/02/14.xcql diff --git a/test/regression/sections/02/15.xcql b/util/regression/sections/02/15.xcql similarity index 100% rename from test/regression/sections/02/15.xcql rename to util/regression/sections/02/15.xcql diff --git a/test/regression/sections/02/16.xcql b/util/regression/sections/02/16.xcql similarity index 100% rename from test/regression/sections/02/16.xcql rename to util/regression/sections/02/16.xcql diff --git a/test/regression/sections/02/17.xcql b/util/regression/sections/02/17.xcql similarity index 100% rename from test/regression/sections/02/17.xcql rename to util/regression/sections/02/17.xcql diff --git a/test/regression/sections/03/.gitignore b/util/regression/sections/03/.gitignore similarity index 100% rename from test/regression/sections/03/.gitignore rename to util/regression/sections/03/.gitignore diff --git a/test/regression/sections/03/01.xcql b/util/regression/sections/03/01.xcql similarity index 100% rename from test/regression/sections/03/01.xcql rename to util/regression/sections/03/01.xcql diff --git a/test/regression/sections/03/02.xcql b/util/regression/sections/03/02.xcql similarity index 100% rename from test/regression/sections/03/02.xcql rename to util/regression/sections/03/02.xcql diff --git a/test/regression/sections/03/03.xcql b/util/regression/sections/03/03.xcql similarity index 100% rename from test/regression/sections/03/03.xcql rename to util/regression/sections/03/03.xcql diff --git a/test/regression/sections/03/04.xcql b/util/regression/sections/03/04.xcql similarity index 100% rename from test/regression/sections/03/04.xcql rename to util/regression/sections/03/04.xcql diff --git a/test/regression/sections/03/05.xcql b/util/regression/sections/03/05.xcql similarity index 100% rename from test/regression/sections/03/05.xcql rename to util/regression/sections/03/05.xcql diff --git a/test/regression/sections/03/06.xcql b/util/regression/sections/03/06.xcql similarity index 100% rename from test/regression/sections/03/06.xcql rename to util/regression/sections/03/06.xcql diff --git a/test/regression/sections/03/07.xcql b/util/regression/sections/03/07.xcql similarity index 100% rename from test/regression/sections/03/07.xcql rename to util/regression/sections/03/07.xcql diff --git a/test/regression/sections/03/08.xcql b/util/regression/sections/03/08.xcql similarity index 100% rename from test/regression/sections/03/08.xcql rename to util/regression/sections/03/08.xcql diff --git a/test/regression/sections/03/09.xcql b/util/regression/sections/03/09.xcql similarity index 100% rename from test/regression/sections/03/09.xcql rename to util/regression/sections/03/09.xcql diff --git a/test/regression/sections/04/.gitignore b/util/regression/sections/04/.gitignore similarity index 100% rename from test/regression/sections/04/.gitignore rename to util/regression/sections/04/.gitignore diff --git a/test/regression/sections/04/01.xcql b/util/regression/sections/04/01.xcql similarity index 100% rename from test/regression/sections/04/01.xcql rename to util/regression/sections/04/01.xcql diff --git a/test/regression/sections/04/02.xcql b/util/regression/sections/04/02.xcql similarity index 100% rename from test/regression/sections/04/02.xcql rename to util/regression/sections/04/02.xcql diff --git a/test/regression/sections/05/.gitignore b/util/regression/sections/05/.gitignore similarity index 100% rename from test/regression/sections/05/.gitignore rename to util/regression/sections/05/.gitignore diff --git a/test/regression/sections/05/01.xcql b/util/regression/sections/05/01.xcql similarity index 100% rename from test/regression/sections/05/01.xcql rename to util/regression/sections/05/01.xcql diff --git a/test/regression/sections/05/02.xcql b/util/regression/sections/05/02.xcql similarity index 100% rename from test/regression/sections/05/02.xcql rename to util/regression/sections/05/02.xcql diff --git a/test/regression/sections/05/03.xcql b/util/regression/sections/05/03.xcql similarity index 100% rename from test/regression/sections/05/03.xcql rename to util/regression/sections/05/03.xcql diff --git a/test/regression/sections/05/04.xcql b/util/regression/sections/05/04.xcql similarity index 100% rename from test/regression/sections/05/04.xcql rename to util/regression/sections/05/04.xcql diff --git a/test/regression/sections/05/05.xcql b/util/regression/sections/05/05.xcql similarity index 100% rename from test/regression/sections/05/05.xcql rename to util/regression/sections/05/05.xcql diff --git a/test/regression/sections/05/06.xcql b/util/regression/sections/05/06.xcql similarity index 100% rename from test/regression/sections/05/06.xcql rename to util/regression/sections/05/06.xcql diff --git a/test/regression/sections/05/07.xcql b/util/regression/sections/05/07.xcql similarity index 100% rename from test/regression/sections/05/07.xcql rename to util/regression/sections/05/07.xcql diff --git a/test/regression/sections/05/08.xcql b/util/regression/sections/05/08.xcql similarity index 100% rename from test/regression/sections/05/08.xcql rename to util/regression/sections/05/08.xcql diff --git a/test/regression/sections/05/09.xcql b/util/regression/sections/05/09.xcql similarity index 100% rename from test/regression/sections/05/09.xcql rename to util/regression/sections/05/09.xcql diff --git a/test/regression/sections/06/.gitignore b/util/regression/sections/06/.gitignore similarity index 100% rename from test/regression/sections/06/.gitignore rename to util/regression/sections/06/.gitignore diff --git a/test/regression/sections/06/01.xcql b/util/regression/sections/06/01.xcql similarity index 100% rename from test/regression/sections/06/01.xcql rename to util/regression/sections/06/01.xcql diff --git a/test/regression/sections/06/02.xcql b/util/regression/sections/06/02.xcql similarity index 100% rename from test/regression/sections/06/02.xcql rename to util/regression/sections/06/02.xcql diff --git a/test/regression/sections/06/03.xcql b/util/regression/sections/06/03.xcql similarity index 100% rename from test/regression/sections/06/03.xcql rename to util/regression/sections/06/03.xcql diff --git a/test/regression/sections/06/04.xcql b/util/regression/sections/06/04.xcql similarity index 100% rename from test/regression/sections/06/04.xcql rename to util/regression/sections/06/04.xcql diff --git a/test/regression/sections/06/05.xcql b/util/regression/sections/06/05.xcql similarity index 100% rename from test/regression/sections/06/05.xcql rename to util/regression/sections/06/05.xcql diff --git a/test/regression/sections/06/06.xcql b/util/regression/sections/06/06.xcql similarity index 100% rename from test/regression/sections/06/06.xcql rename to util/regression/sections/06/06.xcql diff --git a/test/regression/sections/07/.gitignore b/util/regression/sections/07/.gitignore similarity index 100% rename from test/regression/sections/07/.gitignore rename to util/regression/sections/07/.gitignore diff --git a/test/regression/sections/07/01.xcql b/util/regression/sections/07/01.xcql similarity index 100% rename from test/regression/sections/07/01.xcql rename to util/regression/sections/07/01.xcql diff --git a/test/regression/sections/07/02.xcql b/util/regression/sections/07/02.xcql similarity index 100% rename from test/regression/sections/07/02.xcql rename to util/regression/sections/07/02.xcql diff --git a/test/regression/sections/07/03.xcql b/util/regression/sections/07/03.xcql similarity index 100% rename from test/regression/sections/07/03.xcql rename to util/regression/sections/07/03.xcql diff --git a/test/regression/sections/08/.gitignore b/util/regression/sections/08/.gitignore similarity index 100% rename from test/regression/sections/08/.gitignore rename to util/regression/sections/08/.gitignore diff --git a/test/regression/sections/08/01.xcql b/util/regression/sections/08/01.xcql similarity index 100% rename from test/regression/sections/08/01.xcql rename to util/regression/sections/08/01.xcql diff --git a/test/regression/sections/08/02.xcql b/util/regression/sections/08/02.xcql similarity index 100% rename from test/regression/sections/08/02.xcql rename to util/regression/sections/08/02.xcql diff --git a/test/regression/sections/08/03.xcql b/util/regression/sections/08/03.xcql similarity index 100% rename from test/regression/sections/08/03.xcql rename to util/regression/sections/08/03.xcql diff --git a/test/regression/sections/09/.gitignore b/util/regression/sections/09/.gitignore similarity index 100% rename from test/regression/sections/09/.gitignore rename to util/regression/sections/09/.gitignore diff --git a/test/regression/sections/09/01.xcql b/util/regression/sections/09/01.xcql similarity index 100% rename from test/regression/sections/09/01.xcql rename to util/regression/sections/09/01.xcql diff --git a/test/regression/sections/09/02.xcql b/util/regression/sections/09/02.xcql similarity index 100% rename from test/regression/sections/09/02.xcql rename to util/regression/sections/09/02.xcql diff --git a/test/regression/sections/09/03.xcql b/util/regression/sections/09/03.xcql similarity index 100% rename from test/regression/sections/09/03.xcql rename to util/regression/sections/09/03.xcql diff --git a/test/regression/sections/09/04.xcql b/util/regression/sections/09/04.xcql similarity index 100% rename from test/regression/sections/09/04.xcql rename to util/regression/sections/09/04.xcql diff --git a/test/regression/sections/09/05.xcql b/util/regression/sections/09/05.xcql similarity index 100% rename from test/regression/sections/09/05.xcql rename to util/regression/sections/09/05.xcql diff --git a/test/regression/sections/09/06.xcql b/util/regression/sections/09/06.xcql similarity index 100% rename from test/regression/sections/09/06.xcql rename to util/regression/sections/09/06.xcql diff --git a/test/regression/sections/10/.gitignore b/util/regression/sections/10/.gitignore similarity index 100% rename from test/regression/sections/10/.gitignore rename to util/regression/sections/10/.gitignore diff --git a/test/regression/sections/10/01.xcql b/util/regression/sections/10/01.xcql similarity index 100% rename from test/regression/sections/10/01.xcql rename to util/regression/sections/10/01.xcql diff --git a/test/regression/sections/10/02.xcql b/util/regression/sections/10/02.xcql similarity index 100% rename from test/regression/sections/10/02.xcql rename to util/regression/sections/10/02.xcql diff --git a/test/regression/sections/10/03.xcql b/util/regression/sections/10/03.xcql similarity index 100% rename from test/regression/sections/10/03.xcql rename to util/regression/sections/10/03.xcql diff --git a/test/regression/sections/10/04.xcql b/util/regression/sections/10/04.xcql similarity index 100% rename from test/regression/sections/10/04.xcql rename to util/regression/sections/10/04.xcql diff --git a/test/regression/sections/10/05.xcql b/util/regression/sections/10/05.xcql similarity index 100% rename from test/regression/sections/10/05.xcql rename to util/regression/sections/10/05.xcql diff --git a/test/regression/sections/10/06.xcql b/util/regression/sections/10/06.xcql similarity index 100% rename from test/regression/sections/10/06.xcql rename to util/regression/sections/10/06.xcql diff --git a/test/regression/sections/10/07.xcql b/util/regression/sections/10/07.xcql similarity index 100% rename from test/regression/sections/10/07.xcql rename to util/regression/sections/10/07.xcql diff --git a/test/regression/sections/10/08.xcql b/util/regression/sections/10/08.xcql similarity index 100% rename from test/regression/sections/10/08.xcql rename to util/regression/sections/10/08.xcql diff --git a/test/regression/sections/10/09.xcql b/util/regression/sections/10/09.xcql similarity index 100% rename from test/regression/sections/10/09.xcql rename to util/regression/sections/10/09.xcql diff --git a/test/regression/sections/10/10.xcql b/util/regression/sections/10/10.xcql similarity index 100% rename from test/regression/sections/10/10.xcql rename to util/regression/sections/10/10.xcql diff --git a/test/regression/sections/10/11.xcql b/util/regression/sections/10/11.xcql similarity index 100% rename from test/regression/sections/10/11.xcql rename to util/regression/sections/10/11.xcql diff --git a/test/regression/sections/10/12.xcql b/util/regression/sections/10/12.xcql similarity index 100% rename from test/regression/sections/10/12.xcql rename to util/regression/sections/10/12.xcql diff --git a/test/regression/sections/10/13.xcql b/util/regression/sections/10/13.xcql similarity index 100% rename from test/regression/sections/10/13.xcql rename to util/regression/sections/10/13.xcql diff --git a/test/regression/sections/10/14.xcql b/util/regression/sections/10/14.xcql similarity index 100% rename from test/regression/sections/10/14.xcql rename to util/regression/sections/10/14.xcql diff --git a/test/regression/sections/10/15.xcql b/util/regression/sections/10/15.xcql similarity index 100% rename from test/regression/sections/10/15.xcql rename to util/regression/sections/10/15.xcql diff --git a/test/regression/sections/10/16.xcql b/util/regression/sections/10/16.xcql similarity index 100% rename from test/regression/sections/10/16.xcql rename to util/regression/sections/10/16.xcql diff --git a/test/regression/showtest b/util/regression/showtest similarity index 100% rename from test/regression/showtest rename to util/regression/showtest diff --git a/test/regression/xmlpp.pl b/util/regression/xmlpp.pl similarity index 100% rename from test/regression/xmlpp.pl rename to util/regression/xmlpp.pl From 55bf45f6db41d765701bbf96daa6af12861929fb Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Sat, 15 Mar 2014 16:49:29 +0100 Subject: [PATCH 100/147] Add javadoc --- .../java/org/z3950/zing/cql/CQLLexer.java | 2 +- .../java/org/z3950/zing/cql/CQLTokenizer.java | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 83bbe5b..c285902 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -6,7 +6,7 @@ package org.z3950.zing.cql; /** - * + * Implementation of the CQL lexical syntax analyzer * @author jakub */ public class CQLLexer implements CQLTokenizer { diff --git a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java index 4ab0702..0425bb4 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java +++ b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java @@ -6,7 +6,7 @@ package org.z3950.zing.cql; /** - * + * API bridge between the parser and lexer implementation * @author jakub */ public interface CQLTokenizer { @@ -25,14 +25,35 @@ public interface CQLTokenizer { public final static int TT_PROX = 1007; // The "prox" boolean public final static int TT_SORTBY = 1008; // The "sortby" operator + /** + * Consume next input token + */ public void move(); + /** + * Return the value of the last consumed token + * @return value of the token + */ public String value(); + /** + * Return the type of the last consumed token + * @return last consumed token + */ public int what(); + /** + * Render the type and value of the last consumed token + * @return human-readable string + */ public String render(); + /** + * Render specified token type + * @param what token type + * @param quote true, if single characters should be quoted for readability + * @return human-readable string + */ public String render(int what, boolean quote); public int pos(); From cb1b46787519585385c4a47d723bffa2bac3d55c Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Sun, 16 Mar 2014 00:54:14 +0100 Subject: [PATCH 101/147] Trim zero character --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index c285902..af61f3f 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -26,7 +26,7 @@ public CQLLexer(String cql, boolean debug) { @Override public void move() { //eat whitespace - while (qi < ql && strchr(" \t\r\n", qs.charAt(qi))) + while (qi < ql && strchr(" \t\r\n\0", qs.charAt(qi))) qi++; //eof if (qi == ql) { From ae791f20ea7239afe6d4e31de7dfc03b932c1be0 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Sun, 16 Mar 2014 01:56:56 +0100 Subject: [PATCH 102/147] Skip null bytes from the output --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index af61f3f..d7f3b77 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -98,7 +98,8 @@ else if (comp.equals("<>")) { buf.setLength(0); //reset buffer while (qi < ql && !strchr("()/<>= \t\r\n", qs.charAt(qi))) { - buf.append(qs.charAt(qi)); + if (qs.charAt(qi) != '\0') + buf.append(qs.charAt(qi)); qi++; } val = buf.toString(); From aee82c7b27048ab058fd9917d18199d4f38a2de4 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Sun, 16 Mar 2014 10:53:01 +0100 Subject: [PATCH 103/147] More tests There's a corner case in the CQL spec which specifies that escape character should be retained ONLY for '^?*' in quoted strings. This means however that spurious escapes will be present in the non-quoted terms: t\*er\m -> t\*er\m "t\*er\m" -> t\*erm --- src/test/resources/regression/12/02.cql | 1 + src/test/resources/regression/12/02.xcql | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 src/test/resources/regression/12/02.cql create mode 100644 src/test/resources/regression/12/02.xcql diff --git a/src/test/resources/regression/12/02.cql b/src/test/resources/regression/12/02.cql new file mode 100644 index 0000000..e48f360 --- /dev/null +++ b/src/test/resources/regression/12/02.cql @@ -0,0 +1 @@ +te\rm\*\?\^ diff --git a/src/test/resources/regression/12/02.xcql b/src/test/resources/regression/12/02.xcql new file mode 100644 index 0000000..b826cba --- /dev/null +++ b/src/test/resources/regression/12/02.xcql @@ -0,0 +1,7 @@ + + cql.serverChoice + + = + + te\rm\*\?\^ + From 59200080b45184be8779f545d21ce87c4020ccf4 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 17 Mar 2014 13:17:13 +0100 Subject: [PATCH 104/147] Fix STDIN reading And remove null byte handling from the lexer --- .../java/org/z3950/zing/cql/CQLGenerator.java | 5 +-- .../java/org/z3950/zing/cql/CQLLexer.java | 24 ++++++++----- .../java/org/z3950/zing/cql/CQLParser.java | 35 ++++++++++++------- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java index 77e4fce..f03235d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLGenerator.java +++ b/src/main/java/org/z3950/zing/cql/CQLGenerator.java @@ -299,15 +299,12 @@ public static void main (String[] args) throws Exception { String configFile = args[0]; InputStream f = new FileInputStream(configFile); - if (f == null) - throw new FileNotFoundException(configFile); - Properties params = new Properties(); params.load(f); f.close(); for (int i = 1; i < args.length; i += 2) params.setProperty(args[i], args[i+1]); - + CQLGenerator generator = new CQLGenerator(params); CQLNode tree = generator.generate(); System.out.println(tree.toCQL()); diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index d7f3b77..d7adeac 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -5,6 +5,10 @@ */ package org.z3950.zing.cql; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + /** * Implementation of the CQL lexical syntax analyzer * @author jakub @@ -26,7 +30,7 @@ public CQLLexer(String cql, boolean debug) { @Override public void move() { //eat whitespace - while (qi < ql && strchr(" \t\r\n\0", qs.charAt(qi))) + while (qi < ql && strchr(" \t\r\n", qs.charAt(qi))) qi++; //eof if (qi == ql) { @@ -98,8 +102,7 @@ else if (comp.equals("<>")) { buf.setLength(0); //reset buffer while (qi < ql && !strchr("()/<>= \t\r\n", qs.charAt(qi))) { - if (qs.charAt(qi) != '\0') - buf.append(qs.charAt(qi)); + buf.append(qs.charAt(qi)); qi++; } val = buf.toString(); @@ -183,15 +186,20 @@ public static void main(String[] args) throws Exception { if (args.length == 1) { cql = args[0]; } else { - byte[] bytes = new byte[10000]; + BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); try { - // Read in the whole of standard input in one go - int nbytes = System.in.read(bytes); - } catch (java.io.IOException ex) { + // read a single line of input + cql = buff.readLine(); + if (cql == null) { + System.err.println("Can't read query from stdin"); + System.exit(2); + return; + } + } catch (IOException ex) { System.err.println("Can't read query: " + ex.getMessage()); System.exit(2); + return; } - cql = new String(bytes); } CQLTokenizer lexer = new CQLLexer(cql, true); diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 31bd7fb..a4f2fc8 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -1,10 +1,12 @@ package org.z3950.zing.cql; +import java.io.BufferedReader; import java.io.IOException; import java.util.Properties; import java.io.InputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; @@ -446,47 +448,54 @@ public static void main (String[] args) { if (argv.size() == 1) { cql = (String) argv.get(0); } else { - byte[] bytes = new byte[10000]; + BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); try { - // Read in the whole of standard input in one go - int nbytes = System.in.read(bytes); + // read a single line of input + cql = buff.readLine(); + if (cql == null) { + System.err.println("Can't read query from stdin"); + System.exit(2); + return; + } } catch (IOException ex) { System.err.println("Can't read query: " + ex.getMessage()); System.exit(2); + return; } - cql = new String(bytes); } CQLParser parser = new CQLParser(compat); - CQLNode root = null; + CQLNode root; try { root = parser.parse(cql); } catch (CQLParseException ex) { System.err.println("Syntax error: " + ex.getMessage()); System.exit(3); + return; //compiler } catch (IOException ex) { System.err.println("Can't compile query: " + ex.getMessage()); System.exit(4); + return; //compiler } try { if (mode == 'c') { System.out.println(root.toCQL()); } else if (mode == 'p') { + try { InputStream f = new FileInputStream(pfile); - if (f == null) - throw new FileNotFoundException(pfile); - Properties config = new Properties(); config.load(f); f.close(); System.out.println(root.toPQF(config)); + } catch (IOException ex) { + System.err.println("Can't load PQF properties:" + + ex.getMessage()); + System.exit(5); + } } else { System.out.print(root.toXCQL()); } - } catch (IOException ex) { - System.err.println("Can't render query: " + ex.getMessage()); - System.exit(5); } catch (UnknownIndexException ex) { System.err.println("Unknown index: " + ex.getMessage()); System.exit(6); @@ -501,8 +510,8 @@ public static void main (String[] args) { System.err.println("Unknown position: " + ex.getMessage()); System.exit(9); } catch (PQFTranslationException ex) { - // We catch all of this class's subclasses, so -- - throw new Error("can't get a PQFTranslationException"); + System.err.println("Cannot translate to PQF: " + ex.getMessage()); + System.exit(10); } } } From b76b718c1994b348b66a994dcf15c819c4e94617 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 17 Mar 2014 14:08:14 +0100 Subject: [PATCH 105/147] Allow a list of quoted terms Also mixed with a list of words. To align with C CQL parser. --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 2 +- src/main/java/org/z3950/zing/cql/CQLParser.java | 15 +++++++++------ .../java/org/z3950/zing/cql/CQLTokenizer.java | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index d7adeac..669dde7 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -70,7 +70,7 @@ else if (comp.equals("<>")) { } //quoted string } else if (strchr("\"", c)) { //no single-quotes - what = '"'; + what = TT_STRING; //remember quote char char mark = c; qi++; diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index a4f2fc8..b435aa3 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -235,13 +235,13 @@ private CQLNode parseTerm(String index, CQLRelation relation) debug("non-parenthesised term"); word = matchSymbol("index or term"); - while (lexer.what() == CQLTokenizer.TT_WORD && !isRelation()) { + while (isWordOrString() && !isRelation()) { word = word + " " + lexer.value(); - match(CQLTokenizer.TT_WORD); + match(lexer.what()); } if (!isRelation()) - break; + break; index = word; String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? @@ -278,6 +278,11 @@ private CQLNode parsePrefix(String index, CQLRelation relation, return new CQLPrefixNode(name, identifier, node); } + + private boolean isWordOrString() { + return CQLTokenizer.TT_WORD == lexer.what() + || CQLTokenizer.TT_STRING == lexer.what(); + } private boolean isRelation() { debug("isRelation: checking what()=" + lexer.what() + @@ -326,12 +331,10 @@ private String matchSymbol(String expected) debug("in matchSymbol()"); if (lexer.what() == CQLTokenizer.TT_WORD || - lexer.what() == '"' || + lexer.what() == CQLTokenizer.TT_STRING || // The following is a complete list of keywords. Because // they're listed here, they can be used unquoted as // indexes, terms, prefix names and prefix identifiers. - // ### Instead, we should ask the lexer whether what we - // have is a keyword, and let the knowledge reside there. (allowKeywordTerms && lexer.what() == CQLTokenizer.TT_AND || lexer.what() == CQLTokenizer.TT_OR || diff --git a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java index 0425bb4..2d8b6b1 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java +++ b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java @@ -15,6 +15,7 @@ public interface CQLTokenizer { public static final int TT_WORD = -3; public static final int TT_NOTHING = -4; + public final static int TT_STRING = 999; // quoted string public final static int TT_LE = 1000; // The "<=" relation public final static int TT_GE = 1001; // The ">=" relation public final static int TT_NE = 1002; // The "<>" relation From edca4cd03787635f579ba0287dfc3c7b607c1197 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 17 Mar 2014 14:43:39 +0100 Subject: [PATCH 106/147] Properly render string tokens --- src/main/java/org/z3950/zing/cql/CQLLexer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 669dde7..cb990cd 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -141,7 +141,7 @@ public String render(int token, boolean quoteChars) { return "EOF"; case TT_WORD: return "word: '" + val + "'"; - case '"': + case TT_STRING: return "string: \"" + val + "\""; case TT_LE: return "<="; From 17ec2f38ab1b7433d7a0121a4940a011956cd3ac Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 17 Mar 2014 16:13:12 +0100 Subject: [PATCH 107/147] Version is in the pom --- README | 1 - VERSION | 1 - 2 files changed, 2 deletions(-) delete mode 100644 VERSION diff --git a/README b/README index e01743d..0586d3a 100644 --- a/README +++ b/README @@ -37,7 +37,6 @@ WHAT'S WHAT IN THIS DISTRIBUTION? --------------------------------- README This file - VERSION The version-number of this distribution Changes History of releases LGPL-2.1 The GNU lesser GPL (see below) pom.xml Maven project file to control compilation. diff --git a/VERSION b/VERSION deleted file mode 100644 index 809bdcb..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.12 From 0cc4496630458d049dba11311ba96e47070fb980 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 17 Mar 2014 16:15:51 +0100 Subject: [PATCH 108/147] Note on building --- README | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README b/README index 0586d3a..7f3b4f1 100644 --- a/README +++ b/README @@ -46,6 +46,16 @@ WHAT'S WHAT IN THIS DISTRIBUTION? util Various testing and sanity-checking Perl scripts etc Other files: PQF indexes, generator properties, etc. + +COMPILATION AND INSTALLATION +---------------------------- + +The build process is controlled by Maven so compilation is the standard: + + mvn clean install + +which generates build artifacts under target/. + "Installation" of this package would consist of putting the bin directory on your PATH and target/cql-java.jar on your CLASSPATH. From 62f2fa7ebb63eefc6ebcb5294481be1dc15fc0f5 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 17 Mar 2014 16:19:34 +0100 Subject: [PATCH 109/147] Update --- Changes | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Changes b/Changes index d3e03e1..f956a24 100644 --- a/Changes +++ b/Changes @@ -5,9 +5,11 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. -1.12 TO BE RELEASED - - rewrite the CQL lexer to better conform to CQL spec (e.g retain escapes for wildcards, etc) +1.12 Mon 17 Mar 2014 16:16:16 CET + - rewrite the CQL lexer to better conform to CQL spec + (e.g retain escapes for wildcards, etc) - add jUnit test cases + - align list of terms (non-compliant) handling with Yaz CQL parser 1.11 Tue 5 Mar 2013 13:38:18 CET - Fix problem with parsing unquoted terms that begin with a '.' From 55b690e4e16aaeeb26aa6f856256d04b747edbbd Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 17 Mar 2014 16:23:31 +0100 Subject: [PATCH 110/147] [maven-release-plugin] prepare release v1.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb56a31..3efe867 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.12-SNAPSHOT + 1.12 cql-java http://www.indexdata.com/cql-java From ef1bf1042ca56427c347aa86722e8f4fafbfd1cf Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Mon, 17 Mar 2014 16:23:31 +0100 Subject: [PATCH 111/147] [maven-release-plugin] prepare for next development iteration --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3efe867..f249c62 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.12 + 1.13-SNAPSHOT cql-java http://www.indexdata.com/cql-java From 4886cce6a79fa4e1d3365319e2b24a642b179f59 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 19 Mar 2014 15:28:03 +0100 Subject: [PATCH 112/147] Disallow multi-token index names That, in turn, binds non-symbolic relations to the second position and allows more free-form parsing. --- .../java/org/z3950/zing/cql/CQLParser.java | 29 +++++++------ .../org/z3950/zing/cql/CQLParserTest.java | 2 +- src/test/resources/regression/09/01.xcql | 42 +++++++++++++------ 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index b435aa3..4d4f025 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -1,14 +1,12 @@ package org.z3950.zing.cql; + import java.io.BufferedReader; import java.io.IOException; import java.util.Properties; import java.io.InputStream; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -221,7 +219,8 @@ private CQLNode parseTerm(String index, CQLRelation relation) throws CQLParseException, IOException { debug("in parseTerm()"); - String word; + String first; + StringBuilder all; while (true) { if (lexer.what() == '(') { debug("parenthesised term"); @@ -234,16 +233,23 @@ private CQLNode parseTerm(String index, CQLRelation relation) } debug("non-parenthesised term"); - word = matchSymbol("index or term"); - while (isWordOrString() && !isRelation()) { - word = word + " " + lexer.value(); + first = matchSymbol("index or term"); + all = new StringBuilder(first); + //match relation only on second postion + while (isWordOrString() && (all.length() > first.length() || !isRelation())) { + all.append(" ").append(lexer.value()); match(lexer.what()); } if (!isRelation()) - break; - - index = word; + break; //we're done if no relation + + //we have relation, but it only makes sense if preceded by a single term + if (all.length() > first.length()) { + throw new CQLParseException("unexpected relation '"+lexer.value()+"'" + , lexer.pos()); + } + index = first; String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? lexer.value() : lexer.render(lexer.what(), false)); relation = new CQLRelation(relstr); @@ -253,8 +259,7 @@ private CQLNode parseTerm(String index, CQLRelation relation) debug("index='" + index + ", " + "relation='" + relation.toCQL() + "'"); } - - CQLTermNode node = new CQLTermNode(index, relation, word); + CQLTermNode node = new CQLTermNode(index, relation, all.toString()); debug("made term node " + node.toCQL()); return node; } diff --git a/src/test/java/org/z3950/zing/cql/CQLParserTest.java b/src/test/java/org/z3950/zing/cql/CQLParserTest.java index 2566e13..34d5999 100644 --- a/src/test/java/org/z3950/zing/cql/CQLParserTest.java +++ b/src/test/java/org/z3950/zing/cql/CQLParserTest.java @@ -133,7 +133,7 @@ public void testRandomQueries() throws IOException, MissingParameterException { params.load(is); is.close(); CQLGenerator generator = new CQLGenerator(params); - for (int i=0; i<100; i++) { + for (int i=0; i<1000; i++) { CQLNode random = generator.generate(); String expected = random.toCQL(); out.println("Generated query: "+expected); diff --git a/src/test/resources/regression/09/01.xcql b/src/test/resources/regression/09/01.xcql index f721ed0..aefe23d 100644 --- a/src/test/resources/regression/09/01.xcql +++ b/src/test/resources/regression/09/01.xcql @@ -1,20 +1,36 @@ - and + prox - or + and - - cql.serverChoice - - = - - any - + + + or + + + + cql.serverChoice + + = + + any + + + + + cql.serverChoice + + = + + all:stem + + + @@ -22,18 +38,18 @@ = - all:stem + all contains any - all contains + cql.serverChoice - any + = - prox proxfuzzy + proxfuzzy From 738438f3da478a1d0121cbbdab620c47f222c73e Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 19 Mar 2014 15:32:31 +0100 Subject: [PATCH 113/147] Mark syntax errors --- src/main/java/org/z3950/zing/cql/CQLParser.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 4d4f025..8a0fc17 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -478,6 +478,11 @@ public static void main (String[] args) { root = parser.parse(cql); } catch (CQLParseException ex) { System.err.println("Syntax error: " + ex.getMessage()); + StringBuilder space = new StringBuilder(cql.length()); + System.out.println(cql); + for (int i=0; i Date: Wed, 19 Mar 2014 15:56:12 +0100 Subject: [PATCH 114/147] Proper exception message --- src/main/java/org/z3950/zing/cql/CQLParser.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 8a0fc17..cbe64d5 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -244,14 +244,15 @@ private CQLNode parseTerm(String index, CQLRelation relation) if (!isRelation()) break; //we're done if no relation + //render relation + String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? + lexer.value() : lexer.render(lexer.what(), false)); //we have relation, but it only makes sense if preceded by a single term if (all.length() > first.length()) { - throw new CQLParseException("unexpected relation '"+lexer.value()+"'" + throw new CQLParseException("unexpected relation '"+relstr+"'" , lexer.pos()); } index = first; - String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? - lexer.value() : lexer.render(lexer.what(), false)); relation = new CQLRelation(relstr); match(lexer.what()); ModifierSet ms = gatherModifiers(relstr); From 6e0bb6cfb1bc2fefdbbe1b88a097e7dc29cc88f9 Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Wed, 15 Oct 2014 16:51:08 +0200 Subject: [PATCH 115/147] Add classes for visitor traversal --- .../java/org/z3950/zing/cql/CQLAndNode.java | 7 +++ .../org/z3950/zing/cql/CQLBooleanNode.java | 8 +++ .../z3950/zing/cql/CQLDefaultNodeVisitor.java | 51 +++++++++++++++++++ src/main/java/org/z3950/zing/cql/CQLNode.java | 2 + .../org/z3950/zing/cql/CQLNodeVisitor.java | 33 ++++++++++++ .../java/org/z3950/zing/cql/CQLNotNode.java | 6 +++ .../java/org/z3950/zing/cql/CQLOrNode.java | 6 +++ .../org/z3950/zing/cql/CQLPrefixNode.java | 6 +++ .../java/org/z3950/zing/cql/CQLProxNode.java | 5 ++ .../java/org/z3950/zing/cql/CQLRelation.java | 5 ++ .../java/org/z3950/zing/cql/CQLSortNode.java | 6 +++ .../java/org/z3950/zing/cql/CQLTermNode.java | 7 +++ 12 files changed, 142 insertions(+) create mode 100644 src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java create mode 100644 src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java diff --git a/src/main/java/org/z3950/zing/cql/CQLAndNode.java b/src/main/java/org/z3950/zing/cql/CQLAndNode.java index 7e39669..6b95630 100644 --- a/src/main/java/org/z3950/zing/cql/CQLAndNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLAndNode.java @@ -15,6 +15,13 @@ public CQLAndNode(CQLNode left, CQLNode right, ModifierSet ms) { super(left, right, ms); } + @Override + public void traverse(CQLNodeVisitor visitor) { + visitor.onAndNode(this); + super.traverse(visitor); + } + + // ### Too much code duplication here with OR and NOT @Override byte[] opType1() { diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index 18c0bff..1b73ee7 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -42,6 +42,14 @@ protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms) { this.ms = ms; } + @Override + public void traverse(CQLNodeVisitor visitor) { + visitor.onBooleanNode(this); + left.traverse(visitor); + right.traverse(visitor); + } + + @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { diff --git a/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java b/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java new file mode 100644 index 0000000..d77dafb --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 1995-2014, Index Data + * All rights reserved. + * See the file LICENSE for details. + */ + +package org.z3950.zing.cql; + +/** + * Query tree visitor with default (no-op) implementation + * @author jakub + */ +public class CQLDefaultNodeVisitor implements CQLNodeVisitor { + + @Override + public void onSortNode(CQLSortNode node) { + } + + @Override + public void onPrfixNode(CQLPrefixNode node) { + } + + @Override + public void onBooleanNode(CQLBooleanNode node) { + } + + @Override + public void onProxNode(CQLProxNode node) { + } + + @Override + public void onAndNode(CQLAndNode node) { + } + + @Override + public void onOrNode(CQLOrNode node) { + } + + @Override + public void onNotNode(CQLNotNode node) { + } + + @Override + public void onTermNode(CQLTermNode node) { + } + + @Override + public void onRelation(CQLRelation relation) { + } + +} diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index a4e171d..221da44 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -12,6 +12,8 @@ * */ public abstract class CQLNode { + + public abstract void traverse(CQLNodeVisitor visitor); /** * Returns the name of the result-set to which this query is a diff --git a/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java b/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java new file mode 100644 index 0000000..0d120d8 --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1995-2014, Index Data + * All rights reserved. + * See the file LICENSE for details. + */ + +package org.z3950.zing.cql; + +/** + * Allows to visit different types of nodes in the query tree. + * @author jakub + */ +public interface CQLNodeVisitor { + + public void onSortNode(CQLSortNode node); + + public void onPrfixNode(CQLPrefixNode node); + + public void onBooleanNode(CQLBooleanNode node); + + public void onProxNode(CQLProxNode node); + + public void onAndNode(CQLAndNode node); + + public void onOrNode(CQLOrNode node); + + public void onNotNode(CQLNotNode node); + + public void onTermNode(CQLTermNode node); + + public void onRelation(CQLRelation relation); + +} diff --git a/src/main/java/org/z3950/zing/cql/CQLNotNode.java b/src/main/java/org/z3950/zing/cql/CQLNotNode.java index 4f3814c..c32d427 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNotNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNotNode.java @@ -15,6 +15,12 @@ public CQLNotNode(CQLNode left, CQLNode right, ModifierSet ms) { super(left, right, ms); } + @Override + public void traverse(CQLNodeVisitor visitor) { + visitor.onNotNode(this); + super.traverse(visitor); + } + @Override byte[] opType1() { byte[] op = new byte[5]; diff --git a/src/main/java/org/z3950/zing/cql/CQLOrNode.java b/src/main/java/org/z3950/zing/cql/CQLOrNode.java index 92c9dfa..52fd899 100644 --- a/src/main/java/org/z3950/zing/cql/CQLOrNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLOrNode.java @@ -15,6 +15,12 @@ public CQLOrNode(CQLNode left, CQLNode right, ModifierSet ms) { super(left, right, ms); } + @Override + public void traverse(CQLNodeVisitor visitor) { + visitor.onOrNode(this); + super.traverse(visitor); + } + @Override byte[] opType1() { byte[] op = new byte[5]; diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index d3f6b74..2b23a6d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -40,6 +40,12 @@ public CQLPrefixNode(String name, String identifier, CQLNode subtree) { this.subtree = subtree; } + @Override + public void traverse(CQLNodeVisitor visitor) { + visitor.onPrfixNode(this); + subtree.traverse(visitor); + } + @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { diff --git a/src/main/java/org/z3950/zing/cql/CQLProxNode.java b/src/main/java/org/z3950/zing/cql/CQLProxNode.java index 35f1781..c33eade 100644 --- a/src/main/java/org/z3950/zing/cql/CQLProxNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLProxNode.java @@ -18,6 +18,11 @@ public CQLProxNode(CQLNode left, CQLNode right, ModifierSet ms) { super(left, right, ms); } + @Override + public void traverse(CQLNodeVisitor visitor) { + visitor.onProxNode(this); + } + /* * proximity ::= exclusion distance ordered relation which-code unit-code. * exclusion ::= '1' | '0' | 'void'. diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 716a1e9..81fd38c 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -41,6 +41,11 @@ public List getModifiers() { return ms.getModifiers(); } + @Override + public void traverse(CQLNodeVisitor visitor) { + visitor.onRelation(this); + } + @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 96a93e8..efc190b 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -40,6 +40,12 @@ public List getSortIndexes() { return keys; } + @Override + public void traverse(CQLNodeVisitor visitor) { + visitor.onSortNode(this); + subtree.traverse(visitor); + } + @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index a6e1772..2ad9188 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -41,6 +41,13 @@ private static boolean isResultSetIndex(String qual) { qual.equals("cql.resultSetName")); } + @Override + public void traverse(CQLNodeVisitor visitor) { + //we visit relation first to allow filtering on relation type in the visitor + relation.traverse(visitor); + visitor.onTermNode(this); + } + @Override public String getResultSetName() { if (isResultSetIndex(index)) From 68b82aca296a69366b5cc3d8be0eb9d4593a28ab Mon Sep 17 00:00:00 2001 From: rustam Date: Thu, 10 Mar 2016 14:17:53 +0300 Subject: [PATCH 116/147] Added support for truncation attribute --- etc/pqf.properties | 11 ++++++++ .../java/org/z3950/zing/cql/CQLTermNode.java | 22 ++++++++++++++++ .../zing/cql/UnknownTruncationException.java | 25 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 src/main/java/org/z3950/zing/cql/UnknownTruncationException.java diff --git a/etc/pqf.properties b/etc/pqf.properties index 2448482..36a0483 100644 --- a/etc/pqf.properties +++ b/etc/pqf.properties @@ -96,6 +96,17 @@ structure.any = 4=2 structure.* = 4=1 # phrase +# Truncation attributes used to implement CQL wildcard patterns. The +# simpler forms, left, right- and both-truncation will be used for the +# simplest patterns, so that we produce PQF queries that conform more +# closely to the Bath Profile. However, when a more complex pattern +# such as "foo*bar" is used, we fall back on Z39.58-style masking. +# +truncation.right = 5=1 +truncation.left = 5=2 +truncation.both = 5=3 +truncation.none = 5=100 + # Finally, any additional attributes that should always be included # with each term can be specified in the "always" property. # diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index 2ad9188..a810a79 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -135,11 +135,19 @@ private List getAttrs(Properties config) throws PQFTranslationException } String pos = "any"; + String truncation = "none"; String text = term; if (text.length() > 0 && text.substring(0, 1).equals("^")) { text = text.substring(1); // ### change not seen by caller pos = "first"; } + if (text.startsWith("*") && text.endsWith("*")) { + truncation = "both"; + } else if (text.startsWith("*")) { + truncation = "left"; + } else if (text.endsWith("*")) { + truncation = "right"; + } int len = text.length(); if (len > 0 && text.substring(len-1, len).equals("^")) { text = text.substring(0, len-1); // ### change not seen by caller @@ -156,6 +164,11 @@ private List getAttrs(Properties config) throws PQFTranslationException throw new UnknownPositionException(pos); attrs.add(attr); + attr = config.getProperty("truncation." + truncation); + if (attr == null) + throw new UnknownTruncationException(truncation); + attrs.add(attr); + attr = config.getProperty("structure." + rel); if (attr == null) attr = config.getProperty("structure.*"); @@ -187,6 +200,15 @@ public String toPQF(Properties config) throws PQFTranslationException { if (len > 0 && text.substring(len-1, len).equals("^")) text = text.substring(0, len-1); + len = text.length(); + if (text.startsWith("*") && text.endsWith("*")) { + text = text.substring(1, len-1); + } else if (text.startsWith("*")) { + text = text.substring(1); + } else if (text.endsWith("*")) { + text = text.substring(0, len-1); + } + return s + maybeQuote(text); } diff --git a/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java b/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java new file mode 100644 index 0000000..3842e23 --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java @@ -0,0 +1,25 @@ +package org.z3950.zing.cql; + +/** + * Exception indicating that a truncation was not recognised. When rendering a + * tree out as PQF, each term is classified either as left, + * right, left and right truncated, depending on whether + * it begins and/or ends with the character *. Its + * classification is looked up as a truncation in the PQF + * configuration. If the truncation is not configured, we throw one of these + * babies. + * + */ +public class UnknownTruncationException extends PQFTranslationException { + private static final long serialVersionUID = 6971993723734811253L; + + /** + * Creates a new UnknownTruncationException. + * + * @param s + * The truncation for which there was no PQF configuration. + */ + public UnknownTruncationException(String s) { + super(s); + } +} From d7c04f14ba54ae70b0fa0e7247896df94ef7d0f0 Mon Sep 17 00:00:00 2001 From: rustam Date: Thu, 10 Mar 2016 14:55:21 +0300 Subject: [PATCH 117/147] Added support for exact relation --- src/main/java/org/z3950/zing/cql/CQLTermNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index a810a79..218a4aa 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -112,6 +112,8 @@ private List getAttrs(Properties config) throws PQFTranslationException String rel = relation.getBase(); if (rel.equals("=")) { rel = "eq"; + } else if (rel.equals("==")) { + rel = "exact"; } else if (rel.equals("<=")) { rel = "le"; } else if (rel.equals(">=")) { From d0f162de29c5961967dd64dad208285d39cef25b Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 10 Aug 2016 11:13:54 +0200 Subject: [PATCH 118/147] Fix link to Jakub's CQL-js compiler --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 7f3b4f1..3a36f37 100644 --- a/README +++ b/README @@ -136,6 +136,6 @@ SEE ALSO Adam Dickmeiss's CQL compiler, written in C. Rob Sanderson's CQL compiler, written in Python. -Jakub Skoczen's CQL-js compiler, written in JavaScript http://git.indexdata.com/?p=cql-js.git +Jakub Skoczen's CQL-js compiler, written in JavaScript https://github.com/indexdata/cql-js All the other free CQL compilers everyone's going to write :-) The "Changes" file, including the "Still to do" section. From 11d8ed7a2ffaa9097777fac76b146d20cb026075 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 10 Aug 2016 11:20:45 +0200 Subject: [PATCH 119/147] Fix link to XCQL schema --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 3a36f37..961eb89 100644 --- a/README +++ b/README @@ -27,7 +27,7 @@ and there's more (and friendlier) information at XCQL is "XML CQL", a representation of CQL-equivalent queries in XML which is supposed to be easier to parse. The specification is at - http://www.loc.gov/standards/sru/xml-files/xcql.xsd + http://docs.oasis-open.org/search-ws/searchRetrieve/v1.0/os/schemas/xcql.xsd in the form of an XML Schema. But if you didn't know that, why are you even reading this? :-) From bb744780ed5aa84b6293a56cc5b2ae6f91a78cd7 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 10 Aug 2016 11:20:56 +0200 Subject: [PATCH 120/147] Indentation --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 961eb89..4389f86 100644 --- a/README +++ b/README @@ -52,7 +52,7 @@ COMPILATION AND INSTALLATION The build process is controlled by Maven so compilation is the standard: - mvn clean install + mvn clean install which generates build artifacts under target/. @@ -106,7 +106,7 @@ AUTHOR Original code and documentation by Mike Taylor, Index Data At present maintained by Jakub Skoczen, Index Data - http://www.indexdata.com/cql-java + http://www.indexdata.com/cql-java http://zing.z3950.org/cql Please email me with bug-reports, wishlist items, patches, deployment From 5c922b3d79b396c1f60ad87eb815861b1942518c Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 7 Dec 2016 11:58:11 +0000 Subject: [PATCH 121/147] Move README to README.md, preparatory to formatting in Markdown --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From cb693db088524af96895192b4c2aedb208cba786 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Wed, 7 Dec 2016 12:06:48 +0000 Subject: [PATCH 122/147] Markdown-ification --- README.md | 65 ++++++++++++++++++++++++------------------------------- 1 file changed, 28 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 4389f86..c94df9f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ +# CQL-Java -- a free CQL parser and related tools, for Java -CQL-Java - a free CQL compiler, and other CQL tools, for Java - -INTRODUCTION ------------- +## Introduction CQL-Java is a Free Software project that provides: @@ -33,35 +31,32 @@ in the form of an XML Schema. But if you didn't know that, why are you even reading this? :-) -WHAT'S WHAT IN THIS DISTRIBUTION? ---------------------------------- +## What's What in this Distribution? - README This file - Changes History of releases - LGPL-2.1 The GNU lesser GPL (see below) - pom.xml Maven project file to control compilation. - src Source-code for the CQL-Java library and tests - target The compiled library file, "cql-java.jar" and javadoc - bin Simple shell-scripts to invoke CQL programs (parser/lexer/generator) - util Various testing and sanity-checking Perl scripts - etc Other files: PQF indexes, generator properties, etc. +* `README.md` -- This file +* [`Changes`](Changes) -- History of releases +* [`LGPL-2.1`](LGPL-2.1) -- The GNU lesser GPL (see below) +* `pom.xml` -- Maven project file to control compilation. +* `src` -- Source-code for the CQL-Java library and tests +* `target` -- The compiled library file, `cql-java.jar` and javadoc +* `bin` -- Simple shell-scripts to invoke CQL programs (parser/lexer/generator) +* `util` -- Various testing and sanity-checking Perl scripts +* `etc` -- Other files: PQF indexes, generator properties, etc. -COMPILATION AND INSTALLATION ----------------------------- +## Compilation and Installation The build process is controlled by Maven so compilation is the standard: mvn clean install -which generates build artifacts under target/. +which generates build artifacts under `target/`. "Installation" of this package would consist of putting the bin -directory on your PATH and target/cql-java.jar on your CLASSPATH. +directory on your PATH and `target/cql-java.jar` on your CLASSPATH. -SYNOPSIS --------- +## Synopsis Using the test-harnesses: @@ -93,28 +88,24 @@ Using the library in your own applications: // ... where `config' specifies CQL-qualfier => Z-attr mapping -DESCRIPTION ------------ +## Description See the automatically generated class documentation in the "target" subdirectory. -AUTHOR ------- +## Author Original code and documentation by Mike Taylor, Index Data At present maintained by Jakub Skoczen, Index Data - http://www.indexdata.com/cql-java - http://zing.z3950.org/cql +* http://www.indexdata.com/cql-java -Please email me with bug-reports, wishlist items, patches, deployment +Please email us with bug-reports, wishlist items, patches, deployment stories and, of course, large cash donations. -LICENCE -------- +## Licence The CQL-Java suite is Free Software, which is pretty much legally equivalent -- though not morally equivalent -- to Open Source. See @@ -131,11 +122,11 @@ much anything else with it. In particular, you may deploy CQL-Java as a part of a non-free larger work. -SEE ALSO --------- +## See also -Adam Dickmeiss's CQL compiler, written in C. -Rob Sanderson's CQL compiler, written in Python. -Jakub Skoczen's CQL-js compiler, written in JavaScript https://github.com/indexdata/cql-js -All the other free CQL compilers everyone's going to write :-) -The "Changes" file, including the "Still to do" section. +* http://zing.z3950.org/cql +* Adam Dickmeiss's CQL compiler, written in C. +* Rob Sanderson's CQL compiler, written in Python. +* Jakub Skoczen's CQL-js compiler, written in JavaScript https://github.com/indexdata/cql-js +* All the other free CQL compilers everyone's going to write :-) +* The [`Changes`](Changes) file, including the "Still to do" section. From f2a40b25bbf9b80a3c47244564ae0233adc20c1c Mon Sep 17 00:00:00 2001 From: Jakub Skoczen Date: Fri, 9 Dec 2016 13:28:38 +0100 Subject: [PATCH 123/147] Add explicit operator enum and restructure visitor Explicit operator enum allows to discover the type of the CQLBoolean node without manual casting. CQLNodeVisitor has been rewritten to allow for generation of prefix, postfix and infix notations. See the examples in the test for details. --- .../java/org/z3950/zing/cql/CQLAndNode.java | 11 +- .../java/org/z3950/zing/cql/CQLBoolean.java | 14 ++ .../org/z3950/zing/cql/CQLBooleanNode.java | 12 +- .../z3950/zing/cql/CQLDefaultNodeVisitor.java | 20 +-- .../org/z3950/zing/cql/CQLNodeVisitor.java | 21 +-- .../java/org/z3950/zing/cql/CQLNotNode.java | 10 +- .../java/org/z3950/zing/cql/CQLOrNode.java | 8 +- .../org/z3950/zing/cql/CQLPrefixNode.java | 2 +- .../java/org/z3950/zing/cql/CQLProxNode.java | 9 +- .../z3950/zing/cql/CQLNodeVisitorTest.java | 136 ++++++++++++++++++ 10 files changed, 185 insertions(+), 58 deletions(-) create mode 100644 src/main/java/org/z3950/zing/cql/CQLBoolean.java create mode 100644 src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java diff --git a/src/main/java/org/z3950/zing/cql/CQLAndNode.java b/src/main/java/org/z3950/zing/cql/CQLAndNode.java index 6b95630..724c185 100644 --- a/src/main/java/org/z3950/zing/cql/CQLAndNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLAndNode.java @@ -12,15 +12,8 @@ public class CQLAndNode extends CQLBooleanNode { * sides and modifiers. */ public CQLAndNode(CQLNode left, CQLNode right, ModifierSet ms) { - super(left, right, ms); - } - - @Override - public void traverse(CQLNodeVisitor visitor) { - visitor.onAndNode(this); - super.traverse(visitor); - } - + super(left, right, ms, CQLBoolean.AND); + } // ### Too much code duplication here with OR and NOT @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLBoolean.java b/src/main/java/org/z3950/zing/cql/CQLBoolean.java new file mode 100644 index 0000000..53b48ad --- /dev/null +++ b/src/main/java/org/z3950/zing/cql/CQLBoolean.java @@ -0,0 +1,14 @@ +/* + * Copyright (c) 1995-2016, Index Data + * All rights reserved. + * See the file LICENSE for details. + */ +package org.z3950.zing.cql; + +/** + * + * @author jakub + */ +public enum CQLBoolean { + AND, OR, NOT, PROX; +} diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index 1b73ee7..ee167b8 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -8,7 +8,12 @@ * */ public abstract class CQLBooleanNode extends CQLNode { + private final CQLBoolean operator; + public CQLBoolean getOperator() { + return operator; + } + private CQLNode left; /** @@ -36,17 +41,20 @@ public List getModifiers() { return ms.getModifiers(); } - protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms) { + protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms, CQLBoolean operator) { this.left = left; this.right = right; this.ms = ms; + this.operator = operator; } @Override public void traverse(CQLNodeVisitor visitor) { - visitor.onBooleanNode(this); + visitor.onBooleanNodeStart(this); left.traverse(visitor); + visitor.onBooleanNodeOp(this); right.traverse(visitor); + visitor.onBooleanNodeEnd(this); } diff --git a/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java b/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java index d77dafb..e3858ce 100644 --- a/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java +++ b/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java @@ -11,35 +11,27 @@ * @author jakub */ public class CQLDefaultNodeVisitor implements CQLNodeVisitor { - + @Override public void onSortNode(CQLSortNode node) { } @Override - public void onPrfixNode(CQLPrefixNode node) { - } - - @Override - public void onBooleanNode(CQLBooleanNode node) { + public void onPrefixNode(CQLPrefixNode node) { } @Override - public void onProxNode(CQLProxNode node) { + public void onBooleanNodeStart(CQLBooleanNode node) { } @Override - public void onAndNode(CQLAndNode node) { + public void onBooleanNodeOp(CQLBooleanNode node) { } @Override - public void onOrNode(CQLOrNode node) { + public void onBooleanNodeEnd(CQLBooleanNode node) { } - - @Override - public void onNotNode(CQLNotNode node) { - } - + @Override public void onTermNode(CQLTermNode node) { } diff --git a/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java b/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java index 0d120d8..5f90cf6 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java +++ b/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java @@ -7,24 +7,25 @@ package org.z3950.zing.cql; /** - * Allows to visit different types of nodes in the query tree. + * Allows to visit different types of nodes in the query tree. In most cases + * you will want to extend CQLDefaultNodeVisitor and + * choose only the methods you need to override. + * CQLBooleanNode/Start/Op/End methods allow to generate prefix, infix or + * postfix notations without needing to keep track of the parse tree. + * See the CQLNodeVisitorTest for examples. * @author jakub */ public interface CQLNodeVisitor { - + public void onSortNode(CQLSortNode node); - public void onPrfixNode(CQLPrefixNode node); - - public void onBooleanNode(CQLBooleanNode node); - - public void onProxNode(CQLProxNode node); + public void onPrefixNode(CQLPrefixNode node); - public void onAndNode(CQLAndNode node); + public void onBooleanNodeStart(CQLBooleanNode node); - public void onOrNode(CQLOrNode node); + public void onBooleanNodeOp(CQLBooleanNode node); - public void onNotNode(CQLNotNode node); + public void onBooleanNodeEnd(CQLBooleanNode node); public void onTermNode(CQLTermNode node); diff --git a/src/main/java/org/z3950/zing/cql/CQLNotNode.java b/src/main/java/org/z3950/zing/cql/CQLNotNode.java index c32d427..706f4c1 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNotNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNotNode.java @@ -12,14 +12,8 @@ public class CQLNotNode extends CQLBooleanNode { * sides and modifiers. */ public CQLNotNode(CQLNode left, CQLNode right, ModifierSet ms) { - super(left, right, ms); - } - - @Override - public void traverse(CQLNodeVisitor visitor) { - visitor.onNotNode(this); - super.traverse(visitor); - } + super(left, right, ms, CQLBoolean.NOT); + } @Override byte[] opType1() { diff --git a/src/main/java/org/z3950/zing/cql/CQLOrNode.java b/src/main/java/org/z3950/zing/cql/CQLOrNode.java index 52fd899..295f303 100644 --- a/src/main/java/org/z3950/zing/cql/CQLOrNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLOrNode.java @@ -12,13 +12,7 @@ public class CQLOrNode extends CQLBooleanNode { * sides and modifiers. */ public CQLOrNode(CQLNode left, CQLNode right, ModifierSet ms) { - super(left, right, ms); - } - - @Override - public void traverse(CQLNodeVisitor visitor) { - visitor.onOrNode(this); - super.traverse(visitor); + super(left, right, ms, CQLBoolean.OR); } @Override diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index 2b23a6d..64e3103 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -42,7 +42,7 @@ public CQLPrefixNode(String name, String identifier, CQLNode subtree) { @Override public void traverse(CQLNodeVisitor visitor) { - visitor.onPrfixNode(this); + visitor.onPrefixNode(this); subtree.traverse(visitor); } diff --git a/src/main/java/org/z3950/zing/cql/CQLProxNode.java b/src/main/java/org/z3950/zing/cql/CQLProxNode.java index c33eade..b452e22 100644 --- a/src/main/java/org/z3950/zing/cql/CQLProxNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLProxNode.java @@ -15,13 +15,8 @@ public class CQLProxNode extends CQLBooleanNode { * sides and modifiers. */ public CQLProxNode(CQLNode left, CQLNode right, ModifierSet ms) { - super(left, right, ms); - } - - @Override - public void traverse(CQLNodeVisitor visitor) { - visitor.onProxNode(this); - } + super(left, right, ms, CQLBoolean.PROX); + } /* * proximity ::= exclusion distance ordered relation which-code unit-code. diff --git a/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java b/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java new file mode 100644 index 0000000..3a83235 --- /dev/null +++ b/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 1995-2016, Index Data + * All rights reserved. + * See the file LICENSE for details. + */ +package org.z3950.zing.cql; + +import java.io.IOException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +import static java.lang.System.*; + +/** + * + * @author jakub + */ +public class CQLNodeVisitorTest { + + public CQLNodeVisitorTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + @Test + public void testPrefixVisitor() { + String cql = "((x=a and y=b) or z=c)"; + String epxected = "@or @and @attr 1=x a @attr 1=y b @attr 1=z c"; + CQLParser p = new CQLParser(CQLParser.V1POINT2); + out.println("Parsing "+cql); + try { + CQLNode n = p.parse(cql); + CQLNodeVisitor v = new CQLDefaultNodeVisitor() { + String actual = ""; + String termSep = ""; + @Override + public void onBooleanNodeStart(CQLBooleanNode node) { + String op = ""; + switch (node.getOperator()) { + case AND: op = "@and"; break; + case OR: op = "@or"; break; + } + actual += op + " "; + } + + @Override + public void onTermNode(CQLTermNode node) { + actual += termSep + "@attr 1="+node.getIndex() + " " + node.getTerm(); + termSep = " "; + } + + @Override + public String toString() { + return actual; + } + }; + n.traverse(v); + out.println(v); + assertEquals(epxected, v.toString()); + } catch (CQLParseException ex) { + fail(ex.getMessage()); + } catch (IOException ex) { + fail(ex.getMessage()); + } + } + + @Test + public void testInfixVisitor() { + String cql = "((x=a and y=b) or z=c)"; + String epxected = "((x:a OG y:b) ELLER z:c)"; + CQLParser p = new CQLParser(CQLParser.V1POINT2); + out.println("Parsing "+cql); + try { + CQLNode n = p.parse(cql); + CQLNodeVisitor v = new CQLDefaultNodeVisitor() { + String actual = ""; + + @Override + public void onBooleanNodeStart(CQLBooleanNode node) { + actual += "("; + } + + @Override + public void onBooleanNodeOp(CQLBooleanNode node) { + String op = ""; + switch (node.getOperator()) { + case AND: op = "OG"; break; + case OR: op = "ELLER"; break; + } + actual += " " + op + " "; + } + + @Override + public void onBooleanNodeEnd(CQLBooleanNode node) { + actual += ")"; + } + + @Override + public void onTermNode(CQLTermNode node) { + actual += node.getIndex() + ":" + node.getTerm(); + } + + @Override + public String toString() { + return actual; + } + }; + n.traverse(v); + out.println(v); + assertEquals(epxected, v.toString()); + } catch (CQLParseException ex) { + fail(ex.getMessage()); + } catch (IOException ex) { + fail(ex.getMessage()); + } + } + +} From 6325d352b20045aad646470d5490dbc508e21df3 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Fri, 3 Mar 2017 14:15:56 +0000 Subject: [PATCH 124/147] Requires bash, not regular sh, due to the use of $(command) --- bin/CQLParser | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/CQLParser b/bin/CQLParser index c5a384f..d03e5cf 100755 --- a/bin/CQLParser +++ b/bin/CQLParser @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Trivial script to invoke the CQLParser test-harness DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" From c01c255bc037dc60acd4dbeae17a8e4a24835ebd Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Fri, 3 Mar 2017 14:16:45 +0000 Subject: [PATCH 125/147] Requires bash, not regular sh, due to the use of $(command) --- bin/CQLLexer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/CQLLexer b/bin/CQLLexer index 8310fb7..6e94eb3 100755 --- a/bin/CQLLexer +++ b/bin/CQLLexer @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Trivial script to invoke the CQLLexer test-harness DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" From de1c74c5a295ac64a23e2358a04d72127a98a593 Mon Sep 17 00:00:00 2001 From: Mike Taylor Date: Fri, 3 Mar 2017 14:17:40 +0000 Subject: [PATCH 126/147] Requires bash, not regular sh, due to the use of $(command) --- bin/CQLGenerator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/CQLGenerator b/bin/CQLGenerator index 80182aa..a1c3a2f 100755 --- a/bin/CQLGenerator +++ b/bin/CQLGenerator @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Trivial script to invoke the CQLGenerator test-harness DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" From f1ab2a9ef4d08f2312b0e80e555c3e1f4df78507 Mon Sep 17 00:00:00 2001 From: John Malconian Date: Tue, 7 Mar 2017 15:34:28 +0000 Subject: [PATCH 127/147] update wagon dependency to 2.12; update port on maven.indexdata.com --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f249c62..141612a 100644 --- a/pom.xml +++ b/pom.xml @@ -68,12 +68,12 @@ org.apache.maven.wagon wagon-ssh - 2.2 + 2.12 org.apache.maven.wagon wagon-ssh-external - 2.2 + 2.12 @@ -113,7 +113,7 @@ false id-maven-repo Index Data Maven Repository - scp://maven.indexdata.com:222/var/www/maven/repository + scp://maven.indexdata.com/var/www/maven/repository id-website From 6face108d159bbdaf2d0b2c164b9e65b46f1453b Mon Sep 17 00:00:00 2001 From: Julian Ladisch Date: Wed, 10 May 2017 13:13:46 +0200 Subject: [PATCH 128/147] maven-release-plugin 2.5.3 to fix failure on Windows release:prepare fails on Windows since Maven-3.3.x, maven-release-plugin contains a fix since 2.5.2: https://issues.apache.org/jira/browse/MRELEASE-902 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 141612a..9a74ab8 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ org.apache.maven.plugins maven-release-plugin - 2.2.2 + 2.5.3 clean verify production From 0f7e4616eb32c37c00be2f6d6560d6bdeff096a5 Mon Sep 17 00:00:00 2001 From: Julian Ladisch Date: Wed, 10 May 2017 13:30:30 +0200 Subject: [PATCH 129/147] fix profile name --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9a74ab8..3e32d00 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ 2.5.3 clean verify - production + maven-3 v@{project.version} false true From cf4fe3065d63214197597a15488f5dd393e08591 Mon Sep 17 00:00:00 2001 From: Julian Ladisch Date: Wed, 10 May 2017 14:43:13 +0200 Subject: [PATCH 130/147] Changes summary for 1.13 --- Changes | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Changes b/Changes index f956a24..1503a26 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,14 @@ See the bottom of this file for a list of things still to do. The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National Library of Australia, whose help we gratefully acknowledge. +1.13 Wed 10 May 2017 14:44:44 CET + - add classes for visitor traversal + - truncation attribute right/left/both/none (thanks to Rustam Usmanov) + - exact relation == (thanks to Rustam Usmanov) + - CQLNodeVisitor rewritten to allow for generation of prefix, + postfix and infix notations + - enum CQLBoolean + 1.12 Mon 17 Mar 2014 16:16:16 CET - rewrite the CQL lexer to better conform to CQL spec (e.g retain escapes for wildcards, etc) From 4d4053ed2c10584ae781dd6f18791eeb9fd80d50 Mon Sep 17 00:00:00 2001 From: Julian Ladisch Date: Wed, 10 May 2017 14:44:57 +0200 Subject: [PATCH 131/147] ignore errors when producing javadoc --- pom.xml | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 3e32d00..338db5e 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.8.1 + 2.10.4 UTF-8 @@ -98,6 +98,22 @@ true + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + ${javadoc.opts} + + + + @@ -130,7 +146,7 @@ UTF-8 - + maven-3 @@ -144,7 +160,18 @@ org.apache.maven.plugins maven-site-plugin - 3.0 + 3.6 + + + + org.apache.maven.plugins + maven-javadoc-plugin + + ${javadoc.opts} + + + + @@ -163,6 +190,16 @@ + + + java8-doclint-disabled + + [1.8,) + + + -Xdoclint:none + + From 9099f761fb79cd51a7677f0143ea41516fb8658e Mon Sep 17 00:00:00 2001 From: Julian Ladisch Date: Wed, 10 May 2017 15:22:04 +0200 Subject: [PATCH 132/147] [maven-release-plugin] prepare release v1.13 --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 338db5e..876bbe1 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.13-SNAPSHOT + 1.13 cql-java http://www.indexdata.com/cql-java @@ -41,6 +41,7 @@ scm:git:ssh://git.indexdata.com:222/home/git/pub/cql-java http://git.indexdata.com/?p=cql-java.git + v1.13 Bugzilla From 480639e7cab23eb26559550559b0d26afcf95058 Mon Sep 17 00:00:00 2001 From: Julian Ladisch Date: Wed, 10 May 2017 15:22:05 +0200 Subject: [PATCH 133/147] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 876bbe1..13ef107 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.z3950.zing cql-java jar - 1.13 + 1.14-SNAPSHOT cql-java http://www.indexdata.com/cql-java @@ -41,7 +41,7 @@ scm:git:ssh://git.indexdata.com:222/home/git/pub/cql-java http://git.indexdata.com/?p=cql-java.git - v1.13 + HEAD Bugzilla From c1f05d397cfeeff37f7822afe037f9826e2516f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Oct 2020 01:22:07 +0000 Subject: [PATCH 134/147] Bump junit from 4.10 to 4.13.1 Bumps [junit](https://github.com/junit-team/junit4) from 4.10 to 4.13.1. - [Release notes](https://github.com/junit-team/junit4/releases) - [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.10.md) - [Commits](https://github.com/junit-team/junit4/compare/r4.10...r4.13.1) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 13ef107..a5c9f98 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,7 @@ junit junit - 4.10 + 4.13.1 test From 37f540d4a231a1e4b49d2ee31141d75696b84bc1 Mon Sep 17 00:00:00 2001 From: Julian Ladisch Date: Wed, 9 Nov 2022 17:37:24 +0100 Subject: [PATCH 135/147] Fix license name and url in pom.xml (LGPL-2.1-only) The license entry in pom.xml has `LGPL`. This is ambiguous because there are several LGPL versions. The README.md says "version 2.1 of the LGPL" so this should be changed to LGPL-2.1-only, the identifier suggested by https://spdx.org/licenses/ Only the entry in pom.xml is machine-readable, the README isn't, to help tools reading from pom.xml the change should be made. The license entry in pom.xml contains `http://www.indexdata.com/licences/lgpl`. That URL redirects to https://www.gnu.org/licenses/lgpl-3.0.en.html To match the README it is changed to `https://spdx.org/licenses/LGPL-2.1-only.html`. Note: There also exists LGPL-2.1-or-later, the default suggested on https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html Regarding my contributions to cql-java: I agree if cql-java is changed to LGPL-2.1-or-later. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a5c9f98..92dd7e4 100644 --- a/pom.xml +++ b/pom.xml @@ -8,8 +8,8 @@ http://www.indexdata.com/cql-java - LGPL - http://www.indexdata.com/licences/lgpl + LGPL-2.1-only + https://spdx.org/licenses/LGPL-2.1-only.html repo From 1d08fc6e00a363f0efe218b7852c6d4bb33ce46d Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 13 Jan 2025 11:02:46 +0100 Subject: [PATCH 136/147] Upd links; Java 1.8 --- pom.xml | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 92dd7e4..f2fe9bd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ jar 1.14-SNAPSHOT cql-java - http://www.indexdata.com/cql-java + https://www.indexdata.com/cql-java LGPL-2.1-only @@ -16,7 +16,7 @@ 2008 Index Data - http://www.indexdata.com + https://www.indexdata.com @@ -24,7 +24,7 @@ mike mike@indexdata.com Index Data - http://www.indexdata.com/ + https://www.indexdata.com/ @@ -33,24 +33,20 @@ jakub jakub@indexdata.dk Index Data - http://www.indexdata.com/ + https://www.indexdata.com/ - scm:git:ssh://git.indexdata.com:222/home/git/pub/cql-java - http://git.indexdata.com/?p=cql-java.git + scm:git:git://github.com/indexdata/cql-java.git + https://github.com/indexdata/cql-java HEAD Bugzilla - http://bugzilla.indexdata.dk/ + https://index-data.atlassian.net/browse/CQLJAVA - - hudson - http://hudson.indexdata.com/ - @@ -83,8 +79,8 @@ maven-compiler-plugin 2.0.2 - 1.6 - 1.6 + 1.8 + 1.8 @@ -140,7 +136,7 @@ id-maven-repo - http://maven.indexdata.com + https://maven.indexdata.com From 2bc60351edf3b54ef30fd9323bab0901d30f394c Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 28 May 2025 13:23:12 +0200 Subject: [PATCH 137/147] Add GH workflow; JDK 11 (#14) --- .github/workflows/mvn-verify.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/mvn-verify.yaml diff --git a/.github/workflows/mvn-verify.yaml b/.github/workflows/mvn-verify.yaml new file mode 100644 index 0000000..50853df --- /dev/null +++ b/.github/workflows/mvn-verify.yaml @@ -0,0 +1,16 @@ +name: mvn-verify +on: [push, pull_request] + +jobs: + mvn-verify: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'temurin' + cache: maven + - name: Run the Maven verify phase + run: mvn --batch-mode verify From 4094a0378b343015859dcd067d75099ed86e2e04 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 29 May 2025 18:13:35 +0200 Subject: [PATCH 138/147] Fix warning about reporting configuration (#15) * Fix warning about reporting configuration Fixes: Some problems were encountered while building the effective model for org.z3950.zing:cql-java:jar:1.14-SNAPSHOT [WARNING] Reporting configuration should be done in section, not in maven-site-plugin as reportPlugins parameter. --- pom.xml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index f2fe9bd..bb3d03f 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ 2.10.4 UTF-8 + ${javadoc.opts} @@ -158,17 +159,6 @@ org.apache.maven.plugins maven-site-plugin 3.6 - - - - org.apache.maven.plugins - maven-javadoc-plugin - - ${javadoc.opts} - - - - @@ -199,4 +189,3 @@ - From 6251e96ce2434bb7cbe80e9ebeef70872e56f862 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 30 Jun 2025 16:54:23 +0200 Subject: [PATCH 139/147] javadoc: HTML 5 tags; package is on 1st line in java src (#16) --- .../java/org/z3950/zing/cql/CQLAndNode.java | 8 +- .../java/org/z3950/zing/cql/CQLBoolean.java | 16 ++-- .../org/z3950/zing/cql/CQLBooleanNode.java | 6 +- .../z3950/zing/cql/CQLDefaultNodeVisitor.java | 6 -- .../java/org/z3950/zing/cql/CQLGenerator.java | 76 +++++++++---------- .../java/org/z3950/zing/cql/CQLLexer.java | 5 -- src/main/java/org/z3950/zing/cql/CQLNode.java | 23 +++--- .../org/z3950/zing/cql/CQLNodeVisitor.java | 6 -- .../java/org/z3950/zing/cql/CQLNotNode.java | 2 - .../java/org/z3950/zing/cql/CQLOrNode.java | 2 - .../org/z3950/zing/cql/CQLParseException.java | 4 +- .../java/org/z3950/zing/cql/CQLParser.java | 29 ++++--- .../java/org/z3950/zing/cql/CQLPrefix.java | 7 +- .../org/z3950/zing/cql/CQLPrefixNode.java | 3 +- .../java/org/z3950/zing/cql/CQLProxNode.java | 2 - .../java/org/z3950/zing/cql/CQLRelation.java | 10 +-- .../java/org/z3950/zing/cql/CQLSortNode.java | 3 +- .../java/org/z3950/zing/cql/CQLTermNode.java | 8 +- .../java/org/z3950/zing/cql/CQLTokenizer.java | 5 -- .../zing/cql/MissingParameterException.java | 4 +- .../java/org/z3950/zing/cql/Modifier.java | 3 +- .../java/org/z3950/zing/cql/ModifierSet.java | 12 +-- .../zing/cql/PQFTranslationException.java | 2 - .../z3950/zing/cql/UnknownIndexException.java | 4 +- .../zing/cql/UnknownPositionException.java | 12 ++- .../zing/cql/UnknownRelationException.java | 4 +- .../cql/UnknownRelationModifierException.java | 4 +- .../zing/cql/UnknownTruncationException.java | 10 +-- .../java/org/z3950/zing/cql/XCQLBuilder.java | 5 -- .../z3950/zing/cql/CQLNodeVisitorTest.java | 5 -- .../org/z3950/zing/cql/CQLParserTest.java | 12 +-- 31 files changed, 119 insertions(+), 179 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLAndNode.java b/src/main/java/org/z3950/zing/cql/CQLAndNode.java index 724c185..ecff58d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLAndNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLAndNode.java @@ -1,4 +1,3 @@ - package org.z3950.zing.cql; @@ -10,6 +9,13 @@ public class CQLAndNode extends CQLBooleanNode { /** * Creates a new AND node with the specified left- and right-hand * sides and modifiers. + * @param left the left-hand side of the AND + * @param right the right-hand side of the AND + * @param ms the modifiers to apply to this AND + * @see ModifierSet + * @see CQLNode + * @see CQLBoolean + * @see CQLBooleanNode */ public CQLAndNode(CQLNode left, CQLNode right, ModifierSet ms) { super(left, right, ms, CQLBoolean.AND); diff --git a/src/main/java/org/z3950/zing/cql/CQLBoolean.java b/src/main/java/org/z3950/zing/cql/CQLBoolean.java index 53b48ad..bab541b 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBoolean.java +++ b/src/main/java/org/z3950/zing/cql/CQLBoolean.java @@ -1,14 +1,16 @@ -/* - * Copyright (c) 1995-2016, Index Data - * All rights reserved. - * See the file LICENSE for details. - */ package org.z3950.zing.cql; /** - * + * Represents a boolean operator in CQL. * @author jakub */ public enum CQLBoolean { - AND, OR, NOT, PROX; + /** AND is the same as CQL's "and" */ + AND, + /** OR is the same as CQL's "or" */ + OR, + /** NOT is the same as CQL's "not" */ + NOT, + /** PROX is the same as CQL's "prox" */ + PROX; } diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index ee167b8..6d903bf 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -1,5 +1,5 @@ - package org.z3950.zing.cql; + import java.util.List; import java.util.Properties; @@ -18,6 +18,7 @@ public CQLBoolean getOperator() { /** * The root of a parse-tree representing the left-hand side. + * @return the left operand of this boolean node */ public CQLNode getLeftOperand() { return left; @@ -27,6 +28,7 @@ public CQLNode getLeftOperand() { /** * The root of a parse-tree representing the right-hand side. + * @return the right operand of this boolean node */ public CQLNode getRightOperand() { return right; @@ -36,6 +38,7 @@ public CQLNode getRightOperand() { /** * The set of modifiers that are applied to this boolean. + * @return a list of Modifier objects, which may be empty. */ public List getModifiers() { return ms.getModifiers(); @@ -57,7 +60,6 @@ public void traverse(CQLNodeVisitor visitor) { visitor.onBooleanNodeEnd(this); } - @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, List sortkeys) { diff --git a/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java b/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java index e3858ce..9c0b744 100644 --- a/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java +++ b/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java @@ -1,9 +1,3 @@ -/* - * Copyright (c) 1995-2014, Index Data - * All rights reserved. - * See the file LICENSE for details. - */ - package org.z3950.zing.cql; /** diff --git a/src/main/java/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java index f03235d..2f21563 100644 --- a/src/main/java/org/z3950/zing/cql/CQLGenerator.java +++ b/src/main/java/org/z3950/zing/cql/CQLGenerator.java @@ -1,24 +1,22 @@ - package org.z3950.zing.cql; + import java.util.Properties; import java.util.Random; import java.io.InputStream; import java.io.FileInputStream; -import java.io.FileNotFoundException; - /** * A generator that produces random CQL queries. *

* Why is that useful? Mainly to produce test-cases for CQL parsers - * (including the CQLParser class in this package): you can + * (including the CQLParser class in this package): you can * generate a random search tree, render it to XCQL and remember the * result. Then decompile the tree to CQL, feed the generated CQL to * the parser of your choice, and check that the XCQL it comes up with * is the same what you got from your initial rendering. *

- * This code is based on the same grammar as the CQLParser class in - * this distribution - there is a generate_x() method + * This code is based on the same grammar as the CQLParser class in + * this distribution - there is a generate_x() method * for each grammar element X. * * @see * @param params - * A Properties table containing configuration + * A Properties table containing configuration * parameters for the queries to be generated by this generator. - * Recognised parameters are: *

+ * Recognised parameters are: + *

*
- *
seed
+ *
seed
*
- * If specified, this is a long used to seed the + * If specified, this is a long used to seed the * random number generator, so that the CQL generator can be * run repeatably, giving the same results each time. If it's * omitted, then no seed is explicitly specified, and the * results of each run will be different (so long as you don't * run it more that 2^32 times :-) - *

*

- *
complexQuery
+ *
complexQuery
*
* [mandatory] A floating-point number between 0.0 and 1.0, - * indicating the probability for each cql-query node + * indicating the probability for each cql-query node * that it will be expanded into a ``complex query'' - * (cql-query boolean search-clause) rather - * than a search-clause. - *

+ * (cql-query boolean search-clause) rather + * than a search-clause. *

- *
complexClause
+ *
complexClause
*
* [mandatory] A floating-point number between 0.0 and 1.0, - * indicating the probability for each search-clause + * indicating the probability for each search-clause * node that it will be expanded into a full sub-query rather - * than an [ index relation ] term triplet. - *

+ * than an [ index relation ] term triplet. *

- *
proxOp
+ *
proxOp
*
* [mandatory] A floating-point number between 0.0 and 1.0, * indicating the probability that each boolean operator will * be chosen to be proximity operation; otherwise, the three - * simpler boolean operations (and, or and - * not) are chosen with equal probability. - *

+ * simpler boolean operations (and, or and + * not) are chosen with equal probability. *

- *
equalsRelation
+ *
equalsRelation
*
* [mandatory] A floating-point number between 0.0 and 1.0, * indicating the probability that each relation will be chosen - * to be = - this is treated as a special case, since + * to be = - this is treated as a special case, since * it's likely to be by far the most common relation in * ``real life'' searches. - *

*

- *
numericRelation
- *
+ *
numericRelation
+ *
q * [mandatory] A floating-point number between 0.0 and 1.0, * indicating the probability that a relation, having chosen - * not to be =, is instead chosen to be one of the six - * numeric relations (<, >, - * <=, >=, <> and - * =). - *

+ * not to be =, is instead chosen to be one of the six + * numeric relations (<, >, + * <=, >=, <> and + * =). *

*
*/ @@ -116,11 +108,11 @@ private static void debug(String str) { * when it was created. You are free to create as many random * queries as you wish from a single generator; each of them will * use the same parameters. - *

+ *

* @return - * A CQLNode that is the root of the generated tree. - * That tree may be rendered in XCQL using its toXCQL() - * method, or decompiled into CQL using its toCQL + * A CQLNode that is the root of the generated tree. + * That tree may be rendered in XCQL using its toXCQL() + * method, or decompiled into CQL using its toCQL * method. */ public CQLNode generate() throws MissingParameterException { @@ -264,9 +256,9 @@ boolean maybe(String param) throws MissingParameterException { * decompiles it into CQL which is written to standard output. *

* For example, - * java org.z3950.zing.cql.CQLGenerator - * etc/generate.properties seed 18398, - * where the file generate.properties contains:

+     * java org.z3950.zing.cql.CQLGenerator
+     *	etc/generate.properties seed 18398,
+     * where the file generate.properties contains:
      *	complexQuery=0.4
      *	complexClause=0.4
      *	equalsRelation=0.5
diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java
index cb990cd..4294b6f 100644
--- a/src/main/java/org/z3950/zing/cql/CQLLexer.java
+++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java
@@ -1,8 +1,3 @@
-/*
- * Copyright (c) 1995-2014, Index Datassss
- * All rights reserved.
- * See the file LICENSE for details.
- */
 package org.z3950.zing.cql;
 
 import java.io.BufferedReader;
diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java
index 221da44..b71ba1b 100644
--- a/src/main/java/org/z3950/zing/cql/CQLNode.java
+++ b/src/main/java/org/z3950/zing/cql/CQLNode.java
@@ -1,12 +1,10 @@
-
 package org.z3950.zing.cql;
+
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 
-
-
 /**
  * Represents a node in a CQL parse-tree.
  *
@@ -29,7 +27,6 @@ public String getResultSetName() {
 
     /**
      * Translates a parse-tree into an XCQL document.
-     * 

* @return * A String containing an XCQL document equivalent to the * parse-tree whose root is this node. @@ -79,7 +76,6 @@ static void renderSortKeys(XCQLBuilder b, int level, /** * Decompiles a parse-tree into a CQL query. - *

* @return * A String containing a CQL query equivalent to the parse-tree * whose root is this node, so that compiling that query will @@ -96,17 +92,20 @@ static void renderSortKeys(XCQLBuilder b, int level, * Chapter 7 (Supporting Tools) of the * YAZ manual. - *

* @param config - * A Properties object containing configuration + * A Properties object containing configuration * information that specifies the mapping from CQL indexes, * relations, etc. to Type-1 attributes. The mapping * specification is described in the CQL-Java distribution's * sample PQF-mapping configuration file, - * etc/pqf.properties, which see. + * etc/pqf.properties, which see. * @return * A String containing a PQF query equivalent to the parse-tree * whose root is this node. + * @throws PQFTranslationException + * If the parse-tree cannot be translated into PQF, for example + * because it contains a CQL relation that is not supported by the + * PQF configuration. */ abstract public String toPQF(Properties config) throws PQFTranslationException; @@ -118,17 +117,21 @@ abstract public String toPQF(Properties config) * primarily for SRW-to-Z39.50 gateways. * * @param config - * A Properties object containing configuration + * A Properties object containing configuration * information that specifies the mapping from CQL indexes, * relations, etc. to Type-1 attributes. The mapping * specification is described in the CQL-Java distribution's * sample PQF-mapping configuration file, - * etc/pqf.properties, which see. + * etc/pqf.properties, which see. * @return * A byte array containing the BER packet. * @see * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc + * @throws PQFTranslationException + * If the parse-tree cannot be translated into PQF, for example + * because it contains a CQL relation that is not supported by the + * PQF configuration. */ abstract public byte[] toType1BER(Properties config) throws PQFTranslationException; diff --git a/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java b/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java index 5f90cf6..bbd8452 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java +++ b/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java @@ -1,9 +1,3 @@ -/* - * Copyright (c) 1995-2014, Index Data - * All rights reserved. - * See the file LICENSE for details. - */ - package org.z3950.zing.cql; /** diff --git a/src/main/java/org/z3950/zing/cql/CQLNotNode.java b/src/main/java/org/z3950/zing/cql/CQLNotNode.java index 706f4c1..743c1a0 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNotNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNotNode.java @@ -1,7 +1,5 @@ - package org.z3950.zing.cql; - /** * Represents a NOT node in a CQL parse-tree. * diff --git a/src/main/java/org/z3950/zing/cql/CQLOrNode.java b/src/main/java/org/z3950/zing/cql/CQLOrNode.java index 295f303..32600c6 100644 --- a/src/main/java/org/z3950/zing/cql/CQLOrNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLOrNode.java @@ -1,7 +1,5 @@ - package org.z3950.zing.cql; - /** * Represents an OR node in a CQL parse-tree. * diff --git a/src/main/java/org/z3950/zing/cql/CQLParseException.java b/src/main/java/org/z3950/zing/cql/CQLParseException.java index ff1423f..311fa42 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParseException.java +++ b/src/main/java/org/z3950/zing/cql/CQLParseException.java @@ -1,7 +1,5 @@ - package org.z3950.zing.cql; - /** * Exception indicating that an error ocurred parsing CQL. * @@ -9,7 +7,7 @@ public class CQLParseException extends Exception { private int pos; /** - * Creates a new CQLParseException. + * Creates a new CQLParseException. * @param s * An error message describing the problem with the query, * usually a syntax error of some kind. diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index cbe64d5..93c7c10 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -1,4 +1,3 @@ - package org.z3950.zing.cql; import java.io.BufferedReader; @@ -12,7 +11,6 @@ import java.util.List; import java.util.Set; - /** * Compiles CQL strings into parse trees of CQLNode subtypes. * @@ -34,16 +32,16 @@ public class CQLParser { /** * The new parser implements a dialect of CQL specified by the - * compat argument: - *

    - *
  • V1POINT1 - CQL version 1.1 - *
  • - *
  • V1POINT2 - CQL version 1.2 - *
  • - *
  • V1POINT1SORT - CQL version 1.1 but including + * compat argument: + *
      + *
    • V1POINT1 - CQL version 1.1 + *
    • + *
    • V1POINT2 - CQL version 1.2 + *
    • + *
    • V1POINT1SORT - CQL version 1.1 but including * sortby as specified for CQL 1.2. - *
    • - *
    + *
  • + *
*/ public CQLParser(int compat) { this.compat = compat; @@ -100,10 +98,10 @@ public boolean unregisterCustomRelation(String relation) { * The resulting parse tree may be further processed by hand (see * the individual node-types' documentation for details on the * data structure) or, more often, simply rendered out in the - * desired form using one of the back-ends. toCQL() + * desired form using one of the back-ends. toCQL() * returns a decompiled CQL query equivalent to the one that was - * compiled in the first place; toXCQL() returns an - * XML snippet representing the query; and toPQF() + * compiled in the first place; toXCQL() returns an + * XML snippet representing the query; and toPQF() * returns the query rendered in Index Data's Prefix Query * Format. * @@ -403,7 +401,6 @@ private String matchSymbol(String expected) * </searchClause> * </triple> *
- *

* @param -1 * CQL version 1.1 (default version 1.2) * @param -d @@ -414,7 +411,7 @@ private String matchSymbol(String expected) * effect, the test harness acts as a query canonicaliser. * @return * The input query, either as XCQL [default] or CQL [if the - * -c option is supplied]. + * -c option is supplied]. */ public static void main (String[] args) { char mode = 'x'; // x=XCQL, c=CQL, p=PQF diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefix.java b/src/main/java/org/z3950/zing/cql/CQLPrefix.java index 64ed961..d9d8050 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefix.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefix.java @@ -1,4 +1,3 @@ - package org.z3950.zing.cql; /** @@ -11,8 +10,8 @@ public class CQLPrefix { /** * The short name of the prefix mapping. That is, the prefix - * itself, such as dc, as it might be used in an index - * like dc.title. + * itself, such as dc, as it might be used in an index + * like dc.title. */ public String getName() { return name; @@ -24,7 +23,7 @@ public String getName() { /** * The full identifier name of the prefix mapping. That is, * typically, a URI permanently allocated to a specific index - * set, such as http://zthes.z3950.org/cql/1.0. + * set, such as http://zthes.z3950.org/cql/1.0. */ public String getIdentifier() { return identifier; diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index 64e3103..1705aad 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -1,10 +1,9 @@ - package org.z3950.zing.cql; + import java.util.ArrayList; import java.util.List; import java.util.Properties; - /** * Represents a prefix node in a CQL parse-tree. * diff --git a/src/main/java/org/z3950/zing/cql/CQLProxNode.java b/src/main/java/org/z3950/zing/cql/CQLProxNode.java index b452e22..3e844ca 100644 --- a/src/main/java/org/z3950/zing/cql/CQLProxNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLProxNode.java @@ -1,7 +1,5 @@ - package org.z3950.zing.cql; - /** * Represents a proximity node in a CQL parse-tree. * The left- and right-hand-sides must be satisfied by parts of the diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 81fd38c..6f52eec 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -1,5 +1,5 @@ - package org.z3950.zing.cql; + import java.util.List; import java.util.Properties; @@ -13,10 +13,10 @@ public class CQLRelation extends CQLNode { /** * Creates a new CQLRelation with the specified base relation. * Typical base relations include the usual six ordering relations - * (<=, >, etc.), the text - * relations any, all and exact, the - * old server-choice relation scr and profiled relations of - * the form prefix.name. + * (<=, >, etc.), the text + * relations any, all and exact, the + * old server-choice relation scr and profiled relations of + * the form prefix.name. */ // ### Seems wrong: a modifier set should not have a base, a // relation should diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index efc190b..9aed194 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -1,10 +1,9 @@ - package org.z3950.zing.cql; + import java.util.ArrayList; import java.util.List; import java.util.Properties; - /** * Represents a sort node in a CQL parse-tree. * diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index 218a4aa..02a8229 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -1,5 +1,5 @@ - package org.z3950.zing.cql; + import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -18,9 +18,9 @@ public class CQLTermNode extends CQLNode { private String term; /** - * Creates a new term node with the specified index, - * relation and term. The first two may be - * null, but the term may not. + * Creates a new term node with the specified index, + * relation and term. The first two may be + * null, but the term may not. */ public CQLTermNode(String index, CQLRelation relation, String term) { this.index = index; diff --git a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java index 2d8b6b1..8542dd9 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java +++ b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java @@ -1,8 +1,3 @@ -/* - * Copyright (c) 1995-2014, Index Datassss - * All rights reserved. - * See the file LICENSE for details. - */ package org.z3950.zing.cql; /** diff --git a/src/main/java/org/z3950/zing/cql/MissingParameterException.java b/src/main/java/org/z3950/zing/cql/MissingParameterException.java index c953e42..b52b2cb 100644 --- a/src/main/java/org/z3950/zing/cql/MissingParameterException.java +++ b/src/main/java/org/z3950/zing/cql/MissingParameterException.java @@ -1,14 +1,12 @@ - package org.z3950.zing.cql; - /** * Exception indicating that a required property was not specified. * */ public class MissingParameterException extends Exception { /** - * Creates a new MissingParameterException. + * Creates a new MissingParameterException. * @param s * The name of the property whose value was required but not supplied. */ diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index 71232e9..af68453 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -1,9 +1,8 @@ - package org.z3950.zing.cql; /** * Represents a single modifier, consisting of three elements: a type, - * a comparision and a value. For example, "distance", "<", "3". The + * a comparision and a value. For example, "distance", "<", "3". The * type is mandatory; either the comparison and value must both occur, * or neither must. *

diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index da94b8c..754af1e 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -1,5 +1,5 @@ - package org.z3950.zing.cql; + import java.util.ArrayList; import java.util.List; @@ -9,10 +9,12 @@ * This class is used as a workhorse delegate by both CQLRelation and * CQLProxNode - two functionally very separate classes that happen to * require similar data structures and functionality. + *

*

* A ModifierSet consists of a ``base'' string together with a set of * zero or more type comparison value pairs, * where type, comparison and value are all strings. + *

* */ public class ModifierSet { @@ -35,8 +37,8 @@ public String getBase() { } /** - * Adds a modifier of the specified type, - * comparison and value to a ModifierSet. + * Adds a modifier of the specified type, + * comparison and value to a ModifierSet. */ public void addModifier(String type, String comparison, String value) { Modifier modifier = new Modifier(type, comparison, value); @@ -44,8 +46,8 @@ public void addModifier(String type, String comparison, String value) { } /** - * Adds a modifier of the specified type, but with no - * comparison and value, to a ModifierSet. + * Adds a modifier of the specified type, but with no + * comparison and value, to a ModifierSet. */ public void addModifier(String type) { Modifier modifier = new Modifier(type); diff --git a/src/main/java/org/z3950/zing/cql/PQFTranslationException.java b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java index f0d7dc2..a095776 100644 --- a/src/main/java/org/z3950/zing/cql/PQFTranslationException.java +++ b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java @@ -1,7 +1,5 @@ - package org.z3950.zing.cql; - /** * Base class for exceptions occurring when translating parse trees to PQF. * diff --git a/src/main/java/org/z3950/zing/cql/UnknownIndexException.java b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java index 01dce00..e460dfc 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownIndexException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java @@ -1,7 +1,5 @@ - package org.z3950.zing.cql; - /** * Exception indicating that an index was not recognised. * At compilation time, we accept any syntactically valid index; @@ -13,7 +11,7 @@ */ public class UnknownIndexException extends PQFTranslationException { /** - * Creates a new UnknownIndexException. + * Creates a new UnknownIndexException. * @param s * The index for which there was no PQF configuration. */ diff --git a/src/main/java/org/z3950/zing/cql/UnknownPositionException.java b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java index 649a7d0..c7d9c12 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownPositionException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java @@ -1,21 +1,19 @@ - package org.z3950.zing.cql; - /** * Exception indicating that a position was not recognised. * When rendering a tree out as PQF, each term is classified either as - * any, first, last or - * firstAndLast, depending on whether it begins and/or ends - * with the word-anchoring meta-character ^. Its - * classification is looked up as a position in the PQF + * any, first, last or + * firstAndLast, depending on whether it begins and/or ends + * with the word-anchoring meta-character ^. Its + * classification is looked up as a position in the PQF * configuration. If the position is not configured, we throw one of * these babies. * */ public class UnknownPositionException extends PQFTranslationException { /** - * Creates a new UnknownPositionException. + * Creates a new UnknownPositionException. * @param s * The position for which there was no PQF configuration. */ diff --git a/src/main/java/org/z3950/zing/cql/UnknownRelationException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java index 3a665d9..d4998b0 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownRelationException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java @@ -1,7 +1,5 @@ - package org.z3950.zing.cql; - /** * Exception indicating that a relation was not recognised. * At compilation time, we accept any syntactically valid relation; @@ -13,7 +11,7 @@ */ public class UnknownRelationException extends PQFTranslationException { /** - * Creates a new UnknownRelationException. + * Creates a new UnknownRelationException. * @param s * The relation for which there was no PQF configuration. */ diff --git a/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java index 2d3d6f2..b27d952 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java @@ -1,7 +1,5 @@ - package org.z3950.zing.cql; - /** * Exception indicating that a relation modifier was not recognised. * At compilation time, we accept any syntactically valid relation modifier; @@ -13,7 +11,7 @@ */ public class UnknownRelationModifierException extends PQFTranslationException { /** - * Creates a new UnknownRelationModifierException. + * Creates a new UnknownRelationModifierException. * @param s * The relation modifier for which there was no PQF configuration. */ diff --git a/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java b/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java index 3842e23..024fd2e 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java @@ -2,10 +2,10 @@ /** * Exception indicating that a truncation was not recognised. When rendering a - * tree out as PQF, each term is classified either as left, - * right, left and right truncated, depending on whether - * it begins and/or ends with the character *. Its - * classification is looked up as a truncation in the PQF + * tree out as PQF, each term is classified either as left, + * right, left and right truncated, depending on whether + * it begins and/or ends with the character *. Its + * classification is looked up as a truncation in the PQF * configuration. If the truncation is not configured, we throw one of these * babies. * @@ -14,7 +14,7 @@ public class UnknownTruncationException extends PQFTranslationException { private static final long serialVersionUID = 6971993723734811253L; /** - * Creates a new UnknownTruncationException. + * Creates a new UnknownTruncationException. * * @param s * The truncation for which there was no PQF configuration. diff --git a/src/main/java/org/z3950/zing/cql/XCQLBuilder.java b/src/main/java/org/z3950/zing/cql/XCQLBuilder.java index d59ce89..9b3d8fd 100644 --- a/src/main/java/org/z3950/zing/cql/XCQLBuilder.java +++ b/src/main/java/org/z3950/zing/cql/XCQLBuilder.java @@ -1,8 +1,3 @@ -/* - * Copyright (c) 1995-2011, Index Data - * All rights reserved. - * See the file LICENSE for details. - */ package org.z3950.zing.cql; /** diff --git a/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java b/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java index 3a83235..8324098 100644 --- a/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java +++ b/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java @@ -1,8 +1,3 @@ -/* - * Copyright (c) 1995-2016, Index Data - * All rights reserved. - * See the file LICENSE for details. - */ package org.z3950.zing.cql; import java.io.IOException; diff --git a/src/test/java/org/z3950/zing/cql/CQLParserTest.java b/src/test/java/org/z3950/zing/cql/CQLParserTest.java index 34d5999..ed0c1ab 100644 --- a/src/test/java/org/z3950/zing/cql/CQLParserTest.java +++ b/src/test/java/org/z3950/zing/cql/CQLParserTest.java @@ -1,23 +1,16 @@ -/* - * Copyright (c) 1995-2014, Index Datassss - * All rights reserved. - * See the file LICENSE for details. - */ package org.z3950.zing.cql; -import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; import java.util.Enumeration; import java.util.HashSet; +import java.util.Properties; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -26,10 +19,9 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.*; import static java.lang.System.out; -import java.util.Properties; /** * From f9fe79d6d86c3a9541a0f87b7aaea860d1cfbd43 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 24 Oct 2025 15:55:06 +0200 Subject: [PATCH 140/147] Retain escape sequences in lexer, fixes #5 (#21) Retain escape sequences in lexer, fixes #5 \\ is preserved in Lexer, leaving it to later stages to decide what masking is to be used. --- .../java/org/z3950/zing/cql/CQLGenerator.java | 2 +- src/main/java/org/z3950/zing/cql/CQLLexer.java | 16 ++++++---------- .../java/org/z3950/zing/cql/CQLTermNode.java | 2 +- src/test/resources/regression/06/03.xcql | 2 +- src/test/resources/regression/06/06.xcql | 2 +- src/test/resources/regression/12/01.xcql | 2 +- 6 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java index 2f21563..f22a7af 100644 --- a/src/main/java/org/z3950/zing/cql/CQLGenerator.java +++ b/src/main/java/org/z3950/zing/cql/CQLGenerator.java @@ -204,7 +204,7 @@ private String generate_base_relation() throws MissingParameterException { private String generate_term() { switch (rnd.nextInt(10)) { case 0: return "cat"; - case 1: return "\"cat\""; + case 1: return "\"cat\\\""; // A term with both bare quotes and escaped quotes case 2: return "comp.os.linux"; case 3: return "xml:element"; case 4: return ""; diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index 4294b6f..ff5aee3 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -69,19 +69,15 @@ else if (comp.equals("<>")) { //remember quote char char mark = c; qi++; - boolean escaped = false; buf.setLength(0); //reset buffer - while (qi < ql) { - if (!escaped && qs.charAt(qi) == mark) //terminator - break; - if (escaped && strchr("*?^\\", qs.charAt(qi))) //no escaping for d-quote - buf.append("\\"); - if (!escaped && qs.charAt(qi) == '\\') { //escape-char - escaped = true; + while (qi < ql && qs.charAt(qi) != mark) { + if (qs.charAt(qi) == '\\') { //escape-char + if (qi == ql - 1) { + break; //unterminated + } + buf.append(qs.charAt(qi)); qi++; - continue; } - escaped = false; //reset escape buf.append(qs.charAt(qi)); qi++; } diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index 02a8229..6fa042d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -229,7 +229,7 @@ static String maybeQuote(String str) { str.indexOf('/') != -1 || str.indexOf('(') != -1 || str.indexOf(')') != -1) { - str = '"' + str.replace("\"", "\\\"") + '"'; + str = '"' + str.replaceAll("(? = - ^cat says "fish" + ^cat says \"fish\" diff --git a/src/test/resources/regression/06/06.xcql b/src/test/resources/regression/06/06.xcql index 9d38695..2a0cd96 100644 --- a/src/test/resources/regression/06/06.xcql +++ b/src/test/resources/regression/06/06.xcql @@ -3,5 +3,5 @@ = - ^cat*fishdog"horse? + ^cat*fishdog\"horse? diff --git a/src/test/resources/regression/12/01.xcql b/src/test/resources/regression/12/01.xcql index c9fc4b6..b826cba 100644 --- a/src/test/resources/regression/12/01.xcql +++ b/src/test/resources/regression/12/01.xcql @@ -3,5 +3,5 @@ = - term\*\?\^ + te\rm\*\?\^ From 58ade030a56909315fafa348a60dfe7b879812bc Mon Sep 17 00:00:00 2001 From: David Crossley Date: Wed, 5 Nov 2025 16:10:13 +1100 Subject: [PATCH 141/147] Use actions/checkout v5 DEVOPS-2662 --- .github/workflows/mvn-verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mvn-verify.yaml b/.github/workflows/mvn-verify.yaml index 50853df..3cacf9d 100644 --- a/.github/workflows/mvn-verify.yaml +++ b/.github/workflows/mvn-verify.yaml @@ -5,7 +5,7 @@ jobs: mvn-verify: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up JDK 11 uses: actions/setup-java@v4 with: From 4472871ff9cedc96bc4e07e76795e5b4f17246ed Mon Sep 17 00:00:00 2001 From: David Crossley Date: Wed, 5 Nov 2025 16:10:38 +1100 Subject: [PATCH 142/147] Use actions/setup-java v5 DEVOPS-2662 --- .github/workflows/mvn-verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mvn-verify.yaml b/.github/workflows/mvn-verify.yaml index 3cacf9d..ffc7a46 100644 --- a/.github/workflows/mvn-verify.yaml +++ b/.github/workflows/mvn-verify.yaml @@ -7,7 +7,7 @@ jobs: steps: - uses: actions/checkout@v5 - name: Set up JDK 11 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: java-version: '11' distribution: 'temurin' From 3a6427a4dba53b592c556d3a6da7b97b7cdb56d0 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 17 Dec 2025 10:41:25 +0100 Subject: [PATCH 143/147] Specify GitHub as issue tracking (#23) --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index bb3d03f..9357503 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ mike mike@indexdata.com Index Data - https://www.indexdata.com/ + https://www.indexdata.com @@ -33,7 +33,7 @@ jakub jakub@indexdata.dk Index Data - https://www.indexdata.com/ + https://www.indexdata.com @@ -44,8 +44,8 @@ HEAD - Bugzilla - https://index-data.atlassian.net/browse/CQLJAVA + GitHub + https://github.com/indexdata/cql-java/issues From a4fe77bd36b018ed573d441348484f1d645c19cb Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 17 Dec 2025 11:34:20 +0100 Subject: [PATCH 144/147] Case insensitive relation check, fixes #17 (#24) Also, custom relations case-insensitive. --- .../java/org/z3950/zing/cql/CQLParser.java | 78 +++++++++---------- src/test/resources/regression/02/03.cql | 2 +- src/test/resources/regression/02/03.xcql | 2 +- src/test/resources/regression/09/06.cql | 2 +- src/test/resources/regression/09/06.xcql | 8 +- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 93c7c10..9256eef 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -21,7 +21,7 @@ public class CQLParser { private CQLTokenizer lexer; private final int compat; // When false, implement CQL 1.2 private final Set customRelations = new HashSet(); - + public static final int V1POINT1 = 12368; public static final int V1POINT2 = 12369; public static final int V1POINT1SORT = 12370; @@ -47,10 +47,10 @@ public CQLParser(int compat) { this.compat = compat; this.allowKeywordTerms = true; } - + /** - * Official CQL grammar allows registered keywords like 'and/or/not/sortby/prox' - * to be used unquoted in terms. This constructor allows to create an instance + * Official CQL grammar allows registered keywords like 'and/or/not/sortby/prox' + * to be used unquoted in terms. This constructor allows to create an instance * of a parser that prohibits this behavior while sacrificing compatibility. * @param compat CQL version compatibility * @param allowKeywordTerms when false registered keywords are disallowed in unquoted terms @@ -59,7 +59,7 @@ public CQLParser(int compat, boolean allowKeywordTerms) { this.compat = compat; this.allowKeywordTerms = allowKeywordTerms; } - + /** * The new parser implements CQL 1.2 */ @@ -72,24 +72,25 @@ private static void debug(String str) { if (DEBUG) System.err.println("PARSEDEBUG: " + str); } - + /** * Registers custom relation in this parser. Note that when a custom relation * is registered the parser is no longer strictly compliant with the chosen spec. + * Custom relations are case-insensitive. * @param relation * @return true if custom relation has not been registered already */ public boolean registerCustomRelation(String relation) { - return customRelations.add(relation); + return customRelations.add(relation.toLowerCase()); } - + /** * Unregisters previously registered custom relation in this instance of the parser. * @param relation * @return true is relation has been previously registered */ public boolean unregisterCustomRelation(String relation) { - return customRelations.remove(relation); + return customRelations.remove(relation.toLowerCase()); } /** @@ -117,7 +118,7 @@ public CQLNode parse(String cql) CQLNode root = parseTopLevelPrefixes("cql.serverChoice", new CQLRelation(compat == V1POINT2 ? "=" : "scr")); if (lexer.what() != CQLTokenizer.TT_EOF) - throw new CQLParseException("junk after end: " + lexer.render(), + throw new CQLParseException("junk after end: " + lexer.render(), lexer.pos()); return root; @@ -194,7 +195,7 @@ private ModifierSet gatherModifiers(String base) match('/'); if (lexer.what() != CQLTokenizer.TT_WORD) throw new CQLParseException("expected modifier, " - + "got " + lexer.render(), + + "got " + lexer.render(), lexer.pos()); String type = lexer.value().toLowerCase(); match(lexer.what()); @@ -241,7 +242,7 @@ private CQLNode parseTerm(String index, CQLRelation relation) if (!isRelation()) break; //we're done if no relation - + //render relation String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? lexer.value() : lexer.render(lexer.what(), false)); @@ -282,40 +283,39 @@ private CQLNode parsePrefix(String index, CQLRelation relation, return new CQLPrefixNode(name, identifier, node); } - + private boolean isWordOrString() { - return CQLTokenizer.TT_WORD == lexer.what() + return CQLTokenizer.TT_WORD == lexer.what() || CQLTokenizer.TT_STRING == lexer.what(); } private boolean isRelation() { - debug("isRelation: checking what()=" + lexer.what() + - " (" + lexer.render() + ")"); - if (lexer.what() == CQLTokenizer.TT_WORD && - (lexer.value().indexOf('.') >= 0 || - lexer.value().equals("any") || - lexer.value().equals("all") || - lexer.value().equals("within") || - lexer.value().equals("encloses") || - (lexer.value().equals("exact") && compat != V1POINT2) || - (lexer.value().equals("scr") && compat != V1POINT2) || - (lexer.value().equals("adj") && compat == V1POINT2) || - customRelations.contains(lexer.value()))) - return true; - + debug("isRelation: checking what()=" + lexer.what() + + " (" + lexer.render() + ")"); + if (lexer.what() == CQLTokenizer.TT_WORD) { + return lexer.value().indexOf('.') >= 0 || + lexer.value().equalsIgnoreCase("any") || + lexer.value().equalsIgnoreCase("all") || + lexer.value().equalsIgnoreCase("within") || + lexer.value().equalsIgnoreCase("encloses") || + (lexer.value().equalsIgnoreCase("exact") && compat != V1POINT2) || + (lexer.value().equalsIgnoreCase("scr") && compat != V1POINT2) || + (lexer.value().equalsIgnoreCase("adj") && compat == V1POINT2) || + customRelations.stream().anyMatch(r -> r.equalsIgnoreCase(lexer.value())); + } return isSymbolicRelation(); } private boolean isSymbolicRelation() { - debug("isSymbolicRelation: checking what()=" + lexer.what() + - " (" + lexer.render() + ")"); - return (lexer.what() == '<' || - lexer.what() == '>' || - lexer.what() == '=' || - lexer.what() == CQLTokenizer.TT_LE || - lexer.what() == CQLTokenizer.TT_GE || - lexer.what() == CQLTokenizer.TT_NE || - lexer.what() == CQLTokenizer.TT_EQEQ); + debug("isSymbolicRelation: checking what()=" + lexer.what() + + " (" + lexer.render() + ")"); + return (lexer.what() == '<' || + lexer.what() == '>' || + lexer.what() == '=' || + lexer.what() == CQLTokenizer.TT_LE || + lexer.what() == CQLTokenizer.TT_GE || + lexer.what() == CQLTokenizer.TT_NE || + lexer.what() == CQLTokenizer.TT_EQEQ); } private void match(int token) @@ -324,7 +324,7 @@ private void match(int token) if (lexer.what() != token) throw new CQLParseException("expected " + lexer.render(token, true) + - ", " + "got " + lexer.render(), + ", " + "got " + lexer.render(), lexer.pos()); lexer.move(); debug("match() got token=" + lexer.what() + ", value()='" + lexer.value() + "'"); @@ -500,7 +500,7 @@ public static void main (String[] args) { f.close(); System.out.println(root.toPQF(config)); } catch (IOException ex) { - System.err.println("Can't load PQF properties:" + + System.err.println("Can't load PQF properties:" + ex.getMessage()); System.exit(5); } diff --git a/src/test/resources/regression/02/03.cql b/src/test/resources/regression/02/03.cql index 553d2b8..b469c5f 100644 --- a/src/test/resources/regression/02/03.cql +++ b/src/test/resources/regression/02/03.cql @@ -1 +1 @@ -title any fish \ No newline at end of file +title Any fish diff --git a/src/test/resources/regression/02/03.xcql b/src/test/resources/regression/02/03.xcql index 62521be..8034b6a 100644 --- a/src/test/resources/regression/02/03.xcql +++ b/src/test/resources/regression/02/03.xcql @@ -1,7 +1,7 @@ title - any + Any fish diff --git a/src/test/resources/regression/09/06.cql b/src/test/resources/regression/09/06.cql index c1c8282..9e80bcb 100644 --- a/src/test/resources/regression/09/06.cql +++ b/src/test/resources/regression/09/06.cql @@ -1 +1 @@ -sortby sortby sortby sortby sortby \ No newline at end of file +Sortby Sortby Sortby Sortby Sortby \ No newline at end of file diff --git a/src/test/resources/regression/09/06.xcql b/src/test/resources/regression/09/06.xcql index 2e136b5..337cd16 100644 --- a/src/test/resources/regression/09/06.xcql +++ b/src/test/resources/regression/09/06.xcql @@ -3,16 +3,16 @@ = - sortby + Sortby - sortby + Sortby - sortby + Sortby - sortby + Sortby From adefe700fe488796d0932088e3613cdc97ffb539 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 30 Dec 2025 21:38:27 +0100 Subject: [PATCH 145/147] Reformat; add .editorconfig (#25) Consistently make indentation 4 for all Java sources with spaces. Most files were already using indentation of 4, but with mixes of tabs and spaces. --- .editorconfig | 12 + .../java/org/z3950/zing/cql/CQLAndNode.java | 22 +- .../java/org/z3950/zing/cql/CQLBoolean.java | 16 +- .../org/z3950/zing/cql/CQLBooleanNode.java | 53 +- .../z3950/zing/cql/CQLDefaultNodeVisitor.java | 59 +- .../java/org/z3950/zing/cql/CQLGenerator.java | 433 ++++++------ .../java/org/z3950/zing/cql/CQLLexer.java | 349 +++++----- src/main/java/org/z3950/zing/cql/CQLNode.java | 340 ++++----- .../org/z3950/zing/cql/CQLNodeVisitor.java | 31 +- .../java/org/z3950/zing/cql/CQLNotNode.java | 16 +- .../java/org/z3950/zing/cql/CQLOrNode.java | 14 +- .../org/z3950/zing/cql/CQLParseException.java | 16 +- .../java/org/z3950/zing/cql/CQLParser.java | 645 +++++++++--------- .../java/org/z3950/zing/cql/CQLPrefix.java | 9 +- .../org/z3950/zing/cql/CQLPrefixNode.java | 50 +- .../java/org/z3950/zing/cql/CQLProxNode.java | 171 +++-- .../java/org/z3950/zing/cql/CQLRelation.java | 29 +- .../java/org/z3950/zing/cql/CQLSortNode.java | 52 +- .../java/org/z3950/zing/cql/CQLTermNode.java | 529 +++++++------- .../java/org/z3950/zing/cql/CQLTokenizer.java | 103 +-- .../zing/cql/MissingParameterException.java | 5 +- .../java/org/z3950/zing/cql/Modifier.java | 37 +- .../java/org/z3950/zing/cql/ModifierSet.java | 85 ++- .../zing/cql/PQFTranslationException.java | 2 +- .../z3950/zing/cql/UnknownIndexException.java | 7 +- .../zing/cql/UnknownPositionException.java | 9 +- .../zing/cql/UnknownRelationException.java | 7 +- .../cql/UnknownRelationModifierException.java | 7 +- .../zing/cql/UnknownTruncationException.java | 23 +- .../java/org/z3950/zing/cql/XCQLBuilder.java | 73 +- .../z3950/zing/cql/CQLNodeVisitorTest.java | 224 +++--- .../org/z3950/zing/cql/CQLParserTest.java | 340 ++++----- 32 files changed, 1957 insertions(+), 1811 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..dc3a3a1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# EditorConfig is awesome: https://EditorConfig.org +root = true + +[*.java] +charset = utf-8 +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true +insert_final_newline = true + +[*] +trim_trailing_whitespace = true diff --git a/src/main/java/org/z3950/zing/cql/CQLAndNode.java b/src/main/java/org/z3950/zing/cql/CQLAndNode.java index ecff58d..057802c 100644 --- a/src/main/java/org/z3950/zing/cql/CQLAndNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLAndNode.java @@ -1,6 +1,5 @@ package org.z3950.zing.cql; - /** * Represents an AND node in a CQL parse-tree. * @@ -9,26 +8,27 @@ public class CQLAndNode extends CQLBooleanNode { /** * Creates a new AND node with the specified left- and right-hand * sides and modifiers. - * @param left the left-hand side of the AND + * + * @param left the left-hand side of the AND * @param right the right-hand side of the AND - * @param ms the modifiers to apply to this AND + * @param ms the modifiers to apply to this AND * @see ModifierSet * @see CQLNode * @see CQLBoolean * @see CQLBooleanNode */ public CQLAndNode(CQLNode left, CQLNode right, ModifierSet ms) { - super(left, right, ms, CQLBoolean.AND); - } + super(left, right, ms, CQLBoolean.AND); + } // ### Too much code duplication here with OR and NOT @Override byte[] opType1() { - byte[] op = new byte[5]; - putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator - putLen(2, op, 2); - putTag(CONTEXT, 0, PRIMITIVE, op, 3); // and - putLen(0, op, 4); - return op; + byte[] op = new byte[5]; + putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator + putLen(2, op, 2); + putTag(CONTEXT, 0, PRIMITIVE, op, 3); // and + putLen(0, op, 4); + return op; } } diff --git a/src/main/java/org/z3950/zing/cql/CQLBoolean.java b/src/main/java/org/z3950/zing/cql/CQLBoolean.java index bab541b..37dad7e 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBoolean.java +++ b/src/main/java/org/z3950/zing/cql/CQLBoolean.java @@ -5,12 +5,12 @@ * @author jakub */ public enum CQLBoolean { - /** AND is the same as CQL's "and" */ - AND, - /** OR is the same as CQL's "or" */ - OR, - /** NOT is the same as CQL's "not" */ - NOT, - /** PROX is the same as CQL's "prox" */ - PROX; + /** AND is the same as CQL's "and" */ + AND, + /** OR is the same as CQL's "or" */ + OR, + /** NOT is the same as CQL's "not" */ + NOT, + /** PROX is the same as CQL's "prox" */ + PROX; } diff --git a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java index 6d903bf..fee6916 100644 --- a/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLBooleanNode.java @@ -13,11 +13,12 @@ public abstract class CQLBooleanNode extends CQLNode { public CQLBoolean getOperator() { return operator; } - + private CQLNode left; /** * The root of a parse-tree representing the left-hand side. + * * @return the left operand of this boolean node */ public CQLNode getLeftOperand() { @@ -28,6 +29,7 @@ public CQLNode getLeftOperand() { /** * The root of a parse-tree representing the right-hand side. + * * @return the right operand of this boolean node */ public CQLNode getRightOperand() { @@ -38,6 +40,7 @@ public CQLNode getRightOperand() { /** * The set of modifiers that are applied to this boolean. + * * @return a list of Modifier objects, which may be empty. */ public List getModifiers() { @@ -45,25 +48,25 @@ public List getModifiers() { } protected CQLBooleanNode(CQLNode left, CQLNode right, ModifierSet ms, CQLBoolean operator) { - this.left = left; - this.right = right; - this.ms = ms; + this.left = left; + this.right = right; + this.ms = ms; this.operator = operator; } @Override public void traverse(CQLNodeVisitor visitor) { - visitor.onBooleanNodeStart(this); - left.traverse(visitor); - visitor.onBooleanNodeOp(this); - right.traverse(visitor); - visitor.onBooleanNodeEnd(this); + visitor.onBooleanNodeStart(this); + left.traverse(visitor); + visitor.onBooleanNodeOp(this); + right.traverse(visitor); + visitor.onBooleanNodeEnd(this); } @Override void toXCQLInternal(XCQLBuilder b, int level, - List prefixes, List sortkeys) { - b.indent(level).append("\n"); + List prefixes, List sortkeys) { + b.indent(level).append("\n"); renderPrefixes(b, level + 1, prefixes); ms.toXCQLInternal(b, level + 1, "boolean", "value"); b.indent(level + 1).append("\n"); @@ -78,35 +81,37 @@ void toXCQLInternal(XCQLBuilder b, int level, @Override public String toCQL() { - // ### We don't always need parens around the operands - return ("(" + left.toCQL() + ")" + - " " + ms.toCQL() + " " + - "(" + right.toCQL() + ")"); + // ### We don't always need parens around the operands + return ("(" + left.toCQL() + ")" + + " " + ms.toCQL() + " " + + "(" + right.toCQL() + ")"); } @Override public String toPQF(Properties config) throws PQFTranslationException { - return ("@" + opPQF() + - " " + left.toPQF(config) + - " " + right.toPQF(config)); + return ("@" + opPQF() + + " " + left.toPQF(config) + + " " + right.toPQF(config)); } // represents the operation for PQF: overridden for CQLProxNode - String opPQF() { return ms.getBase(); } + String opPQF() { + return ms.getBase(); + } @Override public byte[] toType1BER(Properties config) throws PQFTranslationException { System.out.println("in CQLBooleanNode.toType1BER(): PQF=" + - toPQF(config)); + toPQF(config)); byte[] rpn1 = left.toType1BER(config); byte[] rpn2 = right.toType1BER(config); byte[] op = opType1(); - byte[] rpnStructure = new byte[rpn1.length+rpn2.length+op.length+4]; - - // rpnRpnOp + byte[] rpnStructure = new byte[rpn1.length + rpn2.length + op.length + 4]; + + // rpnRpnOp int offset = putTag(CONTEXT, 1, CONSTRUCTED, rpnStructure, 0); - rpnStructure[offset++] = (byte)(0x80&0xff); // indefinite length + rpnStructure[offset++] = (byte) (0x80 & 0xff); // indefinite length System.arraycopy(rpn1, 0, rpnStructure, offset, rpn1.length); offset += rpn1.length; System.arraycopy(rpn2, 0, rpnStructure, offset, rpn2.length); diff --git a/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java b/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java index 9c0b744..543cde3 100644 --- a/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java +++ b/src/main/java/org/z3950/zing/cql/CQLDefaultNodeVisitor.java @@ -2,36 +2,37 @@ /** * Query tree visitor with default (no-op) implementation + * * @author jakub */ public class CQLDefaultNodeVisitor implements CQLNodeVisitor { - - @Override - public void onSortNode(CQLSortNode node) { - } - - @Override - public void onPrefixNode(CQLPrefixNode node) { - } - - @Override - public void onBooleanNodeStart(CQLBooleanNode node) { - } - - @Override - public void onBooleanNodeOp(CQLBooleanNode node) { - } - - @Override - public void onBooleanNodeEnd(CQLBooleanNode node) { - } - - @Override - public void onTermNode(CQLTermNode node) { - } - - @Override - public void onRelation(CQLRelation relation) { - } - + + @Override + public void onSortNode(CQLSortNode node) { + } + + @Override + public void onPrefixNode(CQLPrefixNode node) { + } + + @Override + public void onBooleanNodeStart(CQLBooleanNode node) { + } + + @Override + public void onBooleanNodeOp(CQLBooleanNode node) { + } + + @Override + public void onBooleanNodeEnd(CQLBooleanNode node) { + } + + @Override + public void onTermNode(CQLTermNode node) { + } + + @Override + public void onRelation(CQLRelation relation) { + } + } diff --git a/src/main/java/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java index f22a7af..110406e 100644 --- a/src/main/java/org/z3950/zing/cql/CQLGenerator.java +++ b/src/main/java/org/z3950/zing/cql/CQLGenerator.java @@ -8,10 +8,10 @@ /** * A generator that produces random CQL queries. *

- * Why is that useful? Mainly to produce test-cases for CQL parsers + * Why is that useful? Mainly to produce test-cases for CQL parsers * (including the CQLParser class in this package): you can * generate a random search tree, render it to XCQL and remember the - * result. Then decompile the tree to CQL, feed the generated CQL to + * result. Then decompile the tree to CQL, feed the generated CQL to * the parser of your choice, and check that the XCQL it comes up with * is the same what you got from your initial rendering. *

@@ -19,8 +19,8 @@ * this distribution - there is a generate_x() method * for each grammar element X. * - * @see http://zing.z3950.org/cql/index.html + * @see http://zing.z3950.org/cql/index.html */ public class CQLGenerator { private Properties params; @@ -29,223 +29,264 @@ public class CQLGenerator { /** * Creates a new CQL generator with the specified parameters. + * * @param params - * A Properties table containing configuration - * parameters for the queries to be generated by this generator. - *

- * Recognised parameters are: - *

- *
- *
seed
- *
- * If specified, this is a long used to seed the - * random number generator, so that the CQL generator can be - * run repeatably, giving the same results each time. If it's - * omitted, then no seed is explicitly specified, and the - * results of each run will be different (so long as you don't - * run it more that 2^32 times :-) - *
- *
complexQuery
- *
- * [mandatory] A floating-point number between 0.0 and 1.0, - * indicating the probability for each cql-query node - * that it will be expanded into a ``complex query'' - * (cql-query boolean search-clause) rather - * than a search-clause. - *
- *
complexClause
- *
- * [mandatory] A floating-point number between 0.0 and 1.0, - * indicating the probability for each search-clause - * node that it will be expanded into a full sub-query rather - * than an [ index relation ] term triplet. - *
- *
proxOp
- *
- * [mandatory] A floating-point number between 0.0 and 1.0, - * indicating the probability that each boolean operator will - * be chosen to be proximity operation; otherwise, the three - * simpler boolean operations (and, or and - * not) are chosen with equal probability. - *
- *
equalsRelation
- *
- * [mandatory] A floating-point number between 0.0 and 1.0, - * indicating the probability that each relation will be chosen - * to be = - this is treated as a special case, since - * it's likely to be by far the most common relation in - * ``real life'' searches. - *
- *
numericRelation
- *
q - * [mandatory] A floating-point number between 0.0 and 1.0, - * indicating the probability that a relation, having chosen - * not to be =, is instead chosen to be one of the six - * numeric relations (<, >, - * <=, >=, <> and - * =). - *
- *
+ * A Properties table containing configuration + * parameters for the queries to be generated by this generator. + *

+ * Recognised parameters are: + *

+ *
+ *
seed
+ *
+ * If specified, this is a long used to seed the + * random number generator, so that the CQL generator can be + * run repeatably, giving the same results each time. If it's + * omitted, then no seed is explicitly specified, and the + * results of each run will be different (so long as you don't + * run it more that 2^32 times :-) + *
+ *
complexQuery
+ *
+ * [mandatory] A floating-point number between 0.0 and 1.0, + * indicating the probability for each cql-query node + * that it will be expanded into a ``complex query'' + * (cql-query boolean search-clause) rather + * than a search-clause. + *
+ *
complexClause
+ *
+ * [mandatory] A floating-point number between 0.0 and 1.0, + * indicating the probability for each search-clause + * node that it will be expanded into a full sub-query rather + * than an [ index relation ] term triplet. + *
+ *
proxOp
+ *
+ * [mandatory] A floating-point number between 0.0 and 1.0, + * indicating the probability that each boolean operator will + * be chosen to be proximity operation; otherwise, the three + * simpler boolean operations (and, or + * and + * not) are chosen with equal probability. + *
+ *
equalsRelation
+ *
+ * [mandatory] A floating-point number between 0.0 and 1.0, + * indicating the probability that each relation will be chosen + * to be = - this is treated as a special case, since + * it's likely to be by far the most common relation in + * ``real life'' searches. + *
+ *
numericRelation
+ *
q + * [mandatory] A floating-point number between 0.0 and 1.0, + * indicating the probability that a relation, having chosen + * not to be =, is instead chosen to be one of the + * six + * numeric relations (<, >, + * <=, >=, <> + * and + * =). + *
+ *
*/ public CQLGenerator(Properties params) { - this.params = params; - String seed = params.getProperty("seed"); - if (seed != null) - rnd = new Random(new Long(seed).longValue()); - else - rnd = new Random(); + this.params = params; + String seed = params.getProperty("seed"); + if (seed != null) { + rnd = new Random(Long.parseLong(seed)); + } else { + rnd = new Random(); + } } private static void debug(String str) { - if (DEBUG) - System.err.println("DEBUG: " + str); + if (DEBUG) + System.err.println("DEBUG: " + str); } - /** + /** * Generates a single random CQL query. *

* Uses the parameters that were associated with the generator - * when it was created. You are free to create as many random + * when it was created. You are free to create as many random * queries as you wish from a single generator; each of them will * use the same parameters. *

+ * * @return - * A CQLNode that is the root of the generated tree. - * That tree may be rendered in XCQL using its toXCQL() - * method, or decompiled into CQL using its toCQL - * method. + * A CQLNode that is the root of the generated tree. + * That tree may be rendered in XCQL using its toXCQL() + * method, or decompiled into CQL using its toCQL + * method. */ public CQLNode generate() throws MissingParameterException { - return generate_cql_query(); + return generate_cql_query(); } private CQLNode generate_cql_query() throws MissingParameterException { - if (!maybe("complexQuery")) { - return generate_search_clause(); - } + if (!maybe("complexQuery")) { + return generate_search_clause(); + } - CQLNode node1 = generate_cql_query(); - CQLNode node2 = generate_search_clause(); - // ### should generate prefix-mapping nodes - if (maybe("proxOp")) { - // ### generate proximity nodes - } else { - switch (rnd.nextInt(3)) { - case 0: return new CQLAndNode(node1, node2, new ModifierSet("and")); - case 1: return new CQLOrNode (node1, node2, new ModifierSet("or")); - case 2: return new CQLNotNode(node1, node2, new ModifierSet("not")); - } - } + CQLNode node1 = generate_cql_query(); + CQLNode node2 = generate_search_clause(); + // ### should generate prefix-mapping nodes + if (maybe("proxOp")) { + // ### generate proximity nodes + } else { + switch (rnd.nextInt(3)) { + case 0: + return new CQLAndNode(node1, node2, new ModifierSet("and")); + case 1: + return new CQLOrNode(node1, node2, new ModifierSet("or")); + case 2: + return new CQLNotNode(node1, node2, new ModifierSet("not")); + } + } - return generate_search_clause(); + return generate_search_clause(); } private CQLNode generate_search_clause() throws MissingParameterException { - if (maybe("complexClause")) { - return generate_cql_query(); - } + if (maybe("complexClause")) { + return generate_cql_query(); + } - // ### Should sometimes generate index/relation-free terms - String index = generate_index(); - CQLRelation relation = generate_relation(); - String term = generate_term(); + // ### Should sometimes generate index/relation-free terms + String index = generate_index(); + CQLRelation relation = generate_relation(); + String term = generate_term(); - return new CQLTermNode(index, relation, term); + return new CQLTermNode(index, relation, term); } // ### Should probably be more configurable private String generate_index() { - String index = ""; // shut up compiler warning - if (rnd.nextInt(2) == 0) { - switch (rnd.nextInt(3)) { - case 0: index = "dc.author"; break; - case 1: index = "dc.title"; break; - case 2: index = "dc.subject"; break; - } - } else { - switch (rnd.nextInt(4)) { - case 0: index = "bath.author"; break; - case 1: index = "bath.title"; break; - case 2: index = "bath.subject"; break; - case 3: index = "foo>bar"; break; - } - } + String index = ""; // shut up compiler warning + if (rnd.nextInt(2) == 0) { + switch (rnd.nextInt(3)) { + case 0: + index = "dc.author"; + break; + case 1: + index = "dc.title"; + break; + case 2: + index = "dc.subject"; + break; + } + } else { + switch (rnd.nextInt(4)) { + case 0: + index = "bath.author"; + break; + case 1: + index = "bath.title"; + break; + case 2: + index = "bath.subject"; + break; + case 3: + index = "foo>bar"; + break; + } + } - return index; + return index; } private CQLRelation generate_relation() throws MissingParameterException { - String base = generate_base_relation(); - CQLRelation rel = new CQLRelation(base); - // ### should generate modifiers too - return rel; + String base = generate_base_relation(); + CQLRelation rel = new CQLRelation(base); + // ### should generate modifiers too + return rel; } private String generate_base_relation() throws MissingParameterException { - if (maybe("equalsRelation")) { - return "="; - } else if (maybe("numericRelation")) { - return generate_numeric_relation(); - } else { - switch (rnd.nextInt(3)) { - case 0: return "within"; - case 1: return "all"; - case 2: return "any"; - } - } + if (maybe("equalsRelation")) { + return "="; + } else if (maybe("numericRelation")) { + return generate_numeric_relation(); + } else { + switch (rnd.nextInt(3)) { + case 0: + return "within"; + case 1: + return "all"; + case 2: + return "any"; + } + } - // NOTREACHED - return ""; // shut up compiler warning + // NOTREACHED + return ""; // shut up compiler warning } // ### could read candidate terms from /usr/dict/words // ### should introduce wildcard characters // ### should generate multi-word terms private String generate_term() { - switch (rnd.nextInt(10)) { - case 0: return "cat"; - case 1: return "\"cat\\\""; // A term with both bare quotes and escaped quotes - case 2: return "comp.os.linux"; - case 3: return "xml:element"; - case 4: return ""; - case 5: return "prox/word/>=/5"; - case 6: return ""; - case 7: return "frog fish"; - case 8: return "the complete dinosaur"; - case 9: return "foo*bar"; - } + switch (rnd.nextInt(10)) { + case 0: + return "cat"; + case 1: + return "\"cat\\\""; // A term with both bare quotes and escaped quotes + case 2: + return "comp.os.linux"; + case 3: + return "xml:element"; + case 4: + return ""; + case 5: + return "prox/word/>=/5"; + case 6: + return ""; + case 7: + return "frog fish"; + case 8: + return "the complete dinosaur"; + case 9: + return "foo*bar"; + } - // NOTREACHED - return ""; // shut up compiler warning + // NOTREACHED + return ""; // shut up compiler warning } private String generate_numeric_relation() { - switch (rnd.nextInt(6)) { - case 0: return "<"; - case 1: return ">"; - case 2: return "<="; - case 3: return ">="; - case 4: return "<>"; - case 5: return "="; - } + switch (rnd.nextInt(6)) { + case 0: + return "<"; + case 1: + return ">"; + case 2: + return "<="; + case 3: + return ">="; + case 4: + return "<>"; + case 5: + return "="; + } - // NOTREACHED - return ""; // shut up compiler warning + // NOTREACHED + return ""; // shut up compiler warning } boolean maybe(String param) throws MissingParameterException { - String probability = params.getProperty(param); - if (probability == null) - throw new MissingParameterException(param); - - double dice = rnd.nextDouble(); - double threshhold = new Double(probability).doubleValue(); - boolean res = dice < threshhold; - debug("dice=" + String.valueOf(dice).substring(0, 8) + - " vs. " + threshhold + "='" + param + "': " + res); - return res; - } + String probability = params.getProperty(param); + if (probability == null) + throw new MissingParameterException(param); + double dice = rnd.nextDouble(); + double threshhold = Double.parseDouble(probability); + boolean res = dice < threshhold; + debug("dice=" + String.valueOf(dice).substring(0, 8) + + " vs. " + threshhold + "='" + param + "': " + res); + return res; + } /** * A simple test-harness for the generator. @@ -258,47 +299,53 @@ boolean maybe(String param) throws MissingParameterException { * For example, * java org.z3950.zing.cql.CQLGenerator * etc/generate.properties seed 18398, - * where the file generate.properties contains:
+     * where the file generate.properties contains:
+     *
+     * 
      *	complexQuery=0.4
      *	complexClause=0.4
      *	equalsRelation=0.5
      *	numericRelation=0.7
      *	proxOp=0.0
      * 
- * yields:
+     *
+     * yields:
+     *
+     * 
      *	((dc.author = "<xml.element>") or (bath.title = cat)) and
      *		(dc.subject >= "the complete dinosaur")
      * 
*

+ * * @param configFile - * The name of a properties file from which to read the - * configuration parameters (see above). + * The name of a properties file from which to read the + * configuration parameters (see above). * @param name - * The name of a configuration parameter. + * The name of a configuration parameter. * @param value - * The value to assign to the configuration parameter named in - * the immediately preceding command-line argument. + * The value to assign to the configuration parameter named in + * the immediately preceding command-line argument. * @return - * A CQL query expressed in a form that should be comprehensible - * to all conformant CQL compilers. + * A CQL query expressed in a form that should be comprehensible + * to all conformant CQL compilers. */ - public static void main (String[] args) throws Exception { - if (args.length % 2 != 1) { - System.err.println("Usage: CQLGenerator "+ - "[ ]..."); - System.exit(1); - } + public static void main(String[] args) throws Exception { + if (args.length % 2 != 1) { + System.err.println("Usage: CQLGenerator " + + "[ ]..."); + System.exit(1); + } + + String configFile = args[0]; + InputStream f = new FileInputStream(configFile); + Properties params = new Properties(); + params.load(f); + f.close(); + for (int i = 1; i < args.length; i += 2) + params.setProperty(args[i], args[i + 1]); - String configFile = args[0]; - InputStream f = new FileInputStream(configFile); - Properties params = new Properties(); - params.load(f); - f.close(); - for (int i = 1; i < args.length; i += 2) - params.setProperty(args[i], args[i+1]); - - CQLGenerator generator = new CQLGenerator(params); - CQLNode tree = generator.generate(); - System.out.println(tree.toCQL()); + CQLGenerator generator = new CQLGenerator(params); + CQLNode tree = generator.generate(); + System.out.println(tree.toCQL()); } } diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index ff5aee3..c27ba40 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -6,197 +6,200 @@ /** * Implementation of the CQL lexical syntax analyzer + * * @author jakub */ public class CQLLexer implements CQLTokenizer { - private String qs; - private int qi; - private int ql; - private int what = TT_NOTHING; - private String val; - private String lval; - private StringBuilder buf = new StringBuilder(); + private String qs; + private int qi; + private int ql; + private int what = TT_NOTHING; + private String val; + private String lval; + private StringBuilder buf = new StringBuilder(); - public CQLLexer(String cql, boolean debug) { - qs = cql; - ql = cql.length(); - } - - @Override - public void move() { - //eat whitespace - while (qi < ql && strchr(" \t\r\n", qs.charAt(qi))) - qi++; - //eof - if (qi == ql) { - what = TT_EOF; - return; + public CQLLexer(String cql, boolean debug) { + qs = cql; + ql = cql.length(); } - //current char - char c = qs.charAt(qi); - //separators - if (strchr("()/", c)) { - what = c; - qi++; - //comparitor - } else if (strchr("<>=", c)) { - what = c; - qi++; - //two-char comparitor - if (qi < ql) { - char d = qs.charAt(qi); - String comp = String.valueOf((char) c) + String.valueOf((char) d); - if (comp.equals("==")) { - what = TT_EQEQ; - qi++; - } - else if (comp.equals("<=")) { - what = TT_LE; - qi++; - } - else if (comp.equals(">=")) { - what = TT_GE; - qi++; - } - else if (comp.equals("<>")) { - what = TT_NE; - qi++; + + @Override + public void move() { + // eat whitespace + while (qi < ql && strchr(" \t\r\n", qs.charAt(qi))) + qi++; + // eof + if (qi == ql) { + what = TT_EOF; + return; } - } - //quoted string - } else if (strchr("\"", c)) { //no single-quotes - what = TT_STRING; - //remember quote char - char mark = c; - qi++; - buf.setLength(0); //reset buffer - while (qi < ql && qs.charAt(qi) != mark) { - if (qs.charAt(qi) == '\\') { //escape-char - if (qi == ql - 1) { - break; //unterminated - } - buf.append(qs.charAt(qi)); - qi++; + // current char + char c = qs.charAt(qi); + // separators + if (strchr("()/", c)) { + what = c; + qi++; + // comparitor + } else if (strchr("<>=", c)) { + what = c; + qi++; + // two-char comparitor + if (qi < ql) { + char d = qs.charAt(qi); + String comp = String.valueOf((char) c) + String.valueOf((char) d); + if (comp.equals("==")) { + what = TT_EQEQ; + qi++; + } else if (comp.equals("<=")) { + what = TT_LE; + qi++; + } else if (comp.equals(">=")) { + what = TT_GE; + qi++; + } else if (comp.equals("<>")) { + what = TT_NE; + qi++; + } + } + // quoted string + } else if (strchr("\"", c)) { // no single-quotes + what = TT_STRING; + // remember quote char + char mark = c; + qi++; + buf.setLength(0); // reset buffer + while (qi < ql && qs.charAt(qi) != mark) { + if (qs.charAt(qi) == '\\') { // escape-char + if (qi == ql - 1) { + break; // unterminated + } + buf.append(qs.charAt(qi)); + qi++; + } + buf.append(qs.charAt(qi)); + qi++; + } + val = buf.toString(); + lval = val.toLowerCase(); + if (qi < ql) + qi++; + else // unterminated + what = TT_EOF; // notify error + // unquoted string + } else { + what = TT_WORD; + buf.setLength(0); // reset buffer + while (qi < ql + && !strchr("()/<>= \t\r\n", qs.charAt(qi))) { + buf.append(qs.charAt(qi)); + qi++; + } + val = buf.toString(); + lval = val.toLowerCase(); + if (lval.equals("or")) + what = TT_OR; + else if (lval.equals("and")) + what = TT_AND; + else if (lval.equals("not")) + what = TT_NOT; + else if (lval.equals("prox")) + what = TT_PROX; + else if (lval.equals("sortby")) + what = TT_SORTBY; } - buf.append(qs.charAt(qi)); - qi++; - } - val = buf.toString(); - lval = val.toLowerCase(); - if (qi < ql) - qi++; - else //unterminated - what = TT_EOF; //notify error - //unquoted string - } else { - what = TT_WORD; - buf.setLength(0); //reset buffer - while (qi < ql - && !strchr("()/<>= \t\r\n", qs.charAt(qi))) { - buf.append(qs.charAt(qi)); - qi++; - } - val = buf.toString(); - lval = val.toLowerCase(); - if (lval.equals("or")) what = TT_OR; - else if (lval.equals("and")) what = TT_AND; - else if (lval.equals("not")) what = TT_NOT; - else if (lval.equals("prox")) what = TT_PROX; - else if (lval.equals("sortby")) what = TT_SORTBY; } - } - private boolean strchr(String s, char ch) { - return s.indexOf(ch) >= 0; - } + private boolean strchr(String s, char ch) { + return s.indexOf(ch) >= 0; + } - @Override - public String value() { - return val; - } + @Override + public String value() { + return val; + } - @Override - public int what() { - return what; - } + @Override + public int what() { + return what; + } - @Override - public String render() { - return render(what, true); - } + @Override + public String render() { + return render(what, true); + } - @Override - public String render(int token, boolean quoteChars) { - switch (token) { - case TT_EOF: - return "EOF"; - case TT_WORD: - return "word: '" + val + "'"; - case TT_STRING: - return "string: \"" + val + "\""; - case TT_LE: - return "<="; - case TT_GE: - return ">="; - case TT_NE: - return "<>"; - case TT_EQEQ: - return "=="; - case TT_AND: - return "and"; - case TT_NOT: - return "not"; - case TT_OR: - return "or"; - case TT_PROX: - return "prox"; - case TT_SORTBY: - return "sortby"; - default: - //a single character, such as '(' or '/' or relation - String res = String.valueOf((char) token); - if (quoteChars) - res = "'" + res + "'"; - return res; + @Override + public String render(int token, boolean quoteChars) { + switch (token) { + case TT_EOF: + return "EOF"; + case TT_WORD: + return "word: '" + val + "'"; + case TT_STRING: + return "string: \"" + val + "\""; + case TT_LE: + return "<="; + case TT_GE: + return ">="; + case TT_NE: + return "<>"; + case TT_EQEQ: + return "=="; + case TT_AND: + return "and"; + case TT_NOT: + return "not"; + case TT_OR: + return "or"; + case TT_PROX: + return "prox"; + case TT_SORTBY: + return "sortby"; + default: + // a single character, such as '(' or '/' or relation + String res = String.valueOf((char) token); + if (quoteChars) + res = "'" + res + "'"; + return res; + } } - } - @Override - public int pos() { - return qi; - } - - public static void main(String[] args) throws Exception { - if (args.length > 1) { - System.err.println("Usage: CQLLexer []"); - System.err.println("If unspecified, query is read from stdin"); - System.exit(1); + @Override + public int pos() { + return qi; } - String cql; - if (args.length == 1) { - cql = args[0]; - } else { - BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); - try { - // read a single line of input - cql = buff.readLine(); - if (cql == null) { - System.err.println("Can't read query from stdin"); - System.exit(2); - return; + public static void main(String[] args) throws Exception { + if (args.length > 1) { + System.err.println("Usage: CQLLexer []"); + System.err.println("If unspecified, query is read from stdin"); + System.exit(1); } - } catch (IOException ex) { - System.err.println("Can't read query: " + ex.getMessage()); - System.exit(2); - return; - } - } - CQLTokenizer lexer = new CQLLexer(cql, true); - while ((lexer.what()) != TT_EOF) { - lexer.move(); - System.out.println(lexer.render()); + String cql; + if (args.length == 1) { + cql = args[0]; + } else { + BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); + try { + // read a single line of input + cql = buff.readLine(); + if (cql == null) { + System.err.println("Can't read query from stdin"); + System.exit(2); + return; + } + } catch (IOException ex) { + System.err.println("Can't read query: " + ex.getMessage()); + System.exit(2); + return; + } + } + + CQLTokenizer lexer = new CQLLexer(cql, true); + while ((lexer.what()) != TT_EOF) { + lexer.move(); + System.out.println(lexer.render()); + } } - } } diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index b71ba1b..f8bb095 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -10,30 +10,32 @@ * */ public abstract class CQLNode { - + public abstract void traverse(CQLNodeVisitor visitor); /** * Returns the name of the result-set to which this query is a * reference, if and only if the entire query consists only of a - * result-set reference. If it's anything else, including a + * result-set reference. If it's anything else, including a * boolean combination of a result-set reference with something * else, then null is returned instead. + * * @return the name of the referenced result-set */ public String getResultSetName() { - return null; + return null; } /** * Translates a parse-tree into an XCQL document. + * * @return - * A String containing an XCQL document equivalent to the - * parse-tree whose root is this node. + * A String containing an XCQL document equivalent to the + * parse-tree whose root is this node. */ public String toXCQL() { StringBuilder sb = new StringBuilder(); - toXCQLInternal(new XCQLBuilder(sb), 0); + toXCQLInternal(new XCQLBuilder(sb), 0); return sb.toString(); } @@ -42,44 +44,43 @@ void toXCQLInternal(XCQLBuilder b, int level) { } abstract void toXCQLInternal(XCQLBuilder b, int level, - List prefixes, List sortkeys); + List prefixes, List sortkeys); static void renderPrefixes(XCQLBuilder b, - int level, List prefixes) { - if (prefixes == null || prefixes.size() == 0) - return; - b.indent(level).append("\n"); - for (int i = 0; i < prefixes.size(); i++) { - CQLPrefix p = prefixes.get(i); - b.indent(level+1).append("\n"); - if (p.name != null) - b.indent(level + 2).append(""). - append(p.name).append("\n"); - b.indent(level + 2).append(""). - append(p.identifier).append("\n"); - b.indent(level+1).append("\n"); - } - b.indent(level).append("\n"); + int level, List prefixes) { + if (prefixes == null || prefixes.size() == 0) + return; + b.indent(level).append("\n"); + for (int i = 0; i < prefixes.size(); i++) { + CQLPrefix p = prefixes.get(i); + b.indent(level + 1).append("\n"); + if (p.name != null) + b.indent(level + 2).append("").append(p.name).append("\n"); + b.indent(level + 2).append("").append(p.identifier).append("\n"); + b.indent(level + 1).append("\n"); + } + b.indent(level).append("\n"); } static void renderSortKeys(XCQLBuilder b, int level, - List sortkeys) { - if (sortkeys == null || sortkeys.size() == 0) - return; - b.indent(level).append("\n"); - for (int i = 0; i < sortkeys.size(); i++) { - ModifierSet key = sortkeys.get(i); - key.toXCQLInternal(b, level+1, "key", "index"); - } - b.indent(level).append("\n"); + List sortkeys) { + if (sortkeys == null || sortkeys.size() == 0) + return; + b.indent(level).append("\n"); + for (int i = 0; i < sortkeys.size(); i++) { + ModifierSet key = sortkeys.get(i); + key.toXCQLInternal(b, level + 1, "key", "index"); + } + b.indent(level).append("\n"); } /** * Decompiles a parse-tree into a CQL query. + * * @return - * A String containing a CQL query equivalent to the parse-tree - * whose root is this node, so that compiling that query will - * yield an identical tree. + * A String containing a CQL query equivalent to the parse-tree + * whose root is this node, so that compiling that query will + * yield an identical tree. */ abstract public String toCQL(); @@ -87,91 +88,96 @@ static void renderSortKeys(XCQLBuilder b, int level, * Renders a parse-tree into a Yaz-style PQF string. * PQF, or Prefix Query Format, is a cryptic but powerful notation * that can be trivially mapped, one-to-one, int Z39.50 Type-1 and - * Type-101 queries. A specification for the format can be found + * Type-101 queries. A specification for the format can be found * in * Chapter 7 (Supporting Tools) of the + * >Chapter 7 (Supporting Tools) of the * YAZ manual. + * * @param config - * A Properties object containing configuration - * information that specifies the mapping from CQL indexes, - * relations, etc. to Type-1 attributes. The mapping - * specification is described in the CQL-Java distribution's - * sample PQF-mapping configuration file, - * etc/pqf.properties, which see. + * A Properties object containing configuration + * information that specifies the mapping from CQL indexes, + * relations, etc. to Type-1 attributes. The mapping + * specification is described in the CQL-Java distribution's + * sample PQF-mapping configuration file, + * etc/pqf.properties, which see. * @return - * A String containing a PQF query equivalent to the parse-tree - * whose root is this node. + * A String containing a PQF query equivalent to the parse-tree + * whose root is this node. * @throws PQFTranslationException - * If the parse-tree cannot be translated into PQF, for example - * because it contains a CQL relation that is not supported by the - * PQF configuration. + * If the parse-tree cannot be translated into + * PQF, for example + * because it contains a CQL relation that is + * not supported by the + * PQF configuration. */ abstract public String toPQF(Properties config) - throws PQFTranslationException; + throws PQFTranslationException; /** * Renders a parser-tree into a BER-endoded packet representing an - * equivalent Z39.50 Type-1 query. If you don't know what that - * means, then you don't need this method :-) This is useful + * equivalent Z39.50 Type-1 query. If you don't know what that + * means, then you don't need this method :-) This is useful * primarily for SRW-to-Z39.50 gateways. * * @param config - * A Properties object containing configuration - * information that specifies the mapping from CQL indexes, - * relations, etc. to Type-1 attributes. The mapping - * specification is described in the CQL-Java distribution's - * sample PQF-mapping configuration file, - * etc/pqf.properties, which see. + * A Properties object containing configuration + * information that specifies the mapping from CQL indexes, + * relations, etc. to Type-1 attributes. The mapping + * specification is described in the CQL-Java distribution's + * sample PQF-mapping configuration file, + * etc/pqf.properties, which see. * @return - * A byte array containing the BER packet. + * A byte array containing the BER packet. * @see - * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc + * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc * @throws PQFTranslationException - * If the parse-tree cannot be translated into PQF, for example - * because it contains a CQL relation that is not supported by the - * PQF configuration. + * If the parse-tree cannot be translated into + * PQF, for example + * because it contains a CQL relation that is + * not supported by the + * PQF configuration. */ abstract public byte[] toType1BER(Properties config) - throws PQFTranslationException; + throws PQFTranslationException; // ANS.1 classes - protected static final int UNIVERSAL = 0; + protected static final int UNIVERSAL = 0; protected static final int APPLICATION = 1; - protected static final int CONTEXT = 2; - protected static final int PRIVATE = 3; + protected static final int CONTEXT = 2; + protected static final int PRIVATE = 3; // ASN.1 tag forms - protected static final int PRIMITIVE = 0; + protected static final int PRIMITIVE = 0; protected static final int CONSTRUCTED = 1; // ASN.1 UNIVERSAL data types - public static final byte BOOLEAN = 1; - public static final byte INTEGER = 2; - public static final byte BITSTRING = 3; - public static final byte OCTETSTRING = 4; - public static final byte NULL = 5; - public static final byte OBJECTIDENTIFIER = 6; - public static final byte OBJECTDESCRIPTOR = 7; - public static final byte EXTERNAL = 8; - public static final byte ENUMERATED = 10; - public static final byte SEQUENCE = 16; - public static final byte SET = 17; - public static final byte VISIBLESTRING = 26; - public static final byte GENERALSTRING = 27; + public static final byte BOOLEAN = 1; + public static final byte INTEGER = 2; + public static final byte BITSTRING = 3; + public static final byte OCTETSTRING = 4; + public static final byte NULL = 5; + public static final byte OBJECTIDENTIFIER = 6; + public static final byte OBJECTDESCRIPTOR = 7; + public static final byte EXTERNAL = 8; + public static final byte ENUMERATED = 10; + public static final byte SEQUENCE = 16; + public static final byte SET = 17; + public static final byte VISIBLESTRING = 26; + public static final byte GENERALSTRING = 27; protected static final int putTag(int asn1class, int fldid, int form, - byte[] record, int offset) { + byte[] record, int offset) { if (fldid < 31) - record[offset++] = (byte)(fldid + asn1class*64 + form*32); + record[offset++] = (byte) (fldid + asn1class * 64 + form * 32); else { - record[offset++] = (byte)(31 + asn1class*64 + form*32); + record[offset++] = (byte) (31 + asn1class * 64 + form * 32); if (fldid < 128) - record[offset++] = (byte)(fldid); + record[offset++] = (byte) (fldid); else { - record[offset++] = (byte)(128 + fldid/128); - record[offset++] = (byte)(fldid % 128); + record[offset++] = (byte) (128 + fldid / 128); + record[offset++] = (byte) (fldid % 128); } } return offset; @@ -186,16 +192,16 @@ protected static final int putTag(int asn1class, int fldid, int form, static final int putLen(int len, byte[] record, int offset) { if (len < 128) - record[offset++] = (byte)len; + record[offset++] = (byte) len; else { int t; - record[offset] = (byte)(lenLen(len) - 1); + record[offset] = (byte) (lenLen(len) - 1); for (t = record[offset]; t > 0; t--) { - record[offset+t] = (byte)(len & 0xff); + record[offset + t] = (byte) (len & 0xff); len >>= 8; } t = offset; - offset += (record[offset]&0xff) + 1; + offset += (record[offset] & 0xff) + 1; record[t] += 128; // turn on bit 8 in length byte. } return offset; @@ -208,11 +214,9 @@ static final int putLen(int len, byte[] record, int offset) { * @return length needed to encode given length */ protected // ### shouldn't this be private? - static final int lenLen(int length) { + static final int lenLen(int length) { - return ((length < 128) ? 1 : - (length < 256) ? 2 : - (length < 65536L) ? 3 : 4); + return ((length < 128) ? 1 : (length < 256) ? 2 : (length < 65536L) ? 3 : 4); } /** @@ -223,112 +227,110 @@ static final int lenLen(int length) { */ protected static final int numLen(long num) { num = num < 0 ? -num : num; - // ### Wouldn't this be better done algorithmically? - // Or at least with the constants expressed in hex? - return ((num < 128) ? 1 : - (num < 32768) ? 2 : - (num < 8388608) ? 3 : - (num < 2147483648L) ? 4 : - (num < 549755813888L) ? 5 : - (num < 140737488355328L) ? 6 : - (num < 36028797018963968L) ? 7 : 8); + // ### Wouldn't this be better done algorithmically? + // Or at least with the constants expressed in hex? + return ((num < 128) ? 1 + : (num < 32768) ? 2 + : (num < 8388608) ? 3 + : (num < 2147483648L) ? 4 + : (num < 549755813888L) ? 5 + : (num < 140737488355328L) ? 6 : (num < 36028797018963968L) ? 7 : 8); } /** * Put a number into a given buffer * - * @param num number to put into buffer + * @param num number to put into buffer * @param record buffer to use * @param offset offset into buffer * @return the new, incremented value of the offset parameter. */ protected static final int putNum(long num, byte record[], int offset) { - int cnt=numLen(num); + int cnt = numLen(num); for (int count = cnt - 1; count >= 0; count--) { - record[offset+count] = (byte)(num & 0xff); + record[offset + count] = (byte) (num & 0xff); num >>= 8; } - return offset+cnt; + return offset + cnt; } // Used only by the makeOID() method - private static final Map madeOIDs = - new HashMap(10); + private static final Map madeOIDs = new HashMap(10); protected static final byte[] makeOID(String oid) { - byte[] o; - int dot, offset = 0, oidOffset = 0, value; - - if ((o = (byte[])madeOIDs.get(oid)) == null) { - o = new byte[100]; + byte[] o = (byte[]) madeOIDs.get(oid); + if (o != null) { + return o; + } + o = parseOID(oid); + if (o == null) { + return null; + } + madeOIDs.put(oid, o); + return o; + } - // Isn't this kind of thing excruciating in Java? - while (oidOffset < oid.length() && - Character.isDigit(oid.charAt(oidOffset)) == true) { - if (offset > 90) // too large + private static final byte[] parseOID(String oid) { + int offset = 0, oidOffset = 0; + byte [] o = new byte[100]; + // Isn't this kind of thing excruciating in Java? + while (oidOffset < oid.length() && + Character.isDigit(oid.charAt(oidOffset)) == true) { + if (offset > 90) { // too large + return null; + } + int dot = oid.indexOf('.', oidOffset); + if (dot == -1) { + if (offset == 0) { return null; - + } + dot = oid.length(); + } + int value = Integer.parseInt(oid.substring(oidOffset, dot)); + if (offset == 0) { // 1st two are special + oidOffset = dot + 1; // skip past '.' dot = oid.indexOf('.', oidOffset); - if (dot == -1) + if (dot == -1) { dot = oid.length(); - - value = Integer.parseInt(oid.substring(oidOffset, dot)); - - if (offset == 0) { // 1st two are special - if (dot == -1) // ### can't happen: -1 is reassigned above - return null; // can't be this short - oidOffset = dot+1; // skip past '.' - - dot = oid.indexOf('.', oidOffset); - if (dot == -1) - dot = oid.length(); - - // ### Eh?! - value = value * 40 + - Integer.parseInt(oid.substring(oidOffset,dot)); } - - if (value < 0x80) { - o[offset++] = (byte)value; - } else { - int count = 0; - byte bits[] = new byte[12]; // save a 84 (12*7) bit number - - while (value != 0) { - bits[count++] = (byte)(value & 0x7f); - value >>= 7; - } - - // Now place in the correct order - while (--count > 0) - o[offset++] = (byte)(bits[count] | 0x80); - - o[offset++] = bits[count]; - } - - dot = oid.indexOf('.', oidOffset); - if (dot == -1) - break; - - oidOffset = dot+1; + value = value * 40 + + Integer.parseInt(oid.substring(oidOffset, dot)); + } + if (value < 0x80) { + o[offset++] = (byte) value; + } else { + int count = 0; + byte bits[] = new byte[12]; // save a 84 (12*7) bit number + while (value != 0) { + bits[count++] = (byte) (value & 0x7f); + value >>= 7; + } + // Now place in the correct order + while (--count > 0) { + o[offset++] = (byte) (bits[count] | 0x80); + } + o[offset++] = bits[count]; } - byte[] ptr = new byte[offset]; - System.arraycopy(o, 0, ptr, 0, offset); - madeOIDs.put(oid, ptr); - return ptr; + dot = oid.indexOf('.', oidOffset); + if (dot == -1) { + byte[] ptr = new byte[offset]; + System.arraycopy(o, 0, ptr, 0, offset); + return ptr; + } + oidOffset = dot + 1; } - return o; + return null; } public static final byte[] makeQuery(CQLNode root, Properties properties) - throws PQFTranslationException { + throws PQFTranslationException { byte[] rpnStructure = root.toType1BER(properties); - byte[] qry = new byte[rpnStructure.length+100]; + byte[] qry = new byte[rpnStructure.length + 100]; int offset = 0; offset = putTag(CONTEXT, 1, CONSTRUCTED, qry, offset); - qry[offset++] = (byte)(0x80&0xff); // indefinite length + qry[offset++] = (byte) (0x80 & 0xff); // indefinite length offset = putTag(UNIVERSAL, OBJECTIDENTIFIER, PRIMITIVE, qry, offset); byte[] oid = makeOID("1.2.840.10003.3.1"); // bib-1 offset = putLen(oid.length, qry, offset); @@ -336,13 +338,13 @@ public static final byte[] makeQuery(CQLNode root, Properties properties) offset += oid.length; System.arraycopy(rpnStructure, 0, qry, offset, rpnStructure.length); offset += rpnStructure.length; - qry[offset++] = 0x00; // end of query + qry[offset++] = 0x00; // end of query qry[offset++] = 0x00; byte[] q = new byte[offset]; System.arraycopy(qry, 0, q, 0, offset); return q; } - + @Override public String toString() { return toCQL(); diff --git a/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java b/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java index bbd8452..0553ba4 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java +++ b/src/main/java/org/z3950/zing/cql/CQLNodeVisitor.java @@ -7,22 +7,23 @@ * CQLBooleanNode/Start/Op/End methods allow to generate prefix, infix or * postfix notations without needing to keep track of the parse tree. * See the CQLNodeVisitorTest for examples. + * * @author jakub */ public interface CQLNodeVisitor { - - public void onSortNode(CQLSortNode node); - - public void onPrefixNode(CQLPrefixNode node); - - public void onBooleanNodeStart(CQLBooleanNode node); - - public void onBooleanNodeOp(CQLBooleanNode node); - - public void onBooleanNodeEnd(CQLBooleanNode node); - - public void onTermNode(CQLTermNode node); - - public void onRelation(CQLRelation relation); - + + public void onSortNode(CQLSortNode node); + + public void onPrefixNode(CQLPrefixNode node); + + public void onBooleanNodeStart(CQLBooleanNode node); + + public void onBooleanNodeOp(CQLBooleanNode node); + + public void onBooleanNodeEnd(CQLBooleanNode node); + + public void onTermNode(CQLTermNode node); + + public void onRelation(CQLRelation relation); + } diff --git a/src/main/java/org/z3950/zing/cql/CQLNotNode.java b/src/main/java/org/z3950/zing/cql/CQLNotNode.java index 743c1a0..970014a 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNotNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNotNode.java @@ -10,16 +10,16 @@ public class CQLNotNode extends CQLBooleanNode { * sides and modifiers. */ public CQLNotNode(CQLNode left, CQLNode right, ModifierSet ms) { - super(left, right, ms, CQLBoolean.NOT); - } + super(left, right, ms, CQLBoolean.NOT); + } @Override byte[] opType1() { - byte[] op = new byte[5]; - putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator - putLen(2, op, 2); - putTag(CONTEXT, 2, PRIMITIVE, op, 3); // and-not - putLen(0, op, 4); - return op; + byte[] op = new byte[5]; + putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator + putLen(2, op, 2); + putTag(CONTEXT, 2, PRIMITIVE, op, 3); // and-not + putLen(0, op, 4); + return op; } } diff --git a/src/main/java/org/z3950/zing/cql/CQLOrNode.java b/src/main/java/org/z3950/zing/cql/CQLOrNode.java index 32600c6..bbe509e 100644 --- a/src/main/java/org/z3950/zing/cql/CQLOrNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLOrNode.java @@ -10,16 +10,16 @@ public class CQLOrNode extends CQLBooleanNode { * sides and modifiers. */ public CQLOrNode(CQLNode left, CQLNode right, ModifierSet ms) { - super(left, right, ms, CQLBoolean.OR); + super(left, right, ms, CQLBoolean.OR); } @Override byte[] opType1() { - byte[] op = new byte[5]; - putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator - putLen(2, op, 2); - putTag(CONTEXT, 1, PRIMITIVE, op, 3); // or - putLen(0, op, 4); - return op; + byte[] op = new byte[5]; + putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator + putLen(2, op, 2); + putTag(CONTEXT, 1, PRIMITIVE, op, 3); // or + putLen(0, op, 4); + return op; } } diff --git a/src/main/java/org/z3950/zing/cql/CQLParseException.java b/src/main/java/org/z3950/zing/cql/CQLParseException.java index 311fa42..299cf1d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParseException.java +++ b/src/main/java/org/z3950/zing/cql/CQLParseException.java @@ -6,23 +6,25 @@ */ public class CQLParseException extends Exception { private int pos; + /** * Creates a new CQLParseException. + * * @param s - * An error message describing the problem with the query, - * usually a syntax error of some kind. + * An error message describing the problem with the query, + * usually a syntax error of some kind. */ public CQLParseException(String s, int pos) { - super(s); + super(s); this.pos = pos; } - + /** * Character position of the parsing error. - * @return + * + * @return */ public int getPosition() { - return pos; + return pos; } } - diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index 9256eef..eae3455 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -14,12 +14,12 @@ /** * Compiles CQL strings into parse trees of CQLNode subtypes. * - * @see http://zing.z3950.org/cql/index.html + * @see http://zing.z3950.org/cql/index.html */ public class CQLParser { private CQLTokenizer lexer; - private final int compat; // When false, implement CQL 1.2 + private final int compat; // When false, implement CQL 1.2 private final Set customRelations = new HashSet(); public static final int V1POINT1 = 12368; @@ -34,17 +34,17 @@ public class CQLParser { * The new parser implements a dialect of CQL specified by the * compat argument: *

    - *
  • V1POINT1 - CQL version 1.1 - *
  • - *
  • V1POINT2 - CQL version 1.2 - *
  • - *
  • V1POINT1SORT - CQL version 1.1 but including - * sortby as specified for CQL 1.2. - *
  • + *
  • V1POINT1 - CQL version 1.1 + *
  • + *
  • V1POINT2 - CQL version 1.2 + *
  • + *
  • V1POINT1SORT - CQL version 1.1 but including + * sortby as specified for CQL 1.2. + *
  • *
*/ public CQLParser(int compat) { - this.compat = compat; + this.compat = compat; this.allowKeywordTerms = true; } @@ -52,11 +52,13 @@ public CQLParser(int compat) { * Official CQL grammar allows registered keywords like 'and/or/not/sortby/prox' * to be used unquoted in terms. This constructor allows to create an instance * of a parser that prohibits this behavior while sacrificing compatibility. - * @param compat CQL version compatibility - * @param allowKeywordTerms when false registered keywords are disallowed in unquoted terms + * + * @param compat CQL version compatibility + * @param allowKeywordTerms when false registered keywords are disallowed in + * unquoted terms */ public CQLParser(int compat, boolean allowKeywordTerms) { - this.compat = compat; + this.compat = compat; this.allowKeywordTerms = allowKeywordTerms; } @@ -64,33 +66,37 @@ public CQLParser(int compat, boolean allowKeywordTerms) { * The new parser implements CQL 1.2 */ public CQLParser() { - this.compat = V1POINT2; + this.compat = V1POINT2; this.allowKeywordTerms = true; } private static void debug(String str) { - if (DEBUG) - System.err.println("PARSEDEBUG: " + str); + if (DEBUG) + System.err.println("PARSEDEBUG: " + str); } /** * Registers custom relation in this parser. Note that when a custom relation - * is registered the parser is no longer strictly compliant with the chosen spec. + * is registered the parser is no longer strictly compliant with the chosen + * spec. * Custom relations are case-insensitive. + * * @param relation * @return true if custom relation has not been registered already */ public boolean registerCustomRelation(String relation) { - return customRelations.add(relation.toLowerCase()); + return customRelations.add(relation.toLowerCase()); } /** - * Unregisters previously registered custom relation in this instance of the parser. + * Unregisters previously registered custom relation in this instance of the + * parser. + * * @param relation * @return true is relation has been previously registered */ public boolean unregisterCustomRelation(String relation) { - return customRelations.remove(relation.toLowerCase()); + return customRelations.remove(relation.toLowerCase()); } /** @@ -99,194 +105,191 @@ public boolean unregisterCustomRelation(String relation) { * The resulting parse tree may be further processed by hand (see * the individual node-types' documentation for details on the * data structure) or, more often, simply rendered out in the - * desired form using one of the back-ends. toCQL() + * desired form using one of the back-ends. toCQL() * returns a decompiled CQL query equivalent to the one that was * compiled in the first place; toXCQL() returns an * XML snippet representing the query; and toPQF() * returns the query rendered in Index Data's Prefix Query * Format. * - * @param cql The query - * @return A CQLNode object which is the root of a parse - * tree representing the query. */ + * @param cql The query + * @return A CQLNode object which is the root of a parse + * tree representing the query. + */ public CQLNode parse(String cql) - throws CQLParseException, IOException { - lexer = new CQLLexer(cql, LEXDEBUG); - - lexer.move(); - debug("about to parseQuery()"); - CQLNode root = parseTopLevelPrefixes("cql.serverChoice", - new CQLRelation(compat == V1POINT2 ? "=" : "scr")); - if (lexer.what() != CQLTokenizer.TT_EOF) - throw new CQLParseException("junk after end: " + lexer.render(), - lexer.pos()); - - return root; + throws CQLParseException, IOException { + lexer = new CQLLexer(cql, LEXDEBUG); + + lexer.move(); + debug("about to parseQuery()"); + CQLNode root = parseTopLevelPrefixes("cql.serverChoice", + new CQLRelation(compat == V1POINT2 ? "=" : "scr")); + if (lexer.what() != CQLTokenizer.TT_EOF) + throw new CQLParseException("junk after end: " + lexer.render(), + lexer.pos()); + + return root; } private CQLNode parseTopLevelPrefixes(String index, CQLRelation relation) - throws CQLParseException, IOException { - debug("top-level prefix mapping"); - - if (lexer.what() == '>') { - return parsePrefix(index, relation, true); - } - - CQLNode node = parseQuery(index, relation); - if ((compat == V1POINT2 || compat == V1POINT1SORT) && - lexer.what() == CQLTokenizer.TT_SORTBY) { - match(lexer.what()); - debug("sortspec"); - - CQLSortNode sortnode = new CQLSortNode(node); - while (lexer.what() != CQLTokenizer.TT_EOF) { - String sortindex = matchSymbol("sort index"); - ModifierSet ms = gatherModifiers(sortindex); - sortnode.addSortIndex(ms); - } - - if (sortnode.keys.size() == 0) { - throw new CQLParseException("no sort keys", lexer.pos()); - } - - node = sortnode; - } - - return node; + throws CQLParseException, IOException { + debug("top-level prefix mapping"); + + if (lexer.what() == '>') { + return parsePrefix(index, relation, true); + } + + CQLNode node = parseQuery(index, relation); + if ((compat == V1POINT2 || compat == V1POINT1SORT) && + lexer.what() == CQLTokenizer.TT_SORTBY) { + match(lexer.what()); + debug("sortspec"); + + CQLSortNode sortnode = new CQLSortNode(node); + while (lexer.what() != CQLTokenizer.TT_EOF) { + String sortindex = matchSymbol("sort index"); + ModifierSet ms = gatherModifiers(sortindex); + sortnode.addSortIndex(ms); + } + + if (sortnode.keys.size() == 0) { + throw new CQLParseException("no sort keys", lexer.pos()); + } + + node = sortnode; + } + + return node; } private CQLNode parseQuery(String index, CQLRelation relation) - throws CQLParseException, IOException { - debug("in parseQuery()"); - - CQLNode term = parseTerm(index, relation); - while (lexer.what() != CQLTokenizer.TT_EOF && - lexer.what() != ')' && - lexer.what() != CQLTokenizer.TT_SORTBY) { - if (lexer.what() == CQLTokenizer.TT_AND || - lexer.what() == CQLTokenizer.TT_OR || - lexer.what() == CQLTokenizer.TT_NOT || - lexer.what() == CQLTokenizer.TT_PROX) { - int type = lexer.what(); - String val = lexer.value(); - match(type); - ModifierSet ms = gatherModifiers(val); - CQLNode term2 = parseTerm(index, relation); - term = ((type == CQLTokenizer.TT_AND) ? new CQLAndNode(term, term2, ms) : - (type == CQLTokenizer.TT_OR) ? new CQLOrNode (term, term2, ms) : - (type == CQLTokenizer.TT_NOT) ? new CQLNotNode(term, term2, ms) : - new CQLProxNode(term, term2, ms)); - } else { - throw new CQLParseException("expected boolean, got " + - lexer.render(), lexer.pos()); - } - } - - debug("no more ops"); - return term; + throws CQLParseException, IOException { + debug("in parseQuery()"); + + CQLNode term = parseTerm(index, relation); + while (lexer.what() != CQLTokenizer.TT_EOF && + lexer.what() != ')' && + lexer.what() != CQLTokenizer.TT_SORTBY) { + if (lexer.what() == CQLTokenizer.TT_AND || + lexer.what() == CQLTokenizer.TT_OR || + lexer.what() == CQLTokenizer.TT_NOT || + lexer.what() == CQLTokenizer.TT_PROX) { + int type = lexer.what(); + String val = lexer.value(); + match(type); + ModifierSet ms = gatherModifiers(val); + CQLNode term2 = parseTerm(index, relation); + term = ((type == CQLTokenizer.TT_AND) ? new CQLAndNode(term, term2, ms) + : (type == CQLTokenizer.TT_OR) ? new CQLOrNode(term, term2, ms) + : (type == CQLTokenizer.TT_NOT) ? new CQLNotNode(term, term2, ms) + : new CQLProxNode(term, term2, ms)); + } else { + throw new CQLParseException("expected boolean, got " + + lexer.render(), lexer.pos()); + } + } + + debug("no more ops"); + return term; } private ModifierSet gatherModifiers(String base) - throws CQLParseException, IOException { - debug("in gatherModifiers()"); - - ModifierSet ms = new ModifierSet(base); - while (lexer.what() == '/') { - match('/'); - if (lexer.what() != CQLTokenizer.TT_WORD) - throw new CQLParseException("expected modifier, " - + "got " + lexer.render(), - lexer.pos()); - String type = lexer.value().toLowerCase(); - match(lexer.what()); - if (!isSymbolicRelation()) { - // It's a simple modifier consisting of type only - ms.addModifier(type); - } else { - // It's a complex modifier of the form type=value - String comparision = lexer.render(lexer.what(), false); - match(lexer.what()); - String value = matchSymbol("modifier value"); - ms.addModifier(type, comparision, value); - } - } - - return ms; + throws CQLParseException, IOException { + debug("in gatherModifiers()"); + + ModifierSet ms = new ModifierSet(base); + while (lexer.what() == '/') { + match('/'); + if (lexer.what() != CQLTokenizer.TT_WORD) + throw new CQLParseException("expected modifier, " + + "got " + lexer.render(), + lexer.pos()); + String type = lexer.value().toLowerCase(); + match(lexer.what()); + if (!isSymbolicRelation()) { + // It's a simple modifier consisting of type only + ms.addModifier(type); + } else { + // It's a complex modifier of the form type=value + String comparision = lexer.render(lexer.what(), false); + match(lexer.what()); + String value = matchSymbol("modifier value"); + ms.addModifier(type, comparision, value); + } + } + + return ms; } private CQLNode parseTerm(String index, CQLRelation relation) - throws CQLParseException, IOException { - debug("in parseTerm()"); + throws CQLParseException, IOException { + debug("in parseTerm()"); - String first; + String first; StringBuilder all; - while (true) { - if (lexer.what() == '(') { - debug("parenthesised term"); - match('('); - CQLNode expr = parseQuery(index, relation); - match(')'); - return expr; - } else if (lexer.what() == '>') { - return parsePrefix(index, relation, false); - } - - debug("non-parenthesised term"); - first = matchSymbol("index or term"); + while (true) { + if (lexer.what() == '(') { + debug("parenthesised term"); + match('('); + CQLNode expr = parseQuery(index, relation); + match(')'); + return expr; + } else if (lexer.what() == '>') { + return parsePrefix(index, relation, false); + } + + debug("non-parenthesised term"); + first = matchSymbol("index or term"); all = new StringBuilder(first); - //match relation only on second postion + // match relation only on second postion while (isWordOrString() && (all.length() > first.length() || !isRelation())) { - all.append(" ").append(lexer.value()); - match(lexer.what()); + all.append(" ").append(lexer.value()); + match(lexer.what()); } - if (!isRelation()) - break; //we're done if no relation + if (!isRelation()) + break; // we're done if no relation - //render relation - String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? - lexer.value() : lexer.render(lexer.what(), false)); - //we have relation, but it only makes sense if preceded by a single term + // render relation + String relstr = (lexer.what() == CQLTokenizer.TT_WORD ? lexer.value() : lexer.render(lexer.what(), false)); + // we have relation, but it only makes sense if preceded by a single term if (all.length() > first.length()) { - throw new CQLParseException("unexpected relation '"+relstr+"'" - , lexer.pos()); + throw new CQLParseException("unexpected relation '" + relstr + "'", lexer.pos()); } index = first; - relation = new CQLRelation(relstr); - match(lexer.what()); - ModifierSet ms = gatherModifiers(relstr); - relation.ms = ms; - debug("index='" + index + ", " + - "relation='" + relation.toCQL() + "'"); - } - CQLTermNode node = new CQLTermNode(index, relation, all.toString()); - debug("made term node " + node.toCQL()); - return node; + relation = new CQLRelation(relstr); + match(lexer.what()); + ModifierSet ms = gatherModifiers(relstr); + relation.ms = ms; + debug("index='" + index + ", " + + "relation='" + relation.toCQL() + "'"); + } + CQLTermNode node = new CQLTermNode(index, relation, all.toString()); + debug("made term node " + node.toCQL()); + return node; } private CQLNode parsePrefix(String index, CQLRelation relation, - boolean topLevel) - throws CQLParseException, IOException { - debug("prefix mapping"); - - match('>'); - String name = null; - String identifier = matchSymbol("prefix-name"); - if (lexer.what() == '=') { - match('='); - name = identifier; - identifier = matchSymbol("prefix-identifer"); - } - CQLNode node = topLevel ? - parseTopLevelPrefixes(index, relation) : - parseQuery(index, relation); - - return new CQLPrefixNode(name, identifier, node); + boolean topLevel) + throws CQLParseException, IOException { + debug("prefix mapping"); + + match('>'); + String name = null; + String identifier = matchSymbol("prefix-name"); + if (lexer.what() == '=') { + match('='); + name = identifier; + identifier = matchSymbol("prefix-identifer"); + } + CQLNode node = topLevel ? parseTopLevelPrefixes(index, relation) : parseQuery(index, relation); + + return new CQLPrefixNode(name, identifier, node); } private boolean isWordOrString() { - return CQLTokenizer.TT_WORD == lexer.what() - || CQLTokenizer.TT_STRING == lexer.what(); + return CQLTokenizer.TT_WORD == lexer.what() + || CQLTokenizer.TT_STRING == lexer.what(); } private boolean isRelation() { @@ -319,55 +322,57 @@ private boolean isSymbolicRelation() { } private void match(int token) - throws CQLParseException, IOException { - debug("in match(" + lexer.render(token, true) + ")"); - if (lexer.what() != token) - throw new CQLParseException("expected " + - lexer.render(token, true) + - ", " + "got " + lexer.render(), - lexer.pos()); - lexer.move(); - debug("match() got token=" + lexer.what() + ", value()='" + lexer.value() + "'"); + throws CQLParseException, IOException { + debug("in match(" + lexer.render(token, true) + ")"); + if (lexer.what() != token) + throw new CQLParseException("expected " + + lexer.render(token, true) + + ", " + "got " + lexer.render(), + lexer.pos()); + lexer.move(); + debug("match() got token=" + lexer.what() + ", value()='" + lexer.value() + "'"); } private String matchSymbol(String expected) - throws CQLParseException, IOException { - - debug("in matchSymbol()"); - if (lexer.what() == CQLTokenizer.TT_WORD || - lexer.what() == CQLTokenizer.TT_STRING || - // The following is a complete list of keywords. Because - // they're listed here, they can be used unquoted as - // indexes, terms, prefix names and prefix identifiers. - (allowKeywordTerms && - lexer.what() == CQLTokenizer.TT_AND || - lexer.what() == CQLTokenizer.TT_OR || - lexer.what() == CQLTokenizer.TT_NOT || - lexer.what() == CQLTokenizer.TT_PROX || - lexer.what() == CQLTokenizer.TT_SORTBY)) { - String symbol = lexer.value(); - match(lexer.what()); - return symbol; - } - - throw new CQLParseException("expected " + expected + ", " + - "got " + lexer.render(), lexer.pos()); - } + throws CQLParseException, IOException { + + debug("in matchSymbol()"); + if (lexer.what() == CQLTokenizer.TT_WORD || + lexer.what() == CQLTokenizer.TT_STRING || + // The following is a complete list of keywords. Because + // they're listed here, they can be used unquoted as + // indexes, terms, prefix names and prefix identifiers. + (allowKeywordTerms && + lexer.what() == CQLTokenizer.TT_AND || + lexer.what() == CQLTokenizer.TT_OR || + lexer.what() == CQLTokenizer.TT_NOT || + lexer.what() == CQLTokenizer.TT_PROX || + lexer.what() == CQLTokenizer.TT_SORTBY)) { + String symbol = lexer.value(); + match(lexer.what()); + return symbol; + } + throw new CQLParseException("expected " + expected + ", " + + "got " + lexer.render(), lexer.pos()); + } /** * Simple test-harness for the CQLParser class. *

* Reads a CQL query either from its command-line argument, if - * there is one, or standard input otherwise. So these two + * there is one, or standard input otherwise. So these two * invocations are equivalent: + * *

      *  CQLParser 'au=(Kerninghan or Ritchie) and ti=Unix'
      *  echo au=(Kerninghan or Ritchie) and ti=Unix | CQLParser
      * 
+ * * The test-harness parses the supplied query and renders is as * XCQL, so that both of the invocations above produce the * following output: + * *
      *	<triple>
      *	  <boolean>
@@ -401,128 +406,130 @@ private String matchSymbol(String expected)
      *	  </searchClause>
      *	</triple>
      * 
+ * * @param -1 - * CQL version 1.1 (default version 1.2) + * CQL version 1.1 (default version 1.2) * @param -d - * Debug mode: extra output written to stderr. + * Debug mode: extra output written to stderr. * @param -c - * Causes the output to be written in CQL rather than XCQL - that - * is, a query equivalent to that which was input, is output. In - * effect, the test harness acts as a query canonicaliser. + * Causes the output to be written in CQL rather than XCQL - that + * is, a query equivalent to that which was input, is output. In + * effect, the test harness acts as a query canonicaliser. * @return - * The input query, either as XCQL [default] or CQL [if the - * -c option is supplied]. + * The input query, either as XCQL [default] or CQL [if the + * -c option is supplied]. */ - public static void main (String[] args) { - char mode = 'x'; // x=XCQL, c=CQL, p=PQF - String pfile = null; - - List argv = new ArrayList(); - for (int i = 0; i < args.length; i++) { - argv.add(args[i]); - } - - int compat = V1POINT2; - if (argv.size() > 0 && argv.get(0).equals("-1")) { - compat = V1POINT1; - argv.remove(0); - } - - if (argv.size() > 0 && argv.get(0).equals("-d")) { - DEBUG = true; - argv.remove(0); - } - - if (argv.size() > 0 && argv.get(0).equals("-c")) { - mode = 'c'; - argv.remove(0); - } else if (argv.size() > 1 && argv.get(0).equals("-p")) { - mode = 'p'; - argv.remove(0); - pfile = (String) argv.get(0); - argv.remove(0); - } - - if (argv.size() > 1) { - System.err.println("Usage: CQLParser [-1] [-d] [-c] " + - "[-p []"); - System.err.println("If unspecified, query is read from stdin"); - System.exit(1); - } - - String cql; - if (argv.size() == 1) { - cql = (String) argv.get(0); - } else { - BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); - try { - // read a single line of input - cql = buff.readLine(); - if (cql == null) { - System.err.println("Can't read query from stdin"); - System.exit(2); - return; - } - } catch (IOException ex) { - System.err.println("Can't read query: " + ex.getMessage()); - System.exit(2); + public static void main(String[] args) { + char mode = 'x'; // x=XCQL, c=CQL, p=PQF + String pfile = null; + + List argv = new ArrayList(); + for (int i = 0; i < args.length; i++) { + argv.add(args[i]); + } + + int compat = V1POINT2; + if (argv.size() > 0 && argv.get(0).equals("-1")) { + compat = V1POINT1; + argv.remove(0); + } + + if (argv.size() > 0 && argv.get(0).equals("-d")) { + DEBUG = true; + argv.remove(0); + } + + if (argv.size() > 0 && argv.get(0).equals("-c")) { + mode = 'c'; + argv.remove(0); + } else if (argv.size() > 1 && argv.get(0).equals("-p")) { + mode = 'p'; + argv.remove(0); + pfile = (String) argv.get(0); + argv.remove(0); + } + + if (argv.size() > 1) { + System.err.println("Usage: CQLParser [-1] [-d] [-c] " + + "[-p []"); + System.err.println("If unspecified, query is read from stdin"); + System.exit(1); + } + + String cql; + if (argv.size() == 1) { + cql = (String) argv.get(0); + } else { + BufferedReader buff = new BufferedReader(new InputStreamReader(System.in)); + try { + // read a single line of input + cql = buff.readLine(); + if (cql == null) { + System.err.println("Can't read query from stdin"); + System.exit(2); + return; + } + } catch (IOException ex) { + System.err.println("Can't read query: " + ex.getMessage()); + System.exit(2); return; - } - } - - CQLParser parser = new CQLParser(compat); - CQLNode root; - try { - root = parser.parse(cql); - } catch (CQLParseException ex) { - System.err.println("Syntax error: " + ex.getMessage()); + } + } + + CQLParser parser = new CQLParser(compat); + CQLNode root; + try { + root = parser.parse(cql); + } catch (CQLParseException ex) { + System.err.println("Syntax error: " + ex.getMessage()); StringBuilder space = new StringBuilder(cql.length()); System.out.println(cql); - for (int i=0; idc
, as it might be used in an index * like dc.title. */ @@ -17,11 +17,10 @@ public String getName() { return name; } - String identifier; /** - * The full identifier name of the prefix mapping. That is, + * The full identifier name of the prefix mapping. That is, * typically, a URI permanently allocated to a specific index * set, such as http://zthes.z3950.org/cql/1.0. */ @@ -34,7 +33,7 @@ public String getIdentifier() { * to the specified identifier. */ CQLPrefix(String name, String identifier) { - this.name = name; - this.identifier = identifier; + this.name = name; + this.identifier = identifier; } } diff --git a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java index 1705aad..f14a471 100644 --- a/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLPrefixNode.java @@ -26,7 +26,7 @@ public CQLPrefix getPrefix() { * that is governed by this prefix definition. */ public CQLNode getSubtree() { - return subtree; + return subtree; } /** @@ -35,50 +35,48 @@ public CQLNode getSubtree() { * the specified subtree. */ public CQLPrefixNode(String name, String identifier, CQLNode subtree) { - this.prefix = new CQLPrefix(name, identifier); - this.subtree = subtree; + this.prefix = new CQLPrefix(name, identifier); + this.subtree = subtree; } @Override public void traverse(CQLNodeVisitor visitor) { - visitor.onPrefixNode(this); - subtree.traverse(visitor); + visitor.onPrefixNode(this); + subtree.traverse(visitor); } @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, - List sortkeys) { - List tmp = (prefixes == null ? - new ArrayList() : - new ArrayList(prefixes)); - tmp.add(prefix); - subtree.toXCQLInternal(b, level, tmp, sortkeys); + List sortkeys) { + List tmp = (prefixes == null ? new ArrayList() : new ArrayList(prefixes)); + tmp.add(prefix); + subtree.toXCQLInternal(b, level, tmp, sortkeys); } @Override public String toCQL() { - // ### We don't always need parens around the subtree - if (prefix.name == null) { - return ">\"" + prefix.identifier + "\" " + - "(" + subtree.toCQL() + ")"; - } else { - return ">" + prefix.name + "=\"" + prefix.identifier + "\" " + - "(" + subtree.toCQL() + ")"; - } + // ### We don't always need parens around the subtree + if (prefix.name == null) { + return ">\"" + prefix.identifier + "\" " + + "(" + subtree.toCQL() + ")"; + } else { + return ">" + prefix.name + "=\"" + prefix.identifier + "\" " + + "(" + subtree.toCQL() + ")"; + } } @Override public String toPQF(Properties config) throws PQFTranslationException { - // Prefixes and their identifiers don't actually play any role - // in PQF translation, since the meanings of the indexes, - // including their prefixes if any, are instead wired into - // `config'. - return subtree.toPQF(config); + // Prefixes and their identifiers don't actually play any role + // in PQF translation, since the meanings of the indexes, + // including their prefixes if any, are instead wired into + // `config'. + return subtree.toPQF(config); } @Override public byte[] toType1BER(Properties config) throws PQFTranslationException { - // See comment on toPQF() - return subtree.toType1BER(config); + // See comment on toPQF() + return subtree.toType1BER(config); } } diff --git a/src/main/java/org/z3950/zing/cql/CQLProxNode.java b/src/main/java/org/z3950/zing/cql/CQLProxNode.java index 3e844ca..14a1e2a 100644 --- a/src/main/java/org/z3950/zing/cql/CQLProxNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLProxNode.java @@ -13,8 +13,8 @@ public class CQLProxNode extends CQLBooleanNode { * sides and modifiers. */ public CQLProxNode(CQLNode left, CQLNode right, ModifierSet ms) { - super(left, right, ms, CQLBoolean.PROX); - } + super(left, right, ms, CQLBoolean.PROX); + } /* * proximity ::= exclusion distance ordered relation which-code unit-code. @@ -27,99 +27,98 @@ public CQLProxNode(CQLNode left, CQLNode right, ModifierSet ms) { */ @Override String opPQF() { - int relCode = getRelCode(); - int unitCode = getProxUnitCode(); - - String res = "prox " + - "0 " + - ms.modifier("distance") + " " + - (ms.modifier("ordering").equals("ordered") ? 1 : 0) + " " + - relCode + " " + - "1 " + - unitCode; - - return res; + int relCode = getRelCode(); + int unitCode = getProxUnitCode(); + + String res = "prox " + + "0 " + + ms.modifier("distance") + " " + + (ms.modifier("ordering").equals("ordered") ? 1 : 0) + " " + + relCode + " " + + "1 " + + unitCode; + + return res; } private int getRelCode() { - String rel = ms.modifier("relation"); - if (rel.equals("<")) { - return 1; - } else if (rel.equals("<=")) { - return 2; - } else if (rel.equals("=")) { - return 3; - } else if (rel.equals(">=")) { - return 4; - } else if (rel.equals(">")) { - return 5; - } else if (rel.equals("<>")) { - return 6; - } - return 0; + String rel = ms.modifier("relation"); + if (rel.equals("<")) { + return 1; + } else if (rel.equals("<=")) { + return 2; + } else if (rel.equals("=")) { + return 3; + } else if (rel.equals(">=")) { + return 4; + } else if (rel.equals(">")) { + return 5; + } else if (rel.equals("<>")) { + return 6; + } + return 0; } private int getProxUnitCode() { - String unit = ms.modifier("unit"); - if (unit.equals("word")) { - return 2; - } else if (unit.equals("sentence")) { - return 3; - } else if (unit.equals("paragraph")) { - return 4; - } else if (unit.equals("element")) { - return 8; - } - return 0; + String unit = ms.modifier("unit"); + if (unit.equals("word")) { + return 2; + } else if (unit.equals("sentence")) { + return 3; + } else if (unit.equals("paragraph")) { + return 4; + } else if (unit.equals("element")) { + return 8; + } + return 0; } - @Override byte[] opType1() { - byte[] op = new byte[100]; - int offset, value; - offset = putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator - op[offset++] = (byte)(0x80&0xff); // indefinite length - - offset = putTag(CONTEXT, 3, CONSTRUCTED, op, offset); // prox - op[offset++] = (byte)(0x80&0xff); // indefinite length - - offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // exclusion - value = 0; // false - offset = putLen(numLen(value), op, offset); - offset = putNum(value, op, offset); - - offset = putTag(CONTEXT, 2, PRIMITIVE, op, offset); // distance - value = Integer.parseInt(ms.modifier("distance")); - offset = putLen(numLen(value), op, offset); - offset = putNum(value, op, offset); - - offset = putTag(CONTEXT, 3, PRIMITIVE, op, offset); // ordered - value = ms.modifier("ordering").equals("ordered") ? 1 : 0; - offset = putLen(numLen(value), op, offset); - offset = putNum(value, op, offset); - - offset = putTag(CONTEXT, 4, PRIMITIVE, op, offset); // relationType - value = getRelCode(); - offset = putLen(numLen(value), op, offset); - offset = putNum(value, op, offset); - - offset = putTag(CONTEXT, 5, CONSTRUCTED, op, offset); // proximityUnitCode - op[offset++] = (byte)(0x80&0xff); // indefinite length - offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // known - value = getProxUnitCode(); - offset = putLen(numLen(value), op, offset); - offset = putNum(value, op, offset); - op[offset++] = 0x00; // end of proximityUnitCode - op[offset++] = 0x00; - - op[offset++] = 0x00; // end of prox - op[offset++] = 0x00; - op[offset++] = 0x00; // end of Operator - op[offset++] = 0x00; - - byte[] o = new byte[offset]; - System.arraycopy(op, 0, o, 0, offset); - return o; + byte[] op = new byte[100]; + int offset, value; + offset = putTag(CONTEXT, 46, CONSTRUCTED, op, 0); // Operator + op[offset++] = (byte) (0x80 & 0xff); // indefinite length + + offset = putTag(CONTEXT, 3, CONSTRUCTED, op, offset); // prox + op[offset++] = (byte) (0x80 & 0xff); // indefinite length + + offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // exclusion + value = 0; // false + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + + offset = putTag(CONTEXT, 2, PRIMITIVE, op, offset); // distance + value = Integer.parseInt(ms.modifier("distance")); + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + + offset = putTag(CONTEXT, 3, PRIMITIVE, op, offset); // ordered + value = ms.modifier("ordering").equals("ordered") ? 1 : 0; + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + + offset = putTag(CONTEXT, 4, PRIMITIVE, op, offset); // relationType + value = getRelCode(); + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + + offset = putTag(CONTEXT, 5, CONSTRUCTED, op, offset); // proximityUnitCode + op[offset++] = (byte) (0x80 & 0xff); // indefinite length + offset = putTag(CONTEXT, 1, PRIMITIVE, op, offset); // known + value = getProxUnitCode(); + offset = putLen(numLen(value), op, offset); + offset = putNum(value, op, offset); + op[offset++] = 0x00; // end of proximityUnitCode + op[offset++] = 0x00; + + op[offset++] = 0x00; // end of prox + op[offset++] = 0x00; + op[offset++] = 0x00; // end of Operator + op[offset++] = 0x00; + + byte[] o = new byte[offset]; + System.arraycopy(op, 0, o, 0, offset); + return o; } } diff --git a/src/main/java/org/z3950/zing/cql/CQLRelation.java b/src/main/java/org/z3950/zing/cql/CQLRelation.java index 6f52eec..3dc5b63 100644 --- a/src/main/java/org/z3950/zing/cql/CQLRelation.java +++ b/src/main/java/org/z3950/zing/cql/CQLRelation.java @@ -21,7 +21,7 @@ public class CQLRelation extends CQLNode { // ### Seems wrong: a modifier set should not have a base, a // relation should public CQLRelation(String base) { - ms = new ModifierSet(base); + ms = new ModifierSet(base); } /** @@ -29,43 +29,44 @@ public CQLRelation(String base) { * originally created. */ public String getBase() { - return ms.getBase(); + return ms.getBase(); } /** * Returns an array of the modifiers associated with a CQLRelation. + * * @return - * An array of Modifier objects. + * An array of Modifier objects. */ public List getModifiers() { - return ms.getModifiers(); + return ms.getModifiers(); } @Override public void traverse(CQLNodeVisitor visitor) { - visitor.onRelation(this); - } - + visitor.onRelation(this); + } + @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, - List sortkeys) { - if (sortkeys != null) - throw new Error("CQLRelation.toXCQL() called with sortkeys"); - ms.toXCQLInternal(b, level, "relation", "value"); + List sortkeys) { + if (sortkeys != null) + throw new Error("CQLRelation.toXCQL() called with sortkeys"); + ms.toXCQLInternal(b, level, "relation", "value"); } @Override public String toCQL() { - return ms.toCQL(); + return ms.toCQL(); } @Override public String toPQF(Properties config) throws PQFTranslationException { - throw new Error("CQLRelation.toPQF() can never be called"); + throw new Error("CQLRelation.toPQF() can never be called"); } @Override public byte[] toType1BER(Properties config) { - throw new Error("CQLRelation.toType1BER() can never be called"); + throw new Error("CQLRelation.toType1BER() can never be called"); } } diff --git a/src/main/java/org/z3950/zing/cql/CQLSortNode.java b/src/main/java/org/z3950/zing/cql/CQLSortNode.java index 9aed194..9b65dd4 100644 --- a/src/main/java/org/z3950/zing/cql/CQLSortNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLSortNode.java @@ -12,14 +12,14 @@ public class CQLSortNode extends CQLNode { /** * The root of a subtree representing the query whose result is to * be sorted. - */ + */ private CQLNode subtree; /** * The set of sort keys by which results are to be sorted, * each expressed as an index together with zero or more * modifiers. - */ + */ List keys; public CQLNode getSubtree() { @@ -27,58 +27,58 @@ public CQLNode getSubtree() { } public CQLSortNode(CQLNode subtree) { - this.subtree = subtree; - keys = new ArrayList(); + this.subtree = subtree; + keys = new ArrayList(); } public void addSortIndex(ModifierSet key) { - keys.add(key); + keys.add(key); } public List getSortIndexes() { - return keys; + return keys; } @Override public void traverse(CQLNodeVisitor visitor) { - visitor.onSortNode(this); - subtree.traverse(visitor); + visitor.onSortNode(this); + subtree.traverse(visitor); } @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, - List sortkeys) { - if (sortkeys != null) - throw new Error("CQLSortNode.toXCQL() called with sortkeys"); - subtree.toXCQLInternal(b, level, prefixes, keys); + List sortkeys) { + if (sortkeys != null) + throw new Error("CQLSortNode.toXCQL() called with sortkeys"); + subtree.toXCQLInternal(b, level, prefixes, keys); } @Override public String toCQL() { - StringBuilder buf = new StringBuilder(subtree.toCQL()); + StringBuilder buf = new StringBuilder(subtree.toCQL()); - if (keys != null) { - buf.append(" sortby"); - for (int i = 0; i < keys.size(); i++) { - ModifierSet key = keys.get(i); - buf.append(" ").append(key.toCQL()); - } - } + if (keys != null) { + buf.append(" sortby"); + for (int i = 0; i < keys.size(); i++) { + ModifierSet key = keys.get(i); + buf.append(" ").append(key.toCQL()); + } + } - return buf.toString(); + return buf.toString(); } @Override public String toPQF(Properties config) throws PQFTranslationException { - return "@attr 1=oops \"###\""; + return "@attr 1=oops \"###\""; } @Override public byte[] toType1BER(Properties config) - throws PQFTranslationException { - // There is no way to represent sorting in a standard Z39.50 - // Type-1 query, so the best we can do is return the - // underlying query and ignore the sort-specification. + throws PQFTranslationException { + // There is no way to represent sorting in a standard Z39.50 + // Type-1 query, so the best we can do is return the + // underlying query and ignore the sort-specification. return subtree.toType1BER(config); } } diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index 6fa042d..9e6551d 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -7,7 +7,7 @@ /** * Represents a terminal node in a CQL parse-tree. * A term node consists of the term String itself, together with, - * optionally, an index string and a relation. Neither or both of + * optionally, an index string and a relation. Neither or both of * these must be provided - you can't have an index without a * relation or vice versa. * @@ -19,298 +19,313 @@ public class CQLTermNode extends CQLNode { /** * Creates a new term node with the specified index, - * relation and term. The first two may be + * relation and term. The first two may be * null, but the term may not. */ public CQLTermNode(String index, CQLRelation relation, String term) { - this.index = index; - this.relation = relation; - this.term = term; + this.index = index; + this.relation = relation; + this.term = term; } - public String getIndex() { return index; } - public CQLRelation getRelation() { return relation; } - public String getTerm() { return term; } + public String getIndex() { + return index; + } + + public CQLRelation getRelation() { + return relation; + } + + public String getTerm() { + return term; + } private static boolean isResultSetIndex(String qual) { - return (qual.equals("srw.resultSet") || - qual.equals("srw.resultSetId") || - qual.equals("srw.resultSetName") || - qual.equals("cql.resultSet") || - qual.equals("cql.resultSetId") || - qual.equals("cql.resultSetName")); + return (qual.equals("srw.resultSet") || + qual.equals("srw.resultSetId") || + qual.equals("srw.resultSetName") || + qual.equals("cql.resultSet") || + qual.equals("cql.resultSetId") || + qual.equals("cql.resultSetName")); } @Override public void traverse(CQLNodeVisitor visitor) { - //we visit relation first to allow filtering on relation type in the visitor - relation.traverse(visitor); - visitor.onTermNode(this); + // we visit relation first to allow filtering on relation type in the visitor + relation.traverse(visitor); + visitor.onTermNode(this); } - + @Override public String getResultSetName() { - if (isResultSetIndex(index)) - return term; - else - return null; + if (isResultSetIndex(index)) + return term; + else + return null; } @Override void toXCQLInternal(XCQLBuilder b, int level, List prefixes, - List sortkeys) { - b.indent(level).append("\n"); - renderPrefixes(b, level + 1, prefixes); - b.indent(level + 1).append("").xq(index).append("\n"); - relation.toXCQLInternal(b, level + 1); - b.indent(level + 1).append("").xq(term).append("\n"); - renderSortKeys(b, level + 1, sortkeys); - b.indent(level).append("\n"); + List sortkeys) { + b.indent(level).append("\n"); + renderPrefixes(b, level + 1, prefixes); + b.indent(level + 1).append("").xq(index).append("\n"); + relation.toXCQLInternal(b, level + 1); + b.indent(level + 1).append("").xq(term).append("\n"); + renderSortKeys(b, level + 1, sortkeys); + b.indent(level).append("\n"); } @Override public String toCQL() { - String quotedIndex = maybeQuote(index); - String quotedTerm = maybeQuote(term); - String res = quotedTerm; - - if (index != null && - !index.equalsIgnoreCase("srw.serverChoice") && - !index.equalsIgnoreCase("cql.serverChoice")) { - // ### We don't always need spaces around `relation'. - res = quotedIndex + " " + relation.toCQL() + " " + quotedTerm; - } - - return res; + String quotedIndex = maybeQuote(index); + String quotedTerm = maybeQuote(term); + String res = quotedTerm; + + if (index != null && + !index.equalsIgnoreCase("srw.serverChoice") && + !index.equalsIgnoreCase("cql.serverChoice")) { + // ### We don't always need spaces around `relation'. + res = quotedIndex + " " + relation.toCQL() + " " + quotedTerm; + } + + return res; } // ### Interaction between this and its callers is not good as - // regards truncation of the term and generation of truncation - // attributes. Change the interface to fix this. + // regards truncation of the term and generation of truncation + // attributes. Change the interface to fix this. private List getAttrs(Properties config) throws PQFTranslationException { - List attrs = new ArrayList(); - - // Do this first so that if any other truncation or - // completeness attributes are generated, they "overwrite" - // those specified here. - // - // ### This approach relies on an unpleasant detail of Index - // Data's (admittedly definitive) implementation of PQF, - // and should not relied upon. - // - String attr = config.getProperty("always"); - if (attr != null) - attrs.add(attr); - - attr = config.getProperty("index." + index); - if (attr == null) - attr = config.getProperty("qualifier." + index); - if (attr == null) - throw new UnknownIndexException(index); - attrs.add(attr); - - String rel = relation.getBase(); - if (rel.equals("=")) { - rel = "eq"; - } else if (rel.equals("==")) { - rel = "exact"; - } else if (rel.equals("<=")) { - rel = "le"; - } else if (rel.equals(">=")) { - rel = "ge"; - } - // ### Handling "any" and "all" properly would involve breaking - // the string down into a bunch of individual words and ORring - // or ANDing them together. Another day. - attr = config.getProperty("relation." + rel); - if (attr == null) - throw new UnknownRelationException(rel); - attrs.add(attr); - - List mods = relation.getModifiers(); - for (int i = 0; i < mods.size(); i++) { - String type = mods.get(i).type; - attr = config.getProperty("relationModifier." + type); - if (attr == null) - throw new UnknownRelationModifierException(type); - attrs.add(attr); - } - - String pos = "any"; - String truncation = "none"; - String text = term; - if (text.length() > 0 && text.substring(0, 1).equals("^")) { - text = text.substring(1); // ### change not seen by caller - pos = "first"; - } - if (text.startsWith("*") && text.endsWith("*")) { - truncation = "both"; - } else if (text.startsWith("*")) { - truncation = "left"; - } else if (text.endsWith("*")) { - truncation = "right"; - } - int len = text.length(); - if (len > 0 && text.substring(len-1, len).equals("^")) { - text = text.substring(0, len-1); // ### change not seen by caller - pos = pos.equals("first") ? "firstAndLast" : "last"; - // ### in the firstAndLast case, the standard - // pqf.properties file specifies that we generate a - // completeness=whole-field attributem, which means that - // we don't generate a position attribute at all. Do we - // care? Does it matter? - } - - attr = config.getProperty("position." + pos); - if (attr == null) - throw new UnknownPositionException(pos); - attrs.add(attr); - - attr = config.getProperty("truncation." + truncation); - if (attr == null) - throw new UnknownTruncationException(truncation); - attrs.add(attr); - - attr = config.getProperty("structure." + rel); - if (attr == null) - attr = config.getProperty("structure.*"); - attrs.add(attr); - - return attrs; + List attrs = new ArrayList(); + + // Do this first so that if any other truncation or + // completeness attributes are generated, they "overwrite" + // those specified here. + // + // ### This approach relies on an unpleasant detail of Index + // Data's (admittedly definitive) implementation of PQF, + // and should not relied upon. + // + String attr = config.getProperty("always"); + if (attr != null) + attrs.add(attr); + + attr = config.getProperty("index." + index); + if (attr == null) + attr = config.getProperty("qualifier." + index); + if (attr == null) + throw new UnknownIndexException(index); + attrs.add(attr); + + String rel = relation.getBase(); + if (rel.equals("=")) { + rel = "eq"; + } else if (rel.equals("==")) { + rel = "exact"; + } else if (rel.equals("<=")) { + rel = "le"; + } else if (rel.equals(">=")) { + rel = "ge"; + } + // ### Handling "any" and "all" properly would involve breaking + // the string down into a bunch of individual words and ORring + // or ANDing them together. Another day. + attr = config.getProperty("relation." + rel); + if (attr == null) + throw new UnknownRelationException(rel); + attrs.add(attr); + + List mods = relation.getModifiers(); + for (int i = 0; i < mods.size(); i++) { + String type = mods.get(i).type; + attr = config.getProperty("relationModifier." + type); + if (attr == null) + throw new UnknownRelationModifierException(type); + attrs.add(attr); + } + + String pos = "any"; + String truncation = "none"; + String text = term; + if (text.length() > 0 && text.substring(0, 1).equals("^")) { + text = text.substring(1); // ### change not seen by caller + pos = "first"; + } + if (text.startsWith("*") && text.endsWith("*")) { + truncation = "both"; + } else if (text.startsWith("*")) { + truncation = "left"; + } else if (text.endsWith("*")) { + truncation = "right"; + } + int len = text.length(); + if (len > 0 && text.substring(len - 1, len).equals("^")) { + text = text.substring(0, len - 1); // ### change not seen by caller + pos = pos.equals("first") ? "firstAndLast" : "last"; + // ### in the firstAndLast case, the standard + // pqf.properties file specifies that we generate a + // completeness=whole-field attribute, which means that + // we don't generate a position attribute at all. Do we + // care? Does it matter? + } + + attr = config.getProperty("position." + pos); + if (attr == null) + throw new UnknownPositionException(pos); + attrs.add(attr); + + attr = config.getProperty("truncation." + truncation); + if (attr == null) + throw new UnknownTruncationException(truncation); + attrs.add(attr); + + attr = config.getProperty("structure." + rel); + if (attr == null) + attr = config.getProperty("structure.*"); + attrs.add(attr); + + return attrs; } @Override public String toPQF(Properties config) throws PQFTranslationException { - if (isResultSetIndex(index)) { - // Special case: ignore relation, modifiers, wildcards, etc. - // There's parallel code in toType1BER() - return "@set " + maybeQuote(term); - } - - List attrs = getAttrs(config); - - String attr, s = ""; - for (int i = 0; i < attrs.size(); i++) { - attr = (String) attrs.get(i); - s += "@attr " + attr.replace(" ", " @attr ") + " "; - } - - String text = term; - if (text.length() > 0 && text.substring(0, 1).equals("^")) - text = text.substring(1); - int len = text.length(); - if (len > 0 && text.substring(len-1, len).equals("^")) - text = text.substring(0, len-1); - - len = text.length(); - if (text.startsWith("*") && text.endsWith("*")) { - text = text.substring(1, len-1); - } else if (text.startsWith("*")) { - text = text.substring(1); - } else if (text.endsWith("*")) { - text = text.substring(0, len-1); - } - - return s + maybeQuote(text); + if (isResultSetIndex(index)) { + // Special case: ignore relation, modifiers, wildcards, etc. + // There's parallel code in toType1BER() + return "@set " + maybeQuote(term); + } + + List attrs = getAttrs(config); + + String attr, s = ""; + for (int i = 0; i < attrs.size(); i++) { + attr = (String) attrs.get(i); + s += "@attr " + attr.replace(" ", " @attr ") + " "; + } + + String text = term; + if (text.length() > 0 && text.substring(0, 1).equals("^")) + text = text.substring(1); + int len = text.length(); + if (len > 0 && text.substring(len - 1, len).equals("^")) + text = text.substring(0, len - 1); + + len = text.length(); + if (text.startsWith("*") && text.endsWith("*")) { + text = text.substring(1, len - 1); + } else if (text.startsWith("*")) { + text = text.substring(1); + } else if (text.endsWith("*")) { + text = text.substring(0, len - 1); + } + + return s + maybeQuote(text); } static String maybeQuote(String str) { - if (str == null) - return null; - - // There _must_ be a better way to make this test ... - if (str.length() == 0 || - str.indexOf('"') != -1 || - str.indexOf(' ') != -1 || - str.indexOf('\t') != -1 || - str.indexOf('=') != -1 || - str.indexOf('<') != -1 || - str.indexOf('>') != -1 || - str.indexOf('/') != -1 || - str.indexOf('(') != -1 || - str.indexOf(')') != -1) { - str = '"' + str.replaceAll("(?') != -1 || + str.indexOf('/') != -1 || + str.indexOf('(') != -1 || + str.indexOf(')') != -1) { + str = '"' + str.replaceAll("(? 0 && text.substring(0, 1).equals("^")) - text = text.substring(1); - int len = text.length(); - if (len > 0 && text.substring(len-1, len).equals("^")) - text = text.substring(0, len-1); - - String attr, attrList; - byte[] operand = new byte[text.length()+100]; - int i, j, offset, type, value; - offset = putTag(CONTEXT, 0, CONSTRUCTED, operand, 0); // op - operand[offset++]=(byte)(0x80&0xff); // indefinite length - offset = putTag(CONTEXT, 102, CONSTRUCTED, operand, offset); // AttributesPlusTerm - operand[offset++] = (byte)(0x80&0xff); // indefinite length - offset = putTag(CONTEXT, 44, CONSTRUCTED, operand, offset); // AttributeList - operand[offset++] = (byte)(0x80&0xff); // indefinite length - - List attrs = getAttrs(config); - for(i = 0; i < attrs.size(); i++) { - attrList = (String) attrs.get(i); - java.util.StringTokenizer st = - new java.util.StringTokenizer(attrList); - while (st.hasMoreTokens()) { - attr = st.nextToken(); - j = attr.indexOf('='); - offset = putTag(UNIVERSAL, SEQUENCE, CONSTRUCTED, operand, offset); - operand[offset++] = (byte)(0x80&0xff); - offset = putTag(CONTEXT, 120, PRIMITIVE, operand, offset); - type = Integer.parseInt(attr.substring(0, j)); - offset = putLen(numLen(type), operand, offset); - offset = putNum(type, operand, offset); - - offset = putTag(CONTEXT, 121, PRIMITIVE, operand, offset); - value = Integer.parseInt(attr.substring(j+1)); - offset = putLen(numLen(value), operand, offset); - offset = putNum(value, operand, offset); - operand[offset++] = 0x00; // end of SEQUENCE - operand[offset++] = 0x00; - } - } - operand[offset++] = 0x00; // end of AttributeList - operand[offset++] = 0x00; - - offset = putTag(CONTEXT, 45, PRIMITIVE, operand, offset); // general Term - byte[] t = text.getBytes(); - offset = putLen(t.length, operand, offset); - System.arraycopy(t, 0, operand, offset, t.length); - offset += t.length; - - operand[offset++] = 0x00; // end of AttributesPlusTerm - operand[offset++] = 0x00; - operand[offset++] = 0x00; // end of Operand - operand[offset++] = 0x00; - byte[] o = new byte[offset]; - System.arraycopy(operand, 0, o, 0, offset); - return o; + if (isResultSetIndex(index)) { + // Special case: ignore relation, modifiers, wildcards, etc. + // There's parallel code in toPQF() + byte[] operand = new byte[term.length() + 100]; + int offset; + offset = putTag(CONTEXT, 0, CONSTRUCTED, operand, 0); // op + operand[offset++] = (byte) (0x80 & 0xff); // indefinite length + offset = putTag(CONTEXT, 31, PRIMITIVE, operand, offset); // ResultSetId + byte[] t = term.getBytes(); + offset = putLen(t.length, operand, offset); + System.arraycopy(t, 0, operand, offset, t.length); + offset += t.length; + operand[offset++] = 0x00; // end of Operand + operand[offset++] = 0x00; + byte[] o = new byte[offset]; + System.arraycopy(operand, 0, o, 0, offset); + return o; + } + + String text = term; + if (text.length() > 0 && text.substring(0, 1).equals("^")) + text = text.substring(1); + int len = text.length(); + if (len > 0 && text.substring(len - 1, len).equals("^")) + text = text.substring(0, len - 1); + + String attr, attrList; + byte[] operand = new byte[text.length() + 100]; + int i, j, offset, type, value; + offset = putTag(CONTEXT, 0, CONSTRUCTED, operand, 0); // op + operand[offset++] = (byte) (0x80 & 0xff); // indefinite length + offset = putTag(CONTEXT, 102, CONSTRUCTED, operand, offset); // AttributesPlusTerm + operand[offset++] = (byte) (0x80 & 0xff); // indefinite length + offset = putTag(CONTEXT, 44, CONSTRUCTED, operand, offset); // AttributeList + operand[offset++] = (byte) (0x80 & 0xff); // indefinite length + + List attrs = getAttrs(config); + for (i = 0; i < attrs.size(); i++) { + attrList = (String) attrs.get(i); + java.util.StringTokenizer st = new java.util.StringTokenizer(attrList); + while (st.hasMoreTokens()) { + attr = st.nextToken(); + j = attr.indexOf('='); + offset = putTag(UNIVERSAL, SEQUENCE, CONSTRUCTED, operand, offset); + operand[offset++] = (byte) (0x80 & 0xff); + offset = putTag(CONTEXT, 120, PRIMITIVE, operand, offset); + try { + type = Integer.parseInt(attr.substring(0, j)); + } catch (NumberFormatException e) { + throw new PQFTranslationException("Bad attribute type: " + attr.substring(0, j)); + } + offset = putLen(numLen(type), operand, offset); + offset = putNum(type, operand, offset); + + offset = putTag(CONTEXT, 121, PRIMITIVE, operand, offset); + try { + value = Integer.parseInt(attr.substring(j + 1)); + } catch (NumberFormatException e) { + throw new PQFTranslationException("Bad attribute value: " + attr.substring(j + 1)); + } + offset = putLen(numLen(value), operand, offset); + offset = putNum(value, operand, offset); + operand[offset++] = 0x00; // end of SEQUENCE + operand[offset++] = 0x00; + } + } + operand[offset++] = 0x00; // end of AttributeList + operand[offset++] = 0x00; + + offset = putTag(CONTEXT, 45, PRIMITIVE, operand, offset); // general Term + byte[] t = text.getBytes(); + offset = putLen(t.length, operand, offset); + System.arraycopy(t, 0, operand, offset, t.length); + offset += t.length; + + operand[offset++] = 0x00; // end of AttributesPlusTerm + operand[offset++] = 0x00; + operand[offset++] = 0x00; // end of Operand + operand[offset++] = 0x00; + byte[] o = new byte[offset]; + System.arraycopy(operand, 0, o, 0, offset); + return o; } } diff --git a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java index 8542dd9..2095f35 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTokenizer.java +++ b/src/main/java/org/z3950/zing/cql/CQLTokenizer.java @@ -2,56 +2,61 @@ /** * API bridge between the parser and lexer implementation + * * @author jakub */ public interface CQLTokenizer { - - public static final int TT_EOF = -1; - public static final int TT_WORD = -3; - public static final int TT_NOTHING = -4; - - public final static int TT_STRING = 999; // quoted string - public final static int TT_LE = 1000; // The "<=" relation - public final static int TT_GE = 1001; // The ">=" relation - public final static int TT_NE = 1002; // The "<>" relation - public final static int TT_EQEQ = 1003; // The "==" relation - public final static int TT_AND = 1004; // The "and" boolean - public final static int TT_OR = 1005; // The "or" boolean - public final static int TT_NOT = 1006; // The "not" boolean - public final static int TT_PROX = 1007; // The "prox" boolean - public final static int TT_SORTBY = 1008; // The "sortby" operator - - /** - * Consume next input token - */ - public void move(); - - /** - * Return the value of the last consumed token - * @return value of the token - */ - public String value(); - - /** - * Return the type of the last consumed token - * @return last consumed token - */ - public int what(); - - /** - * Render the type and value of the last consumed token - * @return human-readable string - */ - public String render(); - - /** - * Render specified token type - * @param what token type - * @param quote true, if single characters should be quoted for readability - * @return human-readable string - */ - public String render(int what, boolean quote); - - public int pos(); - + + public static final int TT_EOF = -1; + public static final int TT_WORD = -3; + public static final int TT_NOTHING = -4; + + public final static int TT_STRING = 999; // quoted string + public final static int TT_LE = 1000; // The "<=" relation + public final static int TT_GE = 1001; // The ">=" relation + public final static int TT_NE = 1002; // The "<>" relation + public final static int TT_EQEQ = 1003; // The "==" relation + public final static int TT_AND = 1004; // The "and" boolean + public final static int TT_OR = 1005; // The "or" boolean + public final static int TT_NOT = 1006; // The "not" boolean + public final static int TT_PROX = 1007; // The "prox" boolean + public final static int TT_SORTBY = 1008; // The "sortby" operator + + /** + * Consume next input token + */ + public void move(); + + /** + * Return the value of the last consumed token + * + * @return value of the token + */ + public String value(); + + /** + * Return the type of the last consumed token + * + * @return last consumed token + */ + public int what(); + + /** + * Render the type and value of the last consumed token + * + * @return human-readable string + */ + public String render(); + + /** + * Render specified token type + * + * @param what token type + * @param quote true, if single characters should be quoted for readability + * @return human-readable string + */ + public String render(int what, boolean quote); + + public int pos(); + } diff --git a/src/main/java/org/z3950/zing/cql/MissingParameterException.java b/src/main/java/org/z3950/zing/cql/MissingParameterException.java index b52b2cb..a25200a 100644 --- a/src/main/java/org/z3950/zing/cql/MissingParameterException.java +++ b/src/main/java/org/z3950/zing/cql/MissingParameterException.java @@ -7,10 +7,11 @@ public class MissingParameterException extends Exception { /** * Creates a new MissingParameterException. + * * @param s - * The name of the property whose value was required but not supplied. + * The name of the property whose value was required but not supplied. */ public MissingParameterException(String s) { - super(s); + super(s); } } diff --git a/src/main/java/org/z3950/zing/cql/Modifier.java b/src/main/java/org/z3950/zing/cql/Modifier.java index af68453..37b21d8 100644 --- a/src/main/java/org/z3950/zing/cql/Modifier.java +++ b/src/main/java/org/z3950/zing/cql/Modifier.java @@ -2,7 +2,7 @@ /** * Represents a single modifier, consisting of three elements: a type, - * a comparision and a value. For example, "distance", "<", "3". The + * a comparison and a value. For example, "distance", "<", "3". The * type is mandatory; either the comparison and value must both occur, * or neither must. *

@@ -19,10 +19,11 @@ public class Modifier { * and value. */ public Modifier(String type, String comparison, String value) { - this.type = type; - this.comparison = comparison; - this.value = value; - //System.err.println("Made new modifier with " + "type='" + type + "', " + "comparison='" + comparison + "', " + "value='" + value + "',\n"); + this.type = type; + this.comparison = comparison; + this.value = value; + // System.err.println("Made new modifier with " + "type='" + type + "', " + + // "comparison='" + comparison + "', " + "value='" + value + "',\n"); } /** @@ -30,48 +31,48 @@ public Modifier(String type, String comparison, String value) { * comparison or value. */ public Modifier(String type) { - this.type = type; - //System.err.println("Made new modifier of type '" + type + "'\n"); + this.type = type; + // System.err.println("Made new modifier of type '" + type + "'\n"); } /** * Returns the type with which the Modifier was created. */ public String getType() { - return type; + return type; } /** * Returns the comparison with which the Modifier was created. */ public String getComparison() { - return comparison; + return comparison; } /** * Returns the value with which the Modifier was created. */ public String getValue() { - return value; + return value; } void toXCQLInternal(XCQLBuilder b, int level, String relationElement) { - b.indent(level).append("\n"); + b.indent(level).append("\n"); b.indent(level + 1).append(""); b.xq(type).append("\n"); - if (value != null) { + if (value != null) { b.indent(level + 1).append("<").append(relationElement).append(">"); b.xq(comparison).append("\n"); b.indent(level + 1).append(""); b.xq(value).append("\n"); - } - b.indent(level).append("\n"); + } + b.indent(level).append("\n"); } public String toCQL() { - StringBuilder buf = new StringBuilder(type); - if (value != null) - buf.append(" ").append(comparison).append(" ").append(value); - return buf.toString(); + StringBuilder buf = new StringBuilder(type); + if (value != null) + buf.append(" ").append(comparison).append(" ").append(value); + return buf.toString(); } } diff --git a/src/main/java/org/z3950/zing/cql/ModifierSet.java b/src/main/java/org/z3950/zing/cql/ModifierSet.java index 754af1e..3456155 100644 --- a/src/main/java/org/z3950/zing/cql/ModifierSet.java +++ b/src/main/java/org/z3950/zing/cql/ModifierSet.java @@ -25,15 +25,15 @@ public class ModifierSet { * Creates a new ModifierSet with the specified base. */ public ModifierSet(String base) { - this.base = base; - modifiers = new ArrayList(); + this.base = base; + modifiers = new ArrayList(); } /** * Returns the base string with which the ModifierSet was created. */ public String getBase() { - return base; + return base; } /** @@ -41,8 +41,8 @@ public String getBase() { * comparison and value to a ModifierSet. */ public void addModifier(String type, String comparison, String value) { - Modifier modifier = new Modifier(type, comparison, value); - modifiers.add(modifier); + Modifier modifier = new Modifier(type, comparison, value); + modifiers.add(modifier); } /** @@ -50,8 +50,8 @@ public void addModifier(String type, String comparison, String value) { * comparison and value, to a ModifierSet. */ public void addModifier(String type) { - Modifier modifier = new Modifier(type); - modifiers.add(modifier); + Modifier modifier = new Modifier(type); + modifiers.add(modifier); } /** @@ -59,60 +59,59 @@ public void addModifier(String type) { * that corresponds to the specified type. */ public String modifier(String type) { - int n = modifiers.size(); - for (int i = 0; i < n; i++) { - Modifier mod = modifiers.get(i); - if (mod.type.equals(type)) - return mod.value; - } - return null; + int n = modifiers.size(); + for (int i = 0; i < n; i++) { + Modifier mod = modifiers.get(i); + if (mod.type.equals(type)) + return mod.value; + } + return null; } /** * Returns an array of the modifiers in a ModifierSet. + * * @return - * An array of Modifiers. + * An array of Modifiers. */ public List getModifiers() { - return modifiers; + return modifiers; } void toXCQLInternal(XCQLBuilder b, int level, - String topLevelElement, String valueElement) { - b.indent(level).append("<").append(topLevelElement). - append(">\n").indent(level + 1).append("<"). - append(valueElement).append(">").xq(base).append("\n"); - if (modifiers.size() > 0) { - b.indent(level + 1).append("\n"); - for (int i = 0; i < modifiers.size(); i++) { - modifiers.get(i).toXCQLInternal(b, level+2, "comparison"); - } - b.indent(level + 1).append("\n"); - } - b.indent(level).append("\n"); + String topLevelElement, String valueElement) { + b.indent(level).append("<").append(topLevelElement).append(">\n").indent(level + 1).append("<") + .append(valueElement).append(">").xq(base).append("\n"); + if (modifiers.size() > 0) { + b.indent(level + 1).append("\n"); + for (int i = 0; i < modifiers.size(); i++) { + modifiers.get(i).toXCQLInternal(b, level + 2, "comparison"); + } + b.indent(level + 1).append("\n"); + } + b.indent(level).append("\n"); } public String toCQL() { - StringBuilder buf = new StringBuilder(base); - for (int i = 0; i < modifiers.size(); i++) { - buf.append("/").append(modifiers.get(i).toCQL()); - } + StringBuilder buf = new StringBuilder(base); + for (int i = 0; i < modifiers.size(); i++) { + buf.append("/").append(modifiers.get(i).toCQL()); + } - return buf.toString(); + return buf.toString(); } public static void main(String[] args) { - if (args.length < 1) { - System.err.println("Usage: ModifierSet [ ]..."); - System.exit(1); - } + if (args.length < 1) { + System.err.println("Usage: ModifierSet [ ]..."); + System.exit(1); + } - ModifierSet res = new ModifierSet(args[0]); - for (int i = 1; i < args.length; i += 3) { - res.addModifier(args[i], args[i+1], args[i+2]); - } + ModifierSet res = new ModifierSet(args[0]); + for (int i = 1; i + 2 < args.length ; i += 3) { + res.addModifier(args[i], args[i + 1], args[i + 2]); + } - System.out.println(res.toCQL()); + System.out.println(res.toCQL()); } } diff --git a/src/main/java/org/z3950/zing/cql/PQFTranslationException.java b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java index a095776..b214b42 100644 --- a/src/main/java/org/z3950/zing/cql/PQFTranslationException.java +++ b/src/main/java/org/z3950/zing/cql/PQFTranslationException.java @@ -6,6 +6,6 @@ */ public class PQFTranslationException extends Exception { PQFTranslationException(String s) { - super(s); + super(s); } } diff --git a/src/main/java/org/z3950/zing/cql/UnknownIndexException.java b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java index e460dfc..48e2ec9 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownIndexException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownIndexException.java @@ -4,7 +4,7 @@ * Exception indicating that an index was not recognised. * At compilation time, we accept any syntactically valid index; * but when rendering a tree out as PQF, we need to translate the - * indexes into sets of Type-1 query attributes. If we can't do + * indexes into sets of Type-1 query attributes. If we can't do * that, because the PQF configuration doesn't know about a relation, * we throw one of these babies. * @@ -12,10 +12,11 @@ public class UnknownIndexException extends PQFTranslationException { /** * Creates a new UnknownIndexException. + * * @param s - * The index for which there was no PQF configuration. + * The index for which there was no PQF configuration. */ public UnknownIndexException(String s) { - super(s); + super(s); } } diff --git a/src/main/java/org/z3950/zing/cql/UnknownPositionException.java b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java index c7d9c12..0b24ffe 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownPositionException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownPositionException.java @@ -5,19 +5,20 @@ * When rendering a tree out as PQF, each term is classified either as * any, first, last or * firstAndLast, depending on whether it begins and/or ends - * with the word-anchoring meta-character ^. Its + * with the word-anchoring meta-character ^. Its * classification is looked up as a position in the PQF - * configuration. If the position is not configured, we throw one of + * configuration. If the position is not configured, we throw one of * these babies. * */ public class UnknownPositionException extends PQFTranslationException { /** * Creates a new UnknownPositionException. + * * @param s - * The position for which there was no PQF configuration. + * The position for which there was no PQF configuration. */ public UnknownPositionException(String s) { - super(s); + super(s); } } diff --git a/src/main/java/org/z3950/zing/cql/UnknownRelationException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java index d4998b0..23b3589 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownRelationException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownRelationException.java @@ -4,7 +4,7 @@ * Exception indicating that a relation was not recognised. * At compilation time, we accept any syntactically valid relation; * but when rendering a tree out as PQF, we need to translate the - * relations into sets of Type-1 query attributes. If we can't do + * relations into sets of Type-1 query attributes. If we can't do * that, because the PQF configuration doesn't know about a relation, * we throw one of these babies. * @@ -12,10 +12,11 @@ public class UnknownRelationException extends PQFTranslationException { /** * Creates a new UnknownRelationException. + * * @param s - * The relation for which there was no PQF configuration. + * The relation for which there was no PQF configuration. */ public UnknownRelationException(String s) { - super(s); + super(s); } } diff --git a/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java index b27d952..5a31c7c 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownRelationModifierException.java @@ -4,7 +4,7 @@ * Exception indicating that a relation modifier was not recognised. * At compilation time, we accept any syntactically valid relation modifier; * but when rendering a tree out as PQF, we need to translate the - * relation modifiers into sets of Type-1 query attributes. If we can't do + * relation modifiers into sets of Type-1 query attributes. If we can't do * that, because the PQF configuration doesn't know about a relation modifier, * we throw one of these babies. * @@ -12,10 +12,11 @@ public class UnknownRelationModifierException extends PQFTranslationException { /** * Creates a new UnknownRelationModifierException. + * * @param s - * The relation modifier for which there was no PQF configuration. + * The relation modifier for which there was no PQF configuration. */ public UnknownRelationModifierException(String s) { - super(s); + super(s); } } diff --git a/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java b/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java index 024fd2e..ea65b3a 100644 --- a/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java +++ b/src/main/java/org/z3950/zing/cql/UnknownTruncationException.java @@ -3,7 +3,8 @@ /** * Exception indicating that a truncation was not recognised. When rendering a * tree out as PQF, each term is classified either as left, - * right, left and right truncated, depending on whether + * right, left and right truncated, depending on + * whether * it begins and/or ends with the character *. Its * classification is looked up as a truncation in the PQF * configuration. If the truncation is not configured, we throw one of these @@ -11,15 +12,15 @@ * */ public class UnknownTruncationException extends PQFTranslationException { - private static final long serialVersionUID = 6971993723734811253L; + private static final long serialVersionUID = 6971993723734811253L; - /** - * Creates a new UnknownTruncationException. - * - * @param s - * The truncation for which there was no PQF configuration. - */ - public UnknownTruncationException(String s) { - super(s); - } + /** + * Creates a new UnknownTruncationException. + * + * @param s + * The truncation for which there was no PQF configuration. + */ + public UnknownTruncationException(String s) { + super(s); + } } diff --git a/src/main/java/org/z3950/zing/cql/XCQLBuilder.java b/src/main/java/org/z3950/zing/cql/XCQLBuilder.java index 9b3d8fd..c35a280 100644 --- a/src/main/java/org/z3950/zing/cql/XCQLBuilder.java +++ b/src/main/java/org/z3950/zing/cql/XCQLBuilder.java @@ -5,45 +5,46 @@ * @author jakub */ class XCQLBuilder { - private StringBuilder sb; + private StringBuilder sb; - XCQLBuilder(StringBuilder sb) { - this.sb = sb; - } + XCQLBuilder(StringBuilder sb) { + this.sb = sb; + } + + XCQLBuilder indent(int level) { + while (level-- > 0) { + sb.append(" "); + } + return this; + } - XCQLBuilder indent(int level) { - while (level-- > 0) { - sb.append(" "); + XCQLBuilder xq(String str) { + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + switch (c) { + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + case '&': + sb.append("&"); + break; + default: + sb.append(c); + } + } + return this; } - return this; - } - XCQLBuilder xq(String str) { - for (int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - switch (c) { - case '<': - sb.append("<"); - break; - case '>': - sb.append(">"); - break; - case '&': - sb.append("&"); - break; - default: - sb.append(c); - } + XCQLBuilder append(String str) { + sb.append(str); + return this; } - return this; - } - - XCQLBuilder append(String str) { - sb.append(str); - return this; - } - public String toString() { - return sb.toString(); - } -} \ No newline at end of file + @Override + public String toString() { + return sb.toString(); + } +} diff --git a/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java b/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java index 8324098..b2da280 100644 --- a/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java +++ b/src/test/java/org/z3950/zing/cql/CQLNodeVisitorTest.java @@ -15,117 +15,125 @@ * @author jakub */ public class CQLNodeVisitorTest { - - public CQLNodeVisitorTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } - - @Test - public void testPrefixVisitor() { - String cql = "((x=a and y=b) or z=c)"; - String epxected = "@or @and @attr 1=x a @attr 1=y b @attr 1=z c"; - CQLParser p = new CQLParser(CQLParser.V1POINT2); - out.println("Parsing "+cql); - try { - CQLNode n = p.parse(cql); - CQLNodeVisitor v = new CQLDefaultNodeVisitor() { - String actual = ""; - String termSep = ""; - @Override - public void onBooleanNodeStart(CQLBooleanNode node) { - String op = ""; - switch (node.getOperator()) { - case AND: op = "@and"; break; - case OR: op = "@or"; break; - } - actual += op + " "; - } - - @Override - public void onTermNode(CQLTermNode node) { - actual += termSep + "@attr 1="+node.getIndex() + " " + node.getTerm(); - termSep = " "; - } - - @Override - public String toString() { - return actual; - } - }; - n.traverse(v); - out.println(v); - assertEquals(epxected, v.toString()); - } catch (CQLParseException ex) { - fail(ex.getMessage()); - } catch (IOException ex) { - fail(ex.getMessage()); + + public CQLNodeVisitorTest() { } - } - - @Test - public void testInfixVisitor() { - String cql = "((x=a and y=b) or z=c)"; - String epxected = "((x:a OG y:b) ELLER z:c)"; - CQLParser p = new CQLParser(CQLParser.V1POINT2); - out.println("Parsing "+cql); - try { - CQLNode n = p.parse(cql); - CQLNodeVisitor v = new CQLDefaultNodeVisitor() { - String actual = ""; - - @Override - public void onBooleanNodeStart(CQLBooleanNode node) { - actual += "("; - } - - @Override - public void onBooleanNodeOp(CQLBooleanNode node) { - String op = ""; - switch (node.getOperator()) { - case AND: op = "OG"; break; - case OR: op = "ELLER"; break; - } - actual += " " + op + " "; - } - @Override - public void onBooleanNodeEnd(CQLBooleanNode node) { - actual += ")"; - } - - @Override - public void onTermNode(CQLTermNode node) { - actual += node.getIndex() + ":" + node.getTerm(); + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + @Test + public void testPrefixVisitor() { + String cql = "((x=a and y=b) or z=c)"; + String epxected = "@or @and @attr 1=x a @attr 1=y b @attr 1=z c"; + CQLParser p = new CQLParser(CQLParser.V1POINT2); + out.println("Parsing " + cql); + try { + CQLNode n = p.parse(cql); + CQLNodeVisitor v = new CQLDefaultNodeVisitor() { + String actual = ""; + String termSep = ""; + + @Override + public void onBooleanNodeStart(CQLBooleanNode node) { + String op = ""; + switch (node.getOperator()) { + case AND: + op = "@and"; + break; + case OR: + op = "@or"; + break; + } + actual += op + " "; + } + + @Override + public void onTermNode(CQLTermNode node) { + actual += termSep + "@attr 1=" + node.getIndex() + " " + node.getTerm(); + termSep = " "; + } + + @Override + public String toString() { + return actual; + } + }; + n.traverse(v); + out.println(v); + assertEquals(epxected, v.toString()); + } catch (CQLParseException ex) { + fail(ex.getMessage()); + } catch (IOException ex) { + fail(ex.getMessage()); } - - @Override - public String toString() { - return actual; + } + + @Test + public void testInfixVisitor() { + String cql = "((x=a and y=b) or z=c)"; + String epxected = "((x:a OG y:b) ELLER z:c)"; + CQLParser p = new CQLParser(CQLParser.V1POINT2); + out.println("Parsing " + cql); + try { + CQLNode n = p.parse(cql); + CQLNodeVisitor v = new CQLDefaultNodeVisitor() { + String actual = ""; + + @Override + public void onBooleanNodeStart(CQLBooleanNode node) { + actual += "("; + } + + @Override + public void onBooleanNodeOp(CQLBooleanNode node) { + String op = ""; + switch (node.getOperator()) { + case AND: + op = "OG"; + break; + case OR: + op = "ELLER"; + break; + } + actual += " " + op + " "; + } + + @Override + public void onBooleanNodeEnd(CQLBooleanNode node) { + actual += ")"; + } + + @Override + public void onTermNode(CQLTermNode node) { + actual += node.getIndex() + ":" + node.getTerm(); + } + + @Override + public String toString() { + return actual; + } + }; + n.traverse(v); + out.println(v); + assertEquals(epxected, v.toString()); + } catch (CQLParseException ex) { + fail(ex.getMessage()); + } catch (IOException ex) { + fail(ex.getMessage()); } - }; - n.traverse(v); - out.println(v); - assertEquals(epxected, v.toString()); - } catch (CQLParseException ex) { - fail(ex.getMessage()); - } catch (IOException ex) { - fail(ex.getMessage()); } - } - } diff --git a/src/test/java/org/z3950/zing/cql/CQLParserTest.java b/src/test/java/org/z3950/zing/cql/CQLParserTest.java index ed0c1ab..5995b5c 100644 --- a/src/test/java/org/z3950/zing/cql/CQLParserTest.java +++ b/src/test/java/org/z3950/zing/cql/CQLParserTest.java @@ -28,166 +28,200 @@ * @author jakub */ public class CQLParserTest { - public CQLParserTest() { - } - - @BeforeClass - public static void setUpClass() { - } - - @AfterClass - public static void tearDownClass() { - } - - @Before - public void setUp() { - } - - @After - public void tearDown() { - } + public CQLParserTest() { + } - /** - * Test of main method, of class CQLParser. - */ - @Test - public void testRegressionQueries() throws IOException { - System.out.println("Testing the parser using pre-canned regression queries..."); - //we might be running the test from within the jar - //list all resource dirs, then traverse them - String[] dirs = getResourceListing(this.getClass(), "regression"); - for (String dir : dirs) { - String files[] = getResourceListing(this.getClass(), "regression/" + dir); - for (String file : files) { - if (!file.endsWith(".cql")) continue; - out.println("Parsing "+dir+"/"+file); - InputStream is = this.getClass().getResourceAsStream("/regression/"+dir+"/"+file); - BufferedReader reader = null, reader2 = null; - try { - reader = new BufferedReader(new InputStreamReader(is)); - String input = reader.readLine(); - out.println("Query: "+input); - String result; - try { - CQLParser parser = new CQLParser(); - CQLNode parsed = parser.parse(input); - result = parsed.toXCQL(); - } catch (CQLParseException pe) { - result = pe.getMessage() + "\n"; - } - out.println("Parsed:"); - out.println(result); - //read the expected xcql output - String expected = ""; - String prefix = file.substring(0, file.length()-4); - InputStream is2 = this.getClass() - .getResourceAsStream("/regression/"+dir+"/"+prefix+".xcql"); - if (is2 != null) { - reader2 = new BufferedReader(new InputStreamReader(is2)); - StringBuilder sb = new StringBuilder(); - String line; - while ((line = reader2.readLine()) != null) { - sb.append(line).append("\n"); - } - expected = sb.toString(); - } - out.println("Expected: "); - out.println(expected); - assertEquals("Assertion failure for "+dir+"/"+file, expected, result); - } finally { - if (reader != null) reader.close(); - if (reader2 != null) reader2.close(); - } - } + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { } - } - - /** - * Test the integrity of the parser as follows: - * - Generate a random tree with CQLGenerator - * - Serialize it - * - Canonicalise it by running through the parser - * - Compare the before-and-after versions. - * Since the CQLGenerator output is in canonical form anyway, the - * before-and-after versions should be identical. This process exercises - * the comprehensiveness and bullet-proofing of the parser, as well as - * the accuracy of the rendering. - * @throws IOException - * @throws MissingParameterException - */ - @Test - public void testRandomQueries() throws IOException, MissingParameterException { - out.println("Testing the parser using 100 randomly generated queries..."); - Properties params = new Properties(); - InputStream is = getClass().getResourceAsStream("/generate.properties"); - if (is == null) - fail("Cannot locate generate.properties"); - params.load(is); - is.close(); - CQLGenerator generator = new CQLGenerator(params); - for (int i=0; i<1000; i++) { - CQLNode random = generator.generate(); - String expected = random.toCQL(); - out.println("Generated query: "+expected); - CQLParser parser = new CQLParser(); - try { - CQLNode parsed = parser.parse(expected); - String result = parsed.toCQL(); - assertEquals(expected, result); - } catch (CQLParseException pe) { - fail("Generated query failed to parse: "+pe.getMessage()); - } + + @Before + public void setUp() { + } + + @After + public void tearDown() { } - } - - //helper methods follow - //TODO move to masterkey-common - - @SuppressWarnings("rawtypes") - public static String[] getResourceListing(Class clazz, String path) throws - IOException { - URL dirURL = clazz.getClassLoader().getResource(path); - if (dirURL != null && dirURL.getProtocol().equals("file")) { - /* A file path: easy enough */ - try { - return new File(dirURL.toURI()).list(); - } catch (URISyntaxException use) { - throw new UnsupportedOperationException(use); - } + + /** + * Test of main method, of class CQLParser. + */ + @Test + public void testRegressionQueries() throws IOException { + System.out.println("Testing the parser using pre-canned regression queries..."); + // we might be running the test from within the jar + // list all resource dirs, then traverse them + String[] dirs = getResourceListing(this.getClass(), "regression"); + for (String dir : dirs) { + String files[] = getResourceListing(this.getClass(), "regression/" + dir); + for (String file : files) { + if (!file.endsWith(".cql")) + continue; + out.println("Parsing " + dir + "/" + file); + InputStream is = this.getClass().getResourceAsStream("/regression/" + dir + "/" + file); + BufferedReader reader = null, reader2 = null; + try { + reader = new BufferedReader(new InputStreamReader(is)); + String input = reader.readLine(); + out.println("Query: " + input); + String result; + try { + CQLParser parser = new CQLParser(); + CQLNode parsed = parser.parse(input); + result = parsed.toXCQL(); + } catch (CQLParseException pe) { + result = pe.getMessage() + "\n"; + } + out.println("Parsed:"); + out.println(result); + // read the expected xcql output + String expected = ""; + String prefix = file.substring(0, file.length() - 4); + InputStream is2 = this.getClass() + .getResourceAsStream("/regression/" + dir + "/" + prefix + ".xcql"); + if (is2 != null) { + reader2 = new BufferedReader(new InputStreamReader(is2)); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader2.readLine()) != null) { + sb.append(line).append("\n"); + } + expected = sb.toString(); + } + out.println("Expected: "); + out.println(expected); + assertEquals("Assertion failure for " + dir + "/" + file, expected, result); + } finally { + if (reader != null) + reader.close(); + if (reader2 != null) + reader2.close(); + } + } + } } - if (dirURL == null) { - /* - * In case of a jar file, we can't actually find a directory. - * Have to assume the same jar as clazz. - */ - String me = clazz.getName().replace(".", "/") + ".class"; - dirURL = clazz.getClassLoader().getResource(me); + /** + * Test the integrity of the parser as follows: + * - Generate a random tree with CQLGenerator + * - Serialize it + * - Canonicalise it by running through the parser + * - Compare the before-and-after versions. + * Since the CQLGenerator output is in canonical form anyway, the + * before-and-after versions should be identical. This process exercises + * the comprehensiveness and bullet-proofing of the parser, as well as + * the accuracy of the rendering. + * + * @throws IOException + * @throws MissingParameterException + */ + @Test + public void testRandomQueries() throws IOException, MissingParameterException { + out.println("Testing the parser using 100 randomly generated queries..."); + Properties params = new Properties(); + InputStream is = getClass().getResourceAsStream("/generate.properties"); + if (is == null) + fail("Cannot locate generate.properties"); + params.load(is); + is.close(); + CQLGenerator generator = new CQLGenerator(params); + for (int i = 0; i < 1000; i++) { + CQLNode random = generator.generate(); + String expected = random.toCQL(); + out.println("Generated query: " + expected); + CQLParser parser = new CQLParser(); + try { + CQLNode parsed = parser.parse(expected); + String result = parsed.toCQL(); + assertEquals(expected, result); + } catch (CQLParseException pe) { + fail("Generated query failed to parse: " + pe.getMessage()); + } + } } - if (dirURL.getProtocol().equals("jar")) { - /* A JAR path */ - String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf( - "!")); //strip out only the JAR file - JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8")); - Enumeration entries = jar.entries(); //gives ALL entries in jar - Set result = new HashSet(); //avoid duplicates in case it is a subdirectory - while (entries.hasMoreElements()) { - String name = entries.nextElement().getName(); - if (name.startsWith(path)) { //filter according to the path - String entry = name.substring(path.length()); - int checkSubdir = entry.indexOf("/"); - if (checkSubdir >= 0) { - // if it is a subdirectory, we just return the directory name - entry = entry.substring(0, checkSubdir); - } - result.add(entry); + @SuppressWarnings("rawtypes") + public static String[] getResourceListing(Class clazz, String path) throws IOException { + URL dirURL = clazz.getClassLoader().getResource(path); + if (dirURL != null && dirURL.getProtocol().equals("file")) { + /* A file path: easy enough */ + try { + return new File(dirURL.toURI()).list(); + } catch (URISyntaxException use) { + throw new UnsupportedOperationException(use); + } + } + + if (dirURL == null) { + /* + * In case of a jar file, we can't actually find a directory. + * Have to assume the same jar as clazz. + */ + String me = clazz.getName().replace(".", "/") + ".class"; + dirURL = clazz.getClassLoader().getResource(me); } - } - return result.toArray(new String[result.size()]); + + if (dirURL.getProtocol().equals("jar")) { + /* A JAR path */ + String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf( + "!")); // strip out only the JAR file + try (JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"))) { + Enumeration entries = jar.entries(); // gives ALL entries in jar + Set result = new HashSet(); // avoid duplicates in case it is a subdirectory + while (entries.hasMoreElements()) { + String name = entries.nextElement().getName(); + if (name.startsWith(path)) { // filter according to the path + String entry = name.substring(path.length()); + int checkSubdir = entry.indexOf("/"); + if (checkSubdir >= 0) { + // if it is a subdirectory, we just return the directory name + entry = entry.substring(0, checkSubdir); + } + result.add(entry); + } + } + return result.toArray(new String[result.size()]); + } + } + throw new UnsupportedOperationException("Cannot list files for URL " + + dirURL); } - throw new UnsupportedOperationException("Cannot list files for URL " - + dirURL); - } -} \ No newline at end of file + @Test + public void testMakeOID() { + String[] oids = { + "1.2", + "1.2.840.10003.5.109.10", + "2.16.840", + }; + int [][] expected = { + {42}, + {42, 134, 72, 206, 19, 5, 109, 10}, + {96, 134, 72}, + }; + int i = 0; + for (String oid : oids) { + out.println("Testing OID: " + oid); + byte[] encoded = CQLNode.makeOID(oid); + for (int j = 0; j < expected[i].length && j < encoded.length; j++) { + assertEquals("Byte " + j + " of OID " + oid, expected[i][j], encoded[j] & 0xff); + } + assertEquals("Length of OID " + oid, expected[i].length, encoded.length); + i++; + } + // not very consistent below, but this is how it is implemented + assertNull(CQLNode.makeOID("")); + assertNull(CQLNode.makeOID("1")); + assertNull(CQLNode.makeOID("b")); + assertThrows(NumberFormatException.class, () -> { + CQLNode.makeOID("1a."); + }); + assertThrows(NumberFormatException.class, () -> { + CQLNode.makeOID("1.b"); + }); + } +} From efaf5ae0116119068bb5d5248035e1e380f69017 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 3 Feb 2026 12:18:39 +0100 Subject: [PATCH 146/147] Proper fixup for " when generating CQL query (#26) The replaceAll for looking back whether the " was escaped did not work as the preceding backslash could have been the result of escaping a backslash itself. Also deal with a trailing backslash (unterminated sequence). A follow up for #5 --- .../java/org/z3950/zing/cql/CQLLexer.java | 5 +- .../java/org/z3950/zing/cql/CQLTermNode.java | 52 +++++++++------- .../org/z3950/zing/cql/CQLTermNodeTest.java | 62 +++++++++++++++++++ 3 files changed, 96 insertions(+), 23 deletions(-) create mode 100644 src/test/java/org/z3950/zing/cql/CQLTermNodeTest.java diff --git a/src/main/java/org/z3950/zing/cql/CQLLexer.java b/src/main/java/org/z3950/zing/cql/CQLLexer.java index c27ba40..a598b01 100644 --- a/src/main/java/org/z3950/zing/cql/CQLLexer.java +++ b/src/main/java/org/z3950/zing/cql/CQLLexer.java @@ -18,6 +18,8 @@ public class CQLLexer implements CQLTokenizer { private String lval; private StringBuilder buf = new StringBuilder(); + static final String OPS_AND_WHITESPACE = "()/<>= \t\r\n"; + public CQLLexer(String cql, boolean debug) { qs = cql; ql = cql.length(); @@ -89,8 +91,7 @@ public void move() { } else { what = TT_WORD; buf.setLength(0); // reset buffer - while (qi < ql - && !strchr("()/<>= \t\r\n", qs.charAt(qi))) { + while (qi < ql && !strchr(OPS_AND_WHITESPACE, qs.charAt(qi))) { buf.append(qs.charAt(qi)); qi++; } diff --git a/src/main/java/org/z3950/zing/cql/CQLTermNode.java b/src/main/java/org/z3950/zing/cql/CQLTermNode.java index 9e6551d..13a26c8 100644 --- a/src/main/java/org/z3950/zing/cql/CQLTermNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLTermNode.java @@ -78,8 +78,8 @@ void toXCQLInternal(XCQLBuilder b, int level, List prefixes, @Override public String toCQL() { - String quotedIndex = maybeQuote(index); - String quotedTerm = maybeQuote(term); + String quotedIndex = toCQLTerm(index); + String quotedTerm = toCQLTerm(term); String res = quotedTerm; if (index != null && @@ -192,7 +192,7 @@ public String toPQF(Properties config) throws PQFTranslationException { if (isResultSetIndex(index)) { // Special case: ignore relation, modifiers, wildcards, etc. // There's parallel code in toType1BER() - return "@set " + maybeQuote(term); + return "@set " + toCQLTerm(term); } List attrs = getAttrs(config); @@ -219,28 +219,38 @@ public String toPQF(Properties config) throws PQFTranslationException { text = text.substring(0, len - 1); } - return s + maybeQuote(text); + return s + toCQLTerm(text); } - static String maybeQuote(String str) { - if (str == null) + // ensure that a term is properly quoted for CQL output if necessary. + // If the term has a bare double-quote (") it will be + // escaped with a backslash. + static String toCQLTerm(String str) { + if (str == null) { return null; - - // There _must_ be a better way to make this test ... - if (str.length() == 0 || - str.indexOf('"') != -1 || - str.indexOf(' ') != -1 || - str.indexOf('\t') != -1 || - str.indexOf('=') != -1 || - str.indexOf('<') != -1 || - str.indexOf('>') != -1 || - str.indexOf('/') != -1 || - str.indexOf('(') != -1 || - str.indexOf(')') != -1) { - str = '"' + str.replaceAll("(?= 0) { + quote = true; + } + if (ch == '"' && !escaped) { + sb.append('\\'); + } + escaped = ch == '\\' && !escaped; + sb.append(ch); + } + if (escaped) { + // trailing backslash - escape it + sb.append('\\'); + } + if (quote) { + return "\"" + sb.toString() + "\""; + } else { + return sb.toString(); + } } @Override diff --git a/src/test/java/org/z3950/zing/cql/CQLTermNodeTest.java b/src/test/java/org/z3950/zing/cql/CQLTermNodeTest.java new file mode 100644 index 0000000..760c1fa --- /dev/null +++ b/src/test/java/org/z3950/zing/cql/CQLTermNodeTest.java @@ -0,0 +1,62 @@ +package org.z3950.zing.cql; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class CQLTermNodeTest { + @Test + public void TestTCQLTermQuoteNull() { + assertNull(CQLTermNode.toCQLTerm(null)); + } + + @Test + public void TestTCQLTermQuoteEmpty() { + assertEquals("\"\"", CQLTermNode.toCQLTerm("")); + } + + @Test + public void TestTCQLTermQuoteRelation() { + assertEquals("\"<\"", CQLTermNode.toCQLTerm("<")); + } + + @Test + public void TestTCQLTermQuoteSimple() { + assertEquals("simple", CQLTermNode.toCQLTerm("simple")); + } + + @Test + public void TestTCQLTermQuoteBlank() { + assertEquals("\"a b\"", CQLTermNode.toCQLTerm("a b")); + } + + @Test + public void TestTCQLTermQuoteQuote1() { + assertEquals("a\\\"", CQLTermNode.toCQLTerm("a\"")); + } + + @Test + public void TestTCQLTermQuoteQuote2() { + assertEquals("a\\\"", CQLTermNode.toCQLTerm("a\\\"")); + } + + @Test + public void TestTCQLTermQuoteQuote3() { + assertEquals("a" + "\\\\" + "\\\"", CQLTermNode.toCQLTerm("a" + "\\\\" + "\"")); + } + + @Test + public void TestTCQLTermQuoteQuote4() { + assertEquals("a" + "\\\\" + "\\\"", CQLTermNode.toCQLTerm("a" + "\\\\" + "\\\"")); + } + + @Test + public void TestTCQLTermQuoteBackSlashTrail1() { + assertEquals("a\\\\", CQLTermNode.toCQLTerm("a\\")); + } + + @Test + public void TestTCQLTermQuoteBackSlashTrail2() { + assertEquals("\"a \\\\\"", CQLTermNode.toCQLTerm("a \\")); + } + +} From 82786ac58a2ba3b696092636b96786a8c9482e90 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 10 Feb 2026 19:21:27 +0100 Subject: [PATCH 147/147] doc: update links (#27) --- README.md | 14 +++++++------- src/main/java/org/z3950/zing/cql/CQLGenerator.java | 4 ++-- src/main/java/org/z3950/zing/cql/CQLNode.java | 8 ++++---- src/main/java/org/z3950/zing/cql/CQLParser.java | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c94df9f..df16dca 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,13 @@ CQL-Java is a Free Software project that provides: CQL is "Common Query Language", a query language designed under the umbrella of the ZING initiative (Z39.59-International Next Generation). The official specification is at - http://www.loc.gov/standards/sru/cql/ + https://www.loc.gov/standards/sru/cql/ and there's more (and friendlier) information at - http://zing.z3950.org/cql/index.html + https://zing.z3950.org/cql/index.html XCQL is "XML CQL", a representation of CQL-equivalent queries in XML which is supposed to be easier to parse. The specification is at - http://docs.oasis-open.org/search-ws/searchRetrieve/v1.0/os/schemas/xcql.xsd + https://docs.oasis-open.org/search-ws/searchRetrieve/v1.0/os/schemas/xcql.xsd in the form of an XML Schema. But if you didn't know that, why are you even reading this? :-) @@ -90,7 +90,7 @@ Using the library in your own applications: ## Description -See the automatically generated class documentation in the "target" +See the automatically generated class documentation in the `target` subdirectory. @@ -99,7 +99,7 @@ subdirectory. Original code and documentation by Mike Taylor, Index Data At present maintained by Jakub Skoczen, Index Data -* http://www.indexdata.com/cql-java +* https://www.indexdata.com/cql-java Please email us with bug-reports, wishlist items, patches, deployment stories and, of course, large cash donations. @@ -109,7 +109,7 @@ stories and, of course, large cash donations. The CQL-Java suite is Free Software, which is pretty much legally equivalent -- though not morally equivalent -- to Open Source. See - http://www.gnu.org/philosophy/free-software-for-freedom.html + https://www.gnu.org/philosophy/free-software-for-freedom.html for a detailed if somewhat one-sided discussion of the differences, and particularly of why Free Software is an important idea. @@ -124,7 +124,7 @@ a part of a non-free larger work. ## See also -* http://zing.z3950.org/cql +* https://zing.z3950.org/cql * Adam Dickmeiss's CQL compiler, written in C. * Rob Sanderson's CQL compiler, written in Python. * Jakub Skoczen's CQL-js compiler, written in JavaScript https://github.com/indexdata/cql-js diff --git a/src/main/java/org/z3950/zing/cql/CQLGenerator.java b/src/main/java/org/z3950/zing/cql/CQLGenerator.java index 110406e..b350f57 100644 --- a/src/main/java/org/z3950/zing/cql/CQLGenerator.java +++ b/src/main/java/org/z3950/zing/cql/CQLGenerator.java @@ -19,8 +19,8 @@ * this distribution - there is a generate_x() method * for each grammar element X. * - * @see http://zing.z3950.org/cql/index.html + * @see https://zing.z3950.org/cql/index.html */ public class CQLGenerator { private Properties params; diff --git a/src/main/java/org/z3950/zing/cql/CQLNode.java b/src/main/java/org/z3950/zing/cql/CQLNode.java index f8bb095..2b33b0e 100644 --- a/src/main/java/org/z3950/zing/cql/CQLNode.java +++ b/src/main/java/org/z3950/zing/cql/CQLNode.java @@ -90,9 +90,9 @@ static void renderSortKeys(XCQLBuilder b, int level, * that can be trivially mapped, one-to-one, int Z39.50 Type-1 and * Type-101 queries. A specification for the format can be found * in - * Chapter 7 (Supporting Tools) of the - * YAZ manual. + * YAZ manual. * * @param config * A Properties object containing configuration @@ -130,8 +130,8 @@ abstract public String toPQF(Properties config) * @return * A byte array containing the BER packet. * @see - * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc + * A Layman's Guide to a Subset of ASN.1, BER, and DER * @throws PQFTranslationException * If the parse-tree cannot be translated into * PQF, for example diff --git a/src/main/java/org/z3950/zing/cql/CQLParser.java b/src/main/java/org/z3950/zing/cql/CQLParser.java index eae3455..27456ce 100644 --- a/src/main/java/org/z3950/zing/cql/CQLParser.java +++ b/src/main/java/org/z3950/zing/cql/CQLParser.java @@ -14,8 +14,8 @@ /** * Compiles CQL strings into parse trees of CQLNode subtypes. * - * @see http://zing.z3950.org/cql/index.html + * @see https://zing.z3950.org/cql/index.html */ public class CQLParser { private CQLTokenizer lexer;