add feature of word list support for CQL->RPN conversion

This commit is contained in:
Jörg Prante 2023-04-14 16:32:00 +02:00
parent 3226ce424b
commit a6e50e7ba5
6 changed files with 43 additions and 74 deletions

View file

@ -1,5 +1,5 @@
group = org.xbib
name = z3950
version = 5.1.5
version = 5.1.6
org.gradle.warning.mode = ALL

View file

@ -72,7 +72,7 @@ public class JDKZClient implements Client, Closeable {
lock.lock();
SearchOperation searchOperation = new SearchOperation(berReader, berWriter,
builder.resultSetName, builder.databases, builder.host);
boolean success = searchOperation.executeCQL(query);
boolean success = searchOperation.executeCQL(query, builder.wordListSupported);
if (!success) {
logger.log(Level.WARNING, MessageFormat.format("search was not a success [{0}]", query));
} else {
@ -410,6 +410,8 @@ public class JDKZClient implements Client, Closeable {
private InitListener initListener;
private boolean wordListSupported;
private Builder() {
this.timeout = 5000;
this.preferredRecordSyntax = "1.2.840.10003.5.10"; // marc21
@ -421,6 +423,7 @@ public class JDKZClient implements Client, Closeable {
this.preferredMessageSize = 10 * 1024 * 1024;
this.implementationName = "Java Z Client";
this.implementationVersion = "1.00";
this.wordListSupported = true;
}
public Builder setHost(String host) {
@ -506,6 +509,11 @@ public class JDKZClient implements Client, Closeable {
return this;
}
public Builder wordListSupported(boolean wordListSupported) {
this.wordListSupported = wordListSupported;
return this;
}
public JDKZClient build() {
return new JDKZClient(this);
}

View file

@ -1,10 +1,7 @@
package org.xbib.z3950.client.jdk.test;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.jupiter.api.Test;
@ -16,15 +13,14 @@ class SWBClientTest {
@Test
void testCQL() {
String serviceName = "SWB";
String query = "bib.identifierISSN = 00280836";
//String query = "bib.identifierISSN = 00280836";
String query = "bib.any all test";
int from = 1;
int size = 10;
try (JDKZClient client = newZClient(serviceName)) {
logger.log(Level.INFO, "executing CQL " + serviceName);
try (JDKZClient client = newZClient()) {
int count = client.searchCQL(query, from, size, null,
(status, total, returned, elapsedMillis) ->
logger.log(Level.INFO, serviceName + " total results = " + total),
logger.log(Level.INFO, "total results = " + total),
record -> logger.log(Level.INFO, "record = " + record),
() -> logger.log(Level.INFO, "timeout"));
logger.log(Level.INFO, "returned records = " + count);
@ -35,15 +31,13 @@ class SWBClientTest {
@Test
void testPQF() {
String serviceName = "SWB";
String query = "@attr 1=8 \"00280836\"";
int from = 1;
int size = 10;
try (JDKZClient client = newZClient(serviceName)) {
logger.log(Level.INFO, "executing PQF " + serviceName);
try (JDKZClient client = newZClient()) {
int count = client.searchPQF(query, from, size, null,
(status, total, returned, elapsedMillis) ->
logger.log(Level.INFO, serviceName + " status = " + status + " total results = " + total),
logger.log(Level.INFO, "status = " + status + " total results = " + total),
record -> logger.log(Level.INFO, "record = " + record.toString(Charset.forName(client.getEncoding()))),
() -> logger.log(Level.WARNING, "timeout"));
logger.log(Level.INFO, "returned records = " + count);
@ -52,53 +46,19 @@ class SWBClientTest {
}
}
private JDKZClient newZClient(String name) throws IOException {
return newZClient(getProperties(name));
}
private Properties getProperties(String name) throws IOException {
Properties properties = new Properties();
try (InputStream inputStream = getClass().getResourceAsStream(name + ".properties")) {
properties.load(inputStream);
}
return properties;
}
private static JDKZClient newZClient(Properties properties) {
JDKZClient.Builder builder = JDKZClient.builder();
if (properties.containsKey("host")) {
builder.setHost(properties.getProperty("host"));
}
if (properties.containsKey("port")) {
builder.setPort(Integer.parseInt(properties.getProperty("port")));
}
if (properties.containsKey("user")) {
builder.setUser(properties.getProperty("user"));
}
if (properties.containsKey("pass")) {
builder.setPass(properties.getProperty("pass"));
}
if (properties.containsKey("database")) {
builder.setDatabases(Collections.singletonList(properties.getProperty("database")));
}
if (properties.containsKey("elementsetname")) {
builder.setElementSetName(properties.getProperty("elementsetname"));
}
if (properties.containsKey("preferredrecordsyntax")) {
builder.setPreferredRecordSyntax(properties.getProperty("preferredrecordsyntax"));
}
if (properties.containsKey("resultsetname")) {
builder.setResultSetName(properties.getProperty("resultsetname"));
}
if (properties.containsKey("encoding")) {
builder.setEncoding(properties.getProperty("encoding"));
}
if (properties.containsKey("format")) {
builder.setFormat(properties.getProperty("format"));
}
if (properties.containsKey("type")) {
builder.setType(properties.getProperty("type"));
}
private JDKZClient newZClient() {
JDKZClient.Builder builder = JDKZClient.builder()
.setHost("z3950.bsz-bw.de")
.setPort(20210)
.setTimeout(10000L)
.setDatabases(Collections.singletonList("swb_fl"))
.setElementSetName("xf")
.setPreferredRecordSyntax("marc21")
.setResultSetName("default")
.setEncoding("UTF-8")
.setFormat("Marc21")
.setType("Bibliographic")
.wordListSupported(false);
return builder.build();
}
}

View file

@ -57,11 +57,13 @@ public final class CQLRPNGenerator implements Visitor {
private RPNQuery rpnQuery;
private final boolean wordListSupported;
public CQLRPNGenerator() {
this(null);
this(null, true);
}
public CQLRPNGenerator(Collection<AttributeElement> attributeElements) {
public CQLRPNGenerator(Collection<AttributeElement> attributeElements, boolean wordListSupported) {
this.attributeElements = new Stack<>();
if (attributeElements != null) {
this.attributeElements.addAll(attributeElements);
@ -74,6 +76,7 @@ public final class CQLRPNGenerator implements Visitor {
addContext("bib", ResourceBundle.getBundle("org.xbib.z3950.common.cql.bib-1"));
addContext("dc", ResourceBundle.getBundle("org.xbib.z3950.common.cql.dc"));
addContext("gbv", ResourceBundle.getBundle("org.xbib.z3950.common.cql.gbv"));
this.wordListSupported = wordListSupported;
}
public void addContext(String context, ResourceBundle bundle) {
@ -233,13 +236,11 @@ public final class CQLRPNGenerator implements Visitor {
push(attributeElements, createAttributeElement(2, 5));
case NOT_EQUALS ->
push(attributeElements, createAttributeElement(2, 6));
case ALL -> { // 4=6 word list
case ALL, ANY -> { // 4=6 word list
push(attributeElements, createAttributeElement(2, 3));
if (wordListSupported) {
replace(attributeElements, createAttributeElement(4, 6));
}
case ANY -> { // 4=104
push(attributeElements, createAttributeElement(2, 3));
replace(attributeElements, createAttributeElement(4, 104));
}
default -> {
}

View file

@ -58,8 +58,8 @@ public class SearchOperation extends AbstractOperation<SearchResponse, SearchReq
return execute(createRPNQueryFromPQF(pqf, charset));
}
public boolean executeCQL(String cql) throws IOException {
return execute(createRPNQueryFromCQL(cql));
public boolean executeCQL(String cql, boolean wordListSupported) throws IOException {
return execute(createRPNQueryFromCQL(cql, wordListSupported));
}
public boolean execute(RPNQuery rpn) throws IOException {
@ -118,8 +118,8 @@ public class SearchOperation extends AbstractOperation<SearchResponse, SearchReq
return status;
}
private RPNQuery createRPNQueryFromCQL(String query) {
CQLRPNGenerator generator = new CQLRPNGenerator();
private RPNQuery createRPNQueryFromCQL(String query, boolean wordListSupported) {
CQLRPNGenerator generator = new CQLRPNGenerator(null, wordListSupported);
CQLParser parser = new CQLParser(query);
parser.parse();
parser.getCQLQuery().accept(generator);

View file

@ -41,7 +41,7 @@ class CQL2RPNTest {
String cql = "dc.title = \"a phrase\"";
CQLParser parser = new CQLParser(cql);
parser.parse();
CQLRPNGenerator generator = new CQLRPNGenerator(Collections.singleton(ae));
CQLRPNGenerator generator = new CQLRPNGenerator(Collections.singleton(ae), true);
parser.getCQLQuery().accept(generator);
String q = generator.getQueryResult().toString();
assertEquals("{attributeSetId 1.2.840.10003.3.1, rpn {op {attrTerm {attributes {{attributeType 7, attributeValue {numeric 4}}{attributeType 3, attributeValue {numeric 3}}{attributeType 4, attributeValue {numeric 1}}{attributeType 5, attributeValue {numeric 100}}{attributeType 6, attributeValue {numeric 1}}{attributeType 1, attributeValue {numeric 4}}{attributeType 2, attributeValue {numeric 3}}}, term {general \"a phrase\"}}}}}", q);