fix PQF to RPN conversion
This commit is contained in:
parent
155f0adcd4
commit
758ab83b3c
5 changed files with 62 additions and 53 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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 + "]";
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 + "]";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue