use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode in project jackrabbit by apache.
the class XPathQueryBuilder method visit.
//---------------------< XPathVisitor >-------------------------------------
/**
* Implements the generic visit method for this <code>XPathVisitor</code>.
*
* @param node the current node as created by the XPath parser.
* @param data the current <code>QueryNode</code> created by this
* <code>XPathVisitor</code>.
* @return the current <code>QueryNode</code>. Can be different from
* <code>data</code>.
*/
public Object visit(SimpleNode node, Object data) {
QueryNode queryNode = (QueryNode) data;
switch(node.getId()) {
case JJTXPATH2:
queryNode = createPathQueryNode(node);
break;
case JJTROOT:
case JJTROOTDESCENDANTS:
if (queryNode instanceof PathQueryNode) {
((PathQueryNode) queryNode).setAbsolute(true);
} else {
exceptions.add(new InvalidQueryException("Unsupported root level query node: " + queryNode));
}
break;
case JJTSTEPEXPR:
if (isAttributeAxis(node)) {
if (queryNode.getType() == QueryNode.TYPE_RELATION || (queryNode.getType() == QueryNode.TYPE_DEREF && ((DerefQueryNode) queryNode).getRefProperty() == null) || queryNode.getType() == QueryNode.TYPE_ORDER || queryNode.getType() == QueryNode.TYPE_PATH || queryNode.getType() == QueryNode.TYPE_TEXTSEARCH) {
// traverse
node.childrenAccept(this, queryNode);
} else if (queryNode.getType() == QueryNode.TYPE_NOT) {
// is null expression
RelationQueryNode isNull = factory.createRelationQueryNode(queryNode, RelationQueryNode.OPERATION_NULL);
applyRelativePath(isNull);
node.childrenAccept(this, isNull);
NotQueryNode notNode = (NotQueryNode) queryNode;
NAryQueryNode parent = (NAryQueryNode) notNode.getParent();
parent.removeOperand(notNode);
parent.addOperand(isNull);
} else {
// not null expression
RelationQueryNode notNull = factory.createRelationQueryNode(queryNode, RelationQueryNode.OPERATION_NOT_NULL);
applyRelativePath(notNull);
node.childrenAccept(this, notNull);
((NAryQueryNode) queryNode).addOperand(notNull);
}
} else {
if (queryNode.getType() == QueryNode.TYPE_PATH) {
createLocationStep(node, (NAryQueryNode) queryNode);
} else if (queryNode.getType() == QueryNode.TYPE_TEXTSEARCH || queryNode.getType() == QueryNode.TYPE_RELATION) {
node.childrenAccept(this, queryNode);
} else {
// step within a predicate
RelationQueryNode tmp = factory.createRelationQueryNode(null, RelationQueryNode.OPERATION_NOT_NULL);
node.childrenAccept(this, tmp);
if (tmpRelPath == null) {
tmpRelPath = new PathBuilder();
}
PathQueryNode relPath = tmp.getRelativePath();
LocationStepQueryNode[] steps = relPath.getPathSteps();
Name nameTest = steps[steps.length - 1].getNameTest();
if (nameTest == null) {
// see LocationStepQueryNode javadoc on when getNameTest()==null: when it was a star (asterisk)
nameTest = RelationQueryNode.STAR_NAME_TEST;
}
tmpRelPath.addLast(nameTest);
}
}
break;
case JJTNAMETEST:
if (queryNode.getType() == QueryNode.TYPE_LOCATION || queryNode.getType() == QueryNode.TYPE_DEREF || queryNode.getType() == QueryNode.TYPE_RELATION || queryNode.getType() == QueryNode.TYPE_TEXTSEARCH || queryNode.getType() == QueryNode.TYPE_PATH) {
createNodeTest(node, queryNode);
} else if (queryNode.getType() == QueryNode.TYPE_ORDER) {
setOrderSpecPath(node, (OrderQueryNode) queryNode);
} else {
// traverse
node.childrenAccept(this, queryNode);
}
break;
case JJTELEMENTNAMEORWILDCARD:
if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
SimpleNode child = (SimpleNode) node.jjtGetChild(0);
if (child.getId() != JJTANYNAME) {
createNodeTest(child, queryNode);
}
}
break;
case JJTTEXTTEST:
if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
LocationStepQueryNode loc = (LocationStepQueryNode) queryNode;
loc.setNameTest(JCR_XMLTEXT);
}
break;
case JJTTYPENAME:
if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
LocationStepQueryNode loc = (LocationStepQueryNode) queryNode;
String ntName = ((SimpleNode) node.jjtGetChild(0)).getValue();
try {
Name nt = resolver.getQName(ntName);
NodeTypeQueryNode nodeType = factory.createNodeTypeQueryNode(loc, nt);
loc.addPredicate(nodeType);
} catch (NameException e) {
exceptions.add(new InvalidQueryException("Not a valid name: " + ntName));
} catch (NamespaceException e) {
exceptions.add(new InvalidQueryException("Not a valid name: " + ntName));
}
}
break;
case JJTOREXPR:
NAryQueryNode parent = (NAryQueryNode) queryNode;
QueryNode orQueryNode = factory.createOrQueryNode(parent);
parent.addOperand(orQueryNode);
// traverse
node.childrenAccept(this, orQueryNode);
break;
case JJTANDEXPR:
parent = (NAryQueryNode) queryNode;
QueryNode andQueryNode = factory.createAndQueryNode(parent);
parent.addOperand(andQueryNode);
// traverse
node.childrenAccept(this, andQueryNode);
break;
case JJTCOMPARISONEXPR:
createExpression(node, (NAryQueryNode) queryNode);
break;
case JJTSTRINGLITERAL:
case JJTDECIMALLITERAL:
case JJTDOUBLELITERAL:
case JJTINTEGERLITERAL:
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
assignValue(node, (RelationQueryNode) queryNode);
} else if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
if (node.getId() == JJTINTEGERLITERAL) {
int index = Integer.parseInt(node.getValue());
((LocationStepQueryNode) queryNode).setIndex(index);
} else {
exceptions.add(new InvalidQueryException("LocationStep only allows integer literal as position index"));
}
} else {
exceptions.add(new InvalidQueryException("Parse error: data is not a RelationQueryNode"));
}
break;
case JJTUNARYMINUS:
if (queryNode.getType() == QueryNode.TYPE_RELATION) {
((RelationQueryNode) queryNode).setUnaryMinus(true);
} else {
exceptions.add(new InvalidQueryException("Parse error: data is not a RelationQueryNode"));
}
break;
case JJTFUNCTIONCALL:
queryNode = createFunction(node, queryNode);
break;
case JJTORDERBYCLAUSE:
root.setOrderNode(factory.createOrderQueryNode(root));
queryNode = root.getOrderNode();
node.childrenAccept(this, queryNode);
break;
case JJTORDERSPEC:
OrderQueryNode orderQueryNode = (OrderQueryNode) queryNode;
orderQueryNode.newOrderSpec();
node.childrenAccept(this, queryNode);
if (!orderQueryNode.isValid()) {
exceptions.add(new InvalidQueryException("Invalid order specification. (Missing @?)"));
}
break;
case JJTORDERMODIFIER:
if (node.jjtGetNumChildren() > 0 && ((SimpleNode) node.jjtGetChild(0)).getId() == JJTDESCENDING) {
((OrderQueryNode) queryNode).setAscending(false);
}
break;
case JJTPREDICATELIST:
if (queryNode.getType() == QueryNode.TYPE_PATH) {
// switch to last location
QueryNode[] operands = ((PathQueryNode) queryNode).getOperands();
queryNode = operands[operands.length - 1];
}
node.childrenAccept(this, queryNode);
break;
case JJTPREDICATE:
if (queryNode.getType() == QueryNode.TYPE_LOCATION || queryNode.getType() == QueryNode.TYPE_DEREF) {
node.childrenAccept(this, queryNode);
} else {
// predicate not allowed here
exceptions.add(new InvalidQueryException("Unsupported location for predicate"));
}
break;
case JJTDOTDOT:
if (queryNode instanceof LocationStepQueryNode) {
((LocationStepQueryNode) queryNode).setNameTest(PATH_FACTORY.getParentElement().getName());
} else {
((RelationQueryNode) queryNode).addPathElement(PATH_FACTORY.getParentElement());
}
break;
default:
// per default traverse
node.childrenAccept(this, queryNode);
}
return queryNode;
}
use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode in project jackrabbit by apache.
the class XPathQueryBuilder method createExpression.
/**
* Creates a new {@link org.apache.jackrabbit.spi.commons.query.RelationQueryNode}
* with <code>queryNode</code> as its parent node.
*
* @param node a comparison expression node.
* @param queryNode the current <code>QueryNode</code>.
*/
private void createExpression(SimpleNode node, NAryQueryNode queryNode) {
if (node.getId() != JJTCOMPARISONEXPR) {
throw new IllegalArgumentException("node must be of type ComparisonExpr");
}
// get operation type
String opType = node.getValue();
int type = 0;
if (opType.equals(OP_EQ)) {
type = RelationQueryNode.OPERATION_EQ_VALUE;
} else if (opType.equals(OP_SIGN_EQ)) {
type = RelationQueryNode.OPERATION_EQ_GENERAL;
} else if (opType.equals(OP_GT)) {
type = RelationQueryNode.OPERATION_GT_VALUE;
} else if (opType.equals(OP_SIGN_GT)) {
type = RelationQueryNode.OPERATION_GT_GENERAL;
} else if (opType.equals(OP_GE)) {
type = RelationQueryNode.OPERATION_GE_VALUE;
} else if (opType.equals(OP_SIGN_GE)) {
type = RelationQueryNode.OPERATION_GE_GENERAL;
} else if (opType.equals(OP_LE)) {
type = RelationQueryNode.OPERATION_LE_VALUE;
} else if (opType.equals(OP_SIGN_LE)) {
type = RelationQueryNode.OPERATION_LE_GENERAL;
} else if (opType.equals(OP_LT)) {
type = RelationQueryNode.OPERATION_LT_VALUE;
} else if (opType.equals(OP_SIGN_LT)) {
type = RelationQueryNode.OPERATION_LT_GENERAL;
} else if (opType.equals(OP_NE)) {
type = RelationQueryNode.OPERATION_NE_VALUE;
} else if (opType.equals(OP_SIGN_NE)) {
type = RelationQueryNode.OPERATION_NE_GENERAL;
} else {
exceptions.add(new InvalidQueryException("Unsupported ComparisonExpr type:" + node.getValue()));
}
final RelationQueryNode rqn = factory.createRelationQueryNode(queryNode, type);
// traverse
node.childrenAccept(this, rqn);
// check if string transformation is valid
try {
rqn.acceptOperands(new DefaultQueryNodeVisitor() {
public Object visit(PropertyFunctionQueryNode node, Object data) {
String functionName = node.getFunctionName();
if ((functionName.equals(PropertyFunctionQueryNode.LOWER_CASE) || functionName.equals(PropertyFunctionQueryNode.UPPER_CASE)) && rqn.getValueType() != QueryConstants.TYPE_STRING) {
String msg = "Upper and lower case function are only supported with String literals";
exceptions.add(new InvalidQueryException(msg));
}
return data;
}
}, null);
} catch (RepositoryException e) {
exceptions.add(e);
}
queryNode.addOperand(rqn);
}
use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode in project jackrabbit by apache.
the class JCRSQLQueryBuilder method visit.
public Object visit(ASTLowerFunction node, Object data) {
RelationQueryNode parent = (RelationQueryNode) data;
if (parent.getValueType() != QueryConstants.TYPE_STRING) {
String msg = "LOWER() function is only supported for String literal";
throw new IllegalArgumentException(msg);
}
parent.addOperand(factory.createPropertyFunctionQueryNode(parent, PropertyFunctionQueryNode.LOWER_CASE));
return parent;
}
use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode in project jackrabbit by apache.
the class LuceneQueryBuilder method visit.
public Object visit(LocationStepQueryNode node, Object data) throws RepositoryException {
Query context = (Query) data;
BooleanQuery andQuery = new BooleanQuery();
if (context == null) {
exceptions.add(new IllegalArgumentException("Unsupported query"));
}
// predicate on step?
Object[] predicates = node.acceptOperands(this, data);
for (Object predicate : predicates) {
andQuery.add((Query) predicate, Occur.MUST);
}
// check for position predicate
QueryNode[] pred = node.getPredicates();
for (QueryNode aPred : pred) {
if (aPred.getType() == QueryNode.TYPE_RELATION) {
RelationQueryNode pos = (RelationQueryNode) aPred;
if (pos.getValueType() == QueryConstants.TYPE_POSITION) {
node.setIndex(pos.getPositionValue());
}
}
}
NameQuery nameTest = null;
if (node.getNameTest() != null) {
if (node.getNameTest().equals(PARENT_ELEMENT_NAME)) {
andQuery.add(new ParentAxisQuery(context, null, indexFormatVersion, nsMappings), Occur.MUST);
return andQuery;
}
nameTest = new NameQuery(node.getNameTest(), indexFormatVersion, nsMappings);
}
if (node.getIncludeDescendants()) {
if (nameTest != null) {
andQuery.add(new DescendantSelfAxisQuery(context, nameTest, false), Occur.MUST);
} else {
// descendant-or-self with nametest=*
if (predicates.length > 0) {
// if we have a predicate attached, the condition acts as
// the sub query.
// only use descendant axis if path is not //*
// otherwise the query for the predicate can be used itself
PathQueryNode pathNode = (PathQueryNode) node.getParent();
if (pathNode.getPathSteps()[0] != node) {
Query subQuery = new DescendantSelfAxisQuery(context, andQuery, false);
andQuery = new BooleanQuery();
andQuery.add(subQuery, Occur.MUST);
}
} else {
// todo this will traverse the whole index, optimize!
// only use descendant axis if path is not //*
PathQueryNode pathNode = (PathQueryNode) node.getParent();
if (pathNode.getPathSteps()[0] != node) {
if (node.getIndex() == LocationStepQueryNode.NONE) {
context = new DescendantSelfAxisQuery(context, false);
andQuery.add(context, Occur.MUST);
} else {
context = new DescendantSelfAxisQuery(context, true);
andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex(), indexFormatVersion, nsMappings), Occur.MUST);
}
} else {
andQuery.add(new MatchAllDocsQuery(), Occur.MUST);
}
}
}
} else {
// name test
if (nameTest != null) {
andQuery.add(new ChildAxisQuery(sharedItemMgr, context, nameTest.getName(), node.getIndex(), indexFormatVersion, nsMappings), Occur.MUST);
} else {
// select child nodes
andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex(), indexFormatVersion, nsMappings), Occur.MUST);
}
}
return andQuery;
}
use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode 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;
}
Aggregations