fix PQF to RPN conversion

This commit is contained in:
Jörg Prante 2023-03-22 20:01:43 +01:00
parent 155f0adcd4
commit 758ab83b3c
5 changed files with 62 additions and 53 deletions

View file

@ -8,7 +8,9 @@ import java.math.BigDecimal;
public class AttrStr extends Node {
private final Integer left;
private final Integer right;
private final String rightStr;
public AttrStr(BigDecimal left, BigDecimal right) {

View file

@ -6,6 +6,7 @@ package org.xbib.z3950.common.pqf;
public class PQF extends Node {
private final String attrset;
private final Query query;
public PQF(String attrset, Query query) {
@ -27,6 +28,10 @@ public class PQF extends Node {
return attrset;
}
public Query getQuery() {
return query;
}
@Override
public String toString() {
return "[PQF: attrset=" + attrset + " query=" + query + "]";

View file

@ -62,27 +62,35 @@ public class PQFRPNGenerator implements Visitor {
@Override
public void visit(Query query) {
// check for expression
ASN1Any any = !result.isEmpty() && result.peek() instanceof RPNStructure ? result.pop() : null;
if (any != null) {
// RPN structure is ready
result.push(any);
return;
}
// new attribute plus term
Operand operand = new Operand();
operand.attrTerm = new AttributesPlusTerm();
operand.attrTerm.term = new org.xbib.z3950.common.v3.Term();
Term term = query.getTerm();
if (term != null) {
Logger.getLogger("").log(Level.INFO, "query = " + query + " term = " + term + " value = " + term.getValue());
operand.attrTerm.term.c_general = new ASN1OctetString(term.getValue());
} else {
operand.attrTerm.term.c_null = new ASN1Null();
}
Stack<AttributeElement> attrs = new Stack<>();
ASN1Any any = !result.isEmpty() && result.peek() instanceof AttributeElement ? result.pop() : null;
any = !result.isEmpty() && result.peek() instanceof AttributeElement ? result.pop() : null;
while (any != null) {
attrs.push((AttributeElement) any);
any = !result.isEmpty() && result.peek() instanceof AttributeElement ? result.pop() : null;
}
operand.attrTerm.attributes = new AttributeList();
operand.attrTerm.attributes.value = attrs.toArray(new AttributeElement[0]);
any = !result.empty() && result.peek() instanceof ASN1OctetString ? result.pop() : null;
if (any != null) {
if (any instanceof ASN1OctetString) {
operand.attrTerm.term.c_general = (ASN1OctetString) any;
}
}
RPNStructure rpn = new RPNStructure();
rpn.c_op = operand;
Logger.getLogger("").log(Level.INFO, "push rpn = " + rpn);
result.push(rpn);
}
@ -103,19 +111,12 @@ public class PQFRPNGenerator implements Visitor {
}
ASN1Any rpn1 = result.pop();
if (rpn1 instanceof RPNStructure) {
Logger.getLogger("test").log(Level.INFO, "rpn1 = " + rpn1);
rpn.c_rpnRpnOp.s_rpn1 = (RPNStructure) rpn1;
} else {
Logger.getLogger("test").log(Level.INFO, "debug rpn1: " + rpn1);
}
ASN1Any rpn2 = result.pop();
if (rpn2 instanceof RPNStructure) {
Logger.getLogger("test").log(Level.INFO, "rpn2 = " + rpn2);
rpn.c_rpnRpnOp.s_rpn2 = (RPNStructure) rpn2;
} else {
Logger.getLogger("test").log(Level.INFO, "debug rpn2: " + rpn2);
}
Logger.getLogger("test").log(Level.INFO, "visit expr: rpn = " + rpn);
result.push(rpn);
}
@ -130,7 +131,6 @@ public class PQFRPNGenerator implements Visitor {
@Override
public void visit(Term term) {
Logger.getLogger("test").log(Level.INFO, "push term = " + term);
result.push(new ASN1OctetString(term.getValue()));
}

View file

@ -1,54 +1,54 @@
package org.xbib.z3950.common.pqf;
import java.util.LinkedList;
import java.util.logging.Logger;
/**
* PQF abstract syntax tree.
*/
public class Query extends Node {
private static final Logger logger = Logger.getLogger(Query.class.getName());
private String attrschema;
private final LinkedList<AttrStr> attrspec = new LinkedList<>();
private Query querystruct;
private Setname setname;
private Term term;
private Expression expr;
private PQF pqf;
// ATTR CHARSTRING1 attrstr querystruct
public Query(String attrschema, AttrStr attrspec, Query querystruct) {
public Query(String attrschema, AttrStr attrspec, Query query) {
this.attrschema = attrschema;
this.attrspec.add(attrspec);
this.querystruct = querystruct;
this.term = querystruct.getTerm();
this.attrspec.addAll(querystruct.getAttrSpec());
this.attrspec.addAll(query.getAttrSpec());
this.setname = query.setname;
this.term = query.term;
this.expr = query.expr;
}
// ATTR attrspec querystruct
public Query(AttrStr attrspec, Query querystruct) {
public Query(AttrStr attrspec, Query query) {
this.attrspec.add(attrspec);
this.querystruct = querystruct;
this.term = querystruct.getTerm();
this.attrspec.addAll(querystruct.getAttrSpec());
this.attrspec.addAll(query.getAttrSpec());
this.setname = query.setname;
this.term = query.term;
this.expr = query.expr;
}
// TERM TERMTYPE pqf
public Query(PQF pqf) {
this.pqf = pqf;
this.attrschema = pqf.getQuery().attrschema;
this.attrspec.addAll(pqf.getQuery().attrspec);
this.setname = pqf.getQuery().setname;
this.term = pqf.getQuery().term;
this.expr = pqf.getQuery().expr;
}
// simple
public Query(Term term) {
this.term = term;
}
// complex
public Query(Expression expr) {
this.expr = expr;
}
@ -67,15 +67,9 @@ public class Query extends Node {
if (expr != null) {
expr.accept(visitor);
}
if (querystruct != null) {
querystruct.accept(visitor);
}
for (AttrStr attr : attrspec) {
attr.accept(visitor);
}
if (pqf != null) {
pqf.accept(visitor);
}
visitor.visit(this);
}
@ -100,7 +94,6 @@ public class Query extends Node {
if (expr != null) {
return "[Query: expr=" + expr + "]";
}
return "[Query: term=" + term + " attrschema=" + attrschema + " setname=" + setname +
" querystruct=" + querystruct + "]";
return "[Query: term=" + term + " attrschema=" + attrschema + " setname=" + setname + "]";
}
}

View file

@ -1,32 +1,41 @@
package org.xbib.z3950.common.pqf;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.xbib.z3950.common.v3.RPNQuery;
import java.io.StringReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.junit.jupiter.api.Assertions.assertEquals;
class PQFTest {
private static final Logger logger = Logger.getLogger(PQFTest.class.getName());
@Test
@Disabled
void testParser() throws SyntaxException {
String q = "@and @attr 1=4 linux @attr 1=2 sybex";
PQFParser parser = new PQFParser(new StringReader(q));
parser.parse();
PQF pqf = parser.getResult();
logger.log(Level.INFO, "pqf = " + pqf.toString());
assertEquals("[PQF: attrset=null query=[Query: expr=[Expression: op=@and,query1=[Query: term=linux attrschema=null setname=null],query2=[Query: term=sybex attrschema=null setname=null]]]]", pqf.toString());
}
@Test
void testRPN1() {
String q = "@and @attr 1=4 linux @attr 1=2 sybex";
assertEquals("{attributeSetId 1.2.840.10003.3.1, rpn {rpnRpnOp {rpn1 {op {attrTerm {attributes {{attributeType 1, attributeValue {numeric 4}}}, term {general \"linux\"}}}}, rpn2 {op {attrTerm {attributes {{attributeType 1, attributeValue {numeric 2}}}, term {general \"sybex\"}}}}, op {and null}}}}",
createRPNQueryFromPQF(q).toString());
}
@Test
void testRPN() {
String q = "@and @attr 1=4 linux @attr 1=2 sybex";
logger.log(Level.INFO, "rpn = " + createRPNQueryFromPQF(q));
void testRPN2() {
String q = "@and @attr 1=4 @attr 2=3 \"linux\" @attr 1=2 sybex";
assertEquals("{attributeSetId 1.2.840.10003.3.1, rpn {rpnRpnOp {rpn1 {op {attrTerm {attributes {{attributeType 2, attributeValue {numeric 3}}{attributeType 1, attributeValue {numeric 4}}}, term {general \"linux\"}}}}, rpn2 {op {attrTerm {attributes {{attributeType 1, attributeValue {numeric 2}}}, term {general \"sybex\"}}}}, op {and null}}}}",
createRPNQueryFromPQF(q).toString());
}
@Test
void testRPN3() {
String q = "@attr 1=31 2023";
assertEquals("{attributeSetId 1.2.840.10003.3.1, rpn {op {attrTerm {attributes {{attributeType 1, attributeValue {numeric 31}}}, term {general \"2023\"}}}}}",
createRPNQueryFromPQF(q).toString());
}
private RPNQuery createRPNQueryFromPQF(String query) {