use of javax.jcr.query.InvalidQueryException 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 javax.jcr.query.InvalidQueryException in project jackrabbit by apache.
the class XPathQueryBuilder method createDerefQueryNode.
private DerefQueryNode createDerefQueryNode(SimpleNode node, boolean descendant, QueryNode pathNode) throws NamespaceException {
DerefQueryNode derefNode = factory.createDerefQueryNode(pathNode, null, false);
// assign property name
node.jjtGetChild(1).jjtAccept(this, derefNode);
// check property name
if (derefNode.getRefProperty() == null) {
exceptions.add(new InvalidQueryException("Wrong first argument type for jcr:deref"));
}
SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0);
if (literal.getId() == JJTSTRINGLITERAL) {
String value = literal.getValue();
// strip quotes
value = value.substring(1, value.length() - 1);
if (!value.equals("*")) {
Name name = null;
try {
name = decode(resolver.getQName(value));
} catch (NameException e) {
exceptions.add(new InvalidQueryException("Illegal name: " + value));
}
derefNode.setNameTest(name);
}
} else {
exceptions.add(new InvalidQueryException("Second argument for jcr:deref must be a String"));
}
// check if descendant
if (!descendant) {
Node p = node.jjtGetParent();
for (int i = 0; i < p.jjtGetNumChildren(); i++) {
SimpleNode c = (SimpleNode) p.jjtGetChild(i);
if (c == node) {
break;
}
descendant = (c.getId() == JJTSLASHSLASH || c.getId() == JJTROOTDESCENDANTS);
}
}
derefNode.setIncludeDescendants(descendant);
return derefNode;
}
use of javax.jcr.query.InvalidQueryException 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 javax.jcr.query.InvalidQueryException in project jackrabbit by apache.
the class QueryFormat method visit.
public Object visit(RelationQueryNode node, Object data) throws RepositoryException {
StringBuffer sb = (StringBuffer) data;
try {
StringBuffer propPath = new StringBuffer();
// only encode if not position function
PathQueryNode relPath = node.getRelativePath();
if (relPath == null) {
propPath.append(".");
} else if (relPath.getNumOperands() > 0 && XPathQueryBuilder.FN_POSITION_FULL.equals(relPath.getPathSteps()[0].getNameTest())) {
propPath.append(resolver.getJCRName(XPathQueryBuilder.FN_POSITION_FULL));
} else {
LocationStepQueryNode[] steps = relPath.getPathSteps();
String slash = "";
for (int i = 0; i < steps.length; i++) {
propPath.append(slash);
slash = "/";
if (i == steps.length - 1 && node.getOperation() != OPERATION_SIMILAR) {
// last step
propPath.append("@");
}
visit(steps[i], propPath);
}
}
// surround name with property function
node.acceptOperands(this, propPath);
if (node.getOperation() == OPERATION_EQ_VALUE) {
sb.append(propPath).append(" eq ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_EQ_GENERAL) {
sb.append(propPath).append(" = ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_GE_GENERAL) {
sb.append(propPath).append(" >= ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_GE_VALUE) {
sb.append(propPath).append(" ge ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_GT_GENERAL) {
sb.append(propPath).append(" > ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_GT_VALUE) {
sb.append(propPath).append(" gt ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_LE_GENERAL) {
sb.append(propPath).append(" <= ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_LE_VALUE) {
sb.append(propPath).append(" le ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_LIKE) {
sb.append(resolver.getJCRName(XPathQueryBuilder.JCR_LIKE));
sb.append("(").append(propPath).append(", ");
appendValue(node, sb);
sb.append(")");
} else if (node.getOperation() == OPERATION_LT_GENERAL) {
sb.append(propPath).append(" < ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_LT_VALUE) {
sb.append(propPath).append(" lt ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_NE_GENERAL) {
sb.append(propPath).append(" != ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_NE_VALUE) {
sb.append(propPath).append(" ne ");
appendValue(node, sb);
} else if (node.getOperation() == OPERATION_NULL) {
sb.append(resolver.getJCRName(XPathQueryBuilder.FN_NOT));
sb.append("(").append(propPath).append(")");
} else if (node.getOperation() == OPERATION_NOT_NULL) {
sb.append(propPath);
} else if (node.getOperation() == OPERATION_SIMILAR) {
sb.append(resolver.getJCRName(XPathQueryBuilder.REP_SIMILAR));
sb.append("(").append(propPath).append(", ");
appendValue(node, sb);
sb.append(")");
} else if (node.getOperation() == OPERATION_SPELLCHECK) {
sb.append(resolver.getJCRName(XPathQueryBuilder.REP_SPELLCHECK));
sb.append("(");
appendValue(node, sb);
sb.append(")");
} else {
exceptions.add(new InvalidQueryException("Invalid operation: " + node.getOperation()));
}
} catch (NamespaceException e) {
exceptions.add(e);
}
return sb;
}
use of javax.jcr.query.InvalidQueryException in project jackrabbit-oak by apache.
the class QueryTest method nodeType.
@Test
public void nodeType() throws Exception {
Session session = createAdminSession();
String xpath = "/jcr:root//element(*,rep:User)[xyz/@jcr:primaryType]";
assertPlan(getPlan(session, xpath), "[rep:User] as [a] /* nodeType");
session.getNode("/oak:index/nodetype").setProperty("declaringNodeTypes", new String[] { "oak:Unstructured" }, PropertyType.NAME);
session.save();
assertPlan(getPlan(session, xpath), "[rep:User] as [a] /* traverse ");
xpath = "/jcr:root//element(*,oak:Unstructured)[xyz/@jcr:primaryType] option(traversal fail)";
// the plan might still use traversal, so we can't just check the plan;
// but using "option(traversal fail)" we have ensured that there is an index
// (the nodetype index) that can serve this query
getPlan(session, xpath);
// and without the node type index, it is supposed to fail
Node nodeTypeIndex = session.getRootNode().getNode("oak:index").getNode("nodetype");
nodeTypeIndex.setProperty("declaringNodeTypes", new String[] {}, PropertyType.NAME);
session.save();
try {
getPlan(session, xpath);
fail();
} catch (InvalidQueryException e) {
// expected
}
session.logout();
}
Aggregations