use of org.apache.jackrabbit.spi.commons.query.PathQueryNode in project jackrabbit by apache.
the class XPathQueryBuilder method createLocationStep.
/**
* Creates a <code>LocationStepQueryNode</code> at the current position
* in parent.
*
* @param node the current node in the xpath syntax tree.
* @param parent the parent <code>PathQueryNode</code>.
* @return the created <code>LocationStepQueryNode</code>.
*/
private LocationStepQueryNode createLocationStep(SimpleNode node, NAryQueryNode parent) {
LocationStepQueryNode queryNode = null;
boolean descendant = false;
Node p = node.jjtGetParent();
for (int i = 0; i < p.jjtGetNumChildren(); i++) {
SimpleNode c = (SimpleNode) p.jjtGetChild(i);
if (c == node) {
queryNode = factory.createLocationStepQueryNode(parent);
queryNode.setNameTest(null);
queryNode.setIncludeDescendants(descendant);
parent.addOperand(queryNode);
break;
}
descendant = (c.getId() == JJTSLASHSLASH || c.getId() == JJTROOTDESCENDANTS);
}
node.childrenAccept(this, queryNode);
return queryNode;
}
use of org.apache.jackrabbit.spi.commons.query.PathQueryNode in project jackrabbit by apache.
the class XPathQueryBuilder method createFunction.
/**
* Creates a function based on <code>node</code>.
*
* @param node the function node from the xpath tree.
* @param queryNode the current query node.
* @return the function node
*/
private QueryNode createFunction(SimpleNode node, QueryNode queryNode) {
// find out function name
String tmp = ((SimpleNode) node.jjtGetChild(0)).getValue();
String fName = tmp.substring(0, tmp.length() - 1);
try {
Name funName = resolver.getQName(fName);
if (FN_NOT.equals(funName) || FN_NOT_10.equals(funName)) {
if (queryNode instanceof NAryQueryNode) {
QueryNode not = factory.createNotQueryNode(queryNode);
((NAryQueryNode) queryNode).addOperand(not);
// @todo is this needed?
queryNode = not;
// traverse
if (node.jjtGetNumChildren() == 2) {
node.jjtGetChild(1).jjtAccept(this, queryNode);
} else {
exceptions.add(new InvalidQueryException("fn:not only supports one expression argument"));
}
} else {
exceptions.add(new InvalidQueryException("Unsupported location for function fn:not"));
}
} else if (XS_DATETIME.equals(funName)) {
// check arguments
if (node.jjtGetNumChildren() == 2) {
if (queryNode instanceof RelationQueryNode) {
RelationQueryNode rel = (RelationQueryNode) queryNode;
SimpleNode literal = (SimpleNode) node.jjtGetChild(1).jjtGetChild(0);
if (literal.getId() == JJTSTRINGLITERAL) {
String value = literal.getValue();
// strip quotes
value = value.substring(1, value.length() - 1);
Calendar c = ISO8601.parse(value);
if (c == null) {
exceptions.add(new InvalidQueryException("Unable to parse string literal for xs:dateTime: " + value));
} else {
rel.setDateValue(c.getTime());
}
} else {
exceptions.add(new InvalidQueryException("Wrong argument type for xs:dateTime"));
}
} else {
exceptions.add(new InvalidQueryException("Unsupported location for function xs:dateTime"));
}
} else {
// wrong number of arguments
exceptions.add(new InvalidQueryException("Wrong number of arguments for xs:dateTime"));
}
} else if (JCR_CONTAINS.equals(funName)) {
// check number of arguments
if (node.jjtGetNumChildren() == 3) {
if (queryNode instanceof NAryQueryNode) {
SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0);
if (literal.getId() == JJTSTRINGLITERAL) {
TextsearchQueryNode contains = factory.createTextsearchQueryNode(queryNode, unescapeQuotes(literal.getValue()));
// assign property name
SimpleNode path = (SimpleNode) node.jjtGetChild(1);
path.jjtAccept(this, contains);
((NAryQueryNode) queryNode).addOperand(contains);
} else {
exceptions.add(new InvalidQueryException("Wrong argument type for jcr:contains"));
}
}
} else {
// wrong number of arguments
exceptions.add(new InvalidQueryException("Wrong number of arguments for jcr:contains"));
}
} else if (JCR_LIKE.equals(funName)) {
// check number of arguments
if (node.jjtGetNumChildren() == 3) {
if (queryNode instanceof NAryQueryNode) {
RelationQueryNode like = factory.createRelationQueryNode(queryNode, RelationQueryNode.OPERATION_LIKE);
((NAryQueryNode) queryNode).addOperand(like);
// assign property name
node.jjtGetChild(1).jjtAccept(this, like);
// check property name
if (like.getRelativePath() == null) {
exceptions.add(new InvalidQueryException("Wrong first argument type for jcr:like"));
}
SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0);
if (literal.getId() == JJTSTRINGLITERAL) {
like.setStringValue(unescapeQuotes(literal.getValue()));
} else {
exceptions.add(new InvalidQueryException("Wrong second argument type for jcr:like"));
}
} else {
exceptions.add(new InvalidQueryException("Unsupported location for function jcr:like"));
}
} else {
// wrong number of arguments
exceptions.add(new InvalidQueryException("Wrong number of arguments for jcr:like"));
}
} else if (FN_TRUE.equals(funName)) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode rel = (RelationQueryNode) queryNode;
rel.setStringValue("true");
} else {
exceptions.add(new InvalidQueryException("Unsupported location for true()"));
}
} else if (FN_FALSE.equals(funName)) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode rel = (RelationQueryNode) queryNode;
rel.setStringValue("false");
} else {
exceptions.add(new InvalidQueryException("Unsupported location for false()"));
}
} else if (FN_POSITION.equals(funName)) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode rel = (RelationQueryNode) queryNode;
if (rel.getOperation() == RelationQueryNode.OPERATION_EQ_GENERAL) {
// set dummy value to set type of relation query node
// will be overwritten when the tree is further parsed.
rel.setPositionValue(1);
rel.addPathElement(PATH_FACTORY.createElement(FN_POSITION_FULL));
} else {
exceptions.add(new InvalidQueryException("Unsupported expression with position(). Only = is supported."));
}
} else {
exceptions.add(new InvalidQueryException("Unsupported location for position()"));
}
} else if (FN_FIRST.equals(funName)) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
((RelationQueryNode) queryNode).setPositionValue(1);
} else if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
((LocationStepQueryNode) queryNode).setIndex(1);
} else {
exceptions.add(new InvalidQueryException("Unsupported location for first()"));
}
} else if (FN_LAST.equals(funName)) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
((RelationQueryNode) queryNode).setPositionValue(LocationStepQueryNode.LAST);
} else if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
((LocationStepQueryNode) queryNode).setIndex(LocationStepQueryNode.LAST);
} else {
exceptions.add(new InvalidQueryException("Unsupported location for last()"));
}
} else if (JCR_DEREF.equals(funName)) {
// check number of arguments
if (node.jjtGetNumChildren() == 3) {
boolean descendant = false;
if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
LocationStepQueryNode loc = (LocationStepQueryNode) queryNode;
// remember if descendant axis
descendant = loc.getIncludeDescendants();
queryNode = loc.getParent();
((NAryQueryNode) queryNode).removeOperand(loc);
}
if (queryNode.getType() == QueryNode.TYPE_PATH) {
PathQueryNode pathNode = (PathQueryNode) queryNode;
pathNode.addPathStep(createDerefQueryNode(node, descendant, pathNode));
} else if (queryNode.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode relNode = (RelationQueryNode) queryNode;
DerefQueryNode deref = createDerefQueryNode(node, descendant, relNode.getRelativePath());
relNode.getRelativePath().addPathStep(deref);
} else {
exceptions.add(new InvalidQueryException("Unsupported location for jcr:deref()"));
}
}
} else if (JCR_SCORE.equals(funName)) {
if (queryNode.getType() == QueryNode.TYPE_ORDER) {
setOrderSpecPath(node, (OrderQueryNode) queryNode);
} else {
exceptions.add(new InvalidQueryException("Unsupported location for jcr:score()"));
}
} else if (FN_LOWER_CASE.equals(funName)) {
if (node.jjtGetNumChildren() == 2) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode relNode = (RelationQueryNode) queryNode;
relNode.addOperand(factory.createPropertyFunctionQueryNode(relNode, PropertyFunctionQueryNode.LOWER_CASE));
// get property name
node.jjtGetChild(1).jjtAccept(this, relNode);
} else if (queryNode.getType() == QueryNode.TYPE_ORDER) {
((OrderQueryNode) queryNode).setFunction(FN_LOWER_CASE.getLocalName());
node.childrenAccept(this, queryNode);
} else {
exceptions.add(new InvalidQueryException("Unsupported location for fn:lower-case()"));
}
} else {
exceptions.add(new InvalidQueryException("Wrong number of argument for fn:lower-case()"));
}
} else if (FN_UPPER_CASE.equals(funName)) {
if (node.jjtGetNumChildren() == 2) {
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode relNode = (RelationQueryNode) queryNode;
relNode.addOperand(factory.createPropertyFunctionQueryNode(relNode, PropertyFunctionQueryNode.UPPER_CASE));
// get property name
node.jjtGetChild(1).jjtAccept(this, relNode);
} else if (queryNode.getType() == QueryNode.TYPE_ORDER) {
((OrderQueryNode) queryNode).setFunction(FN_UPPER_CASE.getLocalName());
node.childrenAccept(this, queryNode);
} else {
exceptions.add(new InvalidQueryException("Unsupported location for fn:upper-case()"));
}
} else {
exceptions.add(new InvalidQueryException("Wrong number of argument for fn:upper-case()"));
}
} else if (REP_NORMALIZE.equals(funName)) {
if (node.jjtGetNumChildren() == 2) {
if (queryNode.getType() == QueryNode.TYPE_ORDER) {
((OrderQueryNode) queryNode).setFunction(REP_NORMALIZE.getLocalName());
node.childrenAccept(this, queryNode);
} else {
exceptions.add(new InvalidQueryException("Unsupported location for rep:normalize()"));
}
} else {
exceptions.add(new InvalidQueryException("Wrong number of argument for rep:normalize()"));
}
} else if (REP_SIMILAR.equals(funName)) {
if (node.jjtGetNumChildren() == 3) {
if (queryNode instanceof NAryQueryNode) {
NAryQueryNode parent = (NAryQueryNode) queryNode;
RelationQueryNode rel = factory.createRelationQueryNode(parent, RelationQueryNode.OPERATION_SIMILAR);
parent.addOperand(rel);
// assign path
node.jjtGetChild(1).jjtAccept(this, rel);
// get path string
node.jjtGetChild(2).jjtAccept(this, rel);
// check if string is set
if (rel.getStringValue() == null) {
exceptions.add(new InvalidQueryException("Second argument for rep:similar() must be of type string"));
}
} else {
exceptions.add(new InvalidQueryException("Unsupported location for rep:similar()"));
}
} else {
exceptions.add(new InvalidQueryException("Wrong number of arguments for rep:similar()"));
}
} else if (REP_SPELLCHECK.equals(funName) && queryNode.getType() != QueryNode.TYPE_PATH) {
if (node.jjtGetNumChildren() == 2) {
if (queryNode instanceof NAryQueryNode) {
NAryQueryNode parent = (NAryQueryNode) queryNode;
RelationQueryNode rel = factory.createRelationQueryNode(parent, RelationQueryNode.OPERATION_SPELLCHECK);
parent.addOperand(rel);
// get string to check
node.jjtGetChild(1).jjtAccept(this, rel);
// check if string is set
if (rel.getStringValue() == null) {
exceptions.add(new InvalidQueryException("Argument for rep:spellcheck() must be of type string"));
}
// set a dummy property name
rel.addPathElement(PATH_FACTORY.createElement(NameConstants.JCR_PRIMARYTYPE));
} else {
exceptions.add(new InvalidQueryException("Unsupported location for rep:spellcheck()"));
}
} else {
exceptions.add(new InvalidQueryException("Wrong number of arguments for rep:spellcheck()"));
}
} else if (queryNode.getType() == QueryNode.TYPE_RELATION) {
// use function name as name of a pseudo property in a relation
try {
Name name = resolver.getQName(fName + "()");
Path.Element element = PATH_FACTORY.createElement(name);
RelationQueryNode relNode = (RelationQueryNode) queryNode;
relNode.addPathElement(element);
} catch (NameException e) {
exceptions.add(e);
}
} else if (queryNode.getType() == QueryNode.TYPE_PATH) {
// use function name as name of a pseudo property in select clause
try {
Name name = resolver.getQName(fName + "()");
root.addSelectProperty(name);
} catch (NameException e) {
exceptions.add(e);
}
} else {
exceptions.add(new InvalidQueryException("Unsupported function: " + fName));
}
} catch (NamespaceException e) {
exceptions.add(e);
} catch (IllegalNameException e) {
exceptions.add(e);
}
return queryNode;
}
use of org.apache.jackrabbit.spi.commons.query.PathQueryNode in project jackrabbit by apache.
the class JCRSQLQueryBuilder method visit.
public Object visit(ASTQuery node, Object data) {
root = factory.createQueryRootNode();
root.setLocationNode(factory.createPathQueryNode(root));
// pass to select, from, where, ...
node.childrenAccept(this, root);
// use //* if no path has been set
PathQueryNode pathNode = root.getLocationNode();
pathNode.setAbsolute(true);
if (pathConstraints.size() == 0) {
LocationStepQueryNode step = factory.createLocationStepQueryNode(pathNode);
step.setNameTest(null);
step.setIncludeDescendants(true);
pathNode.addPathStep(step);
} else {
try {
while (pathConstraints.size() > 1) {
// merge path nodes
MergingPathQueryNode path = null;
for (Iterator it = pathConstraints.iterator(); it.hasNext(); ) {
path = (MergingPathQueryNode) it.next();
if (path.needsMerge()) {
break;
} else {
path = null;
}
}
if (path == null) {
throw new IllegalArgumentException("Invalid combination of jcr:path clauses");
} else {
pathConstraints.remove(path);
MergingPathQueryNode[] paths = (MergingPathQueryNode[]) pathConstraints.toArray(new MergingPathQueryNode[pathConstraints.size()]);
paths = path.doMerge(paths);
pathConstraints.clear();
pathConstraints.addAll(Arrays.asList(paths));
}
}
} catch (NoSuchElementException e) {
throw new IllegalArgumentException("Invalid combination of jcr:path clauses");
}
MergingPathQueryNode path = (MergingPathQueryNode) pathConstraints.get(0);
LocationStepQueryNode[] steps = path.getPathSteps();
for (int i = 0; i < steps.length; i++) {
LocationStepQueryNode step = factory.createLocationStepQueryNode(pathNode);
step.setNameTest(steps[i].getNameTest());
step.setIncludeDescendants(steps[i].getIncludeDescendants());
step.setIndex(steps[i].getIndex());
pathNode.addPathStep(step);
}
}
if (constraintNode.getNumOperands() == 1) {
// attach operand to last path step
LocationStepQueryNode[] steps = pathNode.getPathSteps();
steps[steps.length - 1].addPredicate(constraintNode.getOperands()[0]);
} else if (constraintNode.getNumOperands() > 1) {
// attach constraint to last path step
LocationStepQueryNode[] steps = pathNode.getPathSteps();
steps[steps.length - 1].addPredicate(constraintNode);
}
if (nodeTypeName != null) {
// add node type constraint
LocationStepQueryNode[] steps = pathNode.getPathSteps();
NodeTypeQueryNode nodeType = factory.createNodeTypeQueryNode(steps[steps.length - 1], nodeTypeName);
steps[steps.length - 1].addPredicate(nodeType);
}
return root;
}
Aggregations