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 { public class AttrStr extends Node {
private final Integer left; private final Integer left;
private final Integer right; private final Integer right;
private final String rightStr; private final String rightStr;
public AttrStr(BigDecimal left, BigDecimal right) { public AttrStr(BigDecimal left, BigDecimal right) {

View file

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

View file

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

View file

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

View file

@ -1,32 +1,41 @@
package org.xbib.z3950.common.pqf; package org.xbib.z3950.common.pqf;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.z3950.common.v3.RPNQuery; import org.xbib.z3950.common.v3.RPNQuery;
import java.io.StringReader; import java.io.StringReader;
import java.util.logging.Level; import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.logging.Logger;
class PQFTest { class PQFTest {
private static final Logger logger = Logger.getLogger(PQFTest.class.getName());
@Test @Test
@Disabled
void testParser() throws SyntaxException { void testParser() throws SyntaxException {
String q = "@and @attr 1=4 linux @attr 1=2 sybex"; String q = "@and @attr 1=4 linux @attr 1=2 sybex";
PQFParser parser = new PQFParser(new StringReader(q)); PQFParser parser = new PQFParser(new StringReader(q));
parser.parse(); parser.parse();
PQF pqf = parser.getResult(); 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 @Test
void testRPN() { void testRPN2() {
String q = "@and @attr 1=4 linux @attr 1=2 sybex"; String q = "@and @attr 1=4 @attr 2=3 \"linux\" @attr 1=2 sybex";
logger.log(Level.INFO, "rpn = " + createRPNQueryFromPQF(q)); 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) { private RPNQuery createRPNQueryFromPQF(String query) {