use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode in project jackrabbit by apache.
the class XPathQueryBuilder method createNodeTest.
/**
* Assigns a Name to one of the following QueryNodes:
* {@link RelationQueryNode}, {@link DerefQueryNode}, {@link RelationQueryNode},
* {@link PathQueryNode}, {@link OrderQueryNode}, {@link TextsearchQueryNode}.
*
* @param node the current node in the xpath syntax tree.
* @param queryNode the query node.
*/
private void createNodeTest(SimpleNode node, QueryNode queryNode) {
if (node.jjtGetNumChildren() > 0) {
SimpleNode child = (SimpleNode) node.jjtGetChild(0);
if (child.getId() == JJTQNAME || child.getId() == JJTQNAMEFORITEMTYPE) {
try {
Name name = decode(resolver.getQName(child.getValue()));
if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
if (name.equals(JCR_ROOT)) {
name = LocationStepQueryNode.EMPTY_NAME;
}
((LocationStepQueryNode) queryNode).setNameTest(name);
} else if (queryNode.getType() == QueryNode.TYPE_DEREF) {
((DerefQueryNode) queryNode).setRefProperty(name);
} else if (queryNode.getType() == QueryNode.TYPE_RELATION) {
Path.Element element = PATH_FACTORY.createElement(name);
((RelationQueryNode) queryNode).addPathElement(element);
} else if (queryNode.getType() == QueryNode.TYPE_PATH) {
root.addSelectProperty(name);
} else if (queryNode.getType() == QueryNode.TYPE_ORDER) {
root.getOrderNode().addOrderSpec(name, true);
} else if (queryNode.getType() == QueryNode.TYPE_TEXTSEARCH) {
TextsearchQueryNode ts = (TextsearchQueryNode) queryNode;
ts.addPathElement(PATH_FACTORY.createElement(name));
if (isAttributeNameTest(node)) {
ts.setReferencesProperty(true);
}
}
} catch (RepositoryException e) {
exceptions.add(new InvalidQueryException("Illegal name: " + child.getValue()));
}
} else if (child.getId() == JJTSTAR) {
if (queryNode.getType() == QueryNode.TYPE_LOCATION) {
((LocationStepQueryNode) queryNode).setNameTest(null);
} else if (queryNode.getType() == QueryNode.TYPE_RELATION) {
((RelationQueryNode) queryNode).addPathElement(PATH_FACTORY.createElement(RelationQueryNode.STAR_NAME_TEST));
} else if (queryNode.getType() == QueryNode.TYPE_TEXTSEARCH) {
((TextsearchQueryNode) queryNode).addPathElement(PATH_FACTORY.createElement(RelationQueryNode.STAR_NAME_TEST));
}
} else {
exceptions.add(new InvalidQueryException("Unsupported location for name test: " + child));
}
}
}
use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode in project jackrabbit by apache.
the class JCRSQLQueryBuilder method createRelationQueryNode.
//------------------------< internal >--------------------------------------
/**
* Creates a new {@link org.apache.jackrabbit.spi.commons.query.RelationQueryNode}.
*
* @param parent the parent node for the created <code>RelationQueryNode</code>.
* @param propertyName the property name for the relation.
* @param operationType the operation type.
* @param literal the literal value for the relation or
* <code>null</code> if the relation does not have a
* literal (e.g. IS NULL).
* @return a <code>RelationQueryNode</code>.
* @throws IllegalArgumentException if the literal value does not conform
* to its type. E.g. a malformed String representation of a date.
*/
private RelationQueryNode createRelationQueryNode(QueryNode parent, Name propertyName, int operationType, ASTLiteral literal) throws IllegalArgumentException {
RelationQueryNode node = null;
try {
Path relPath = null;
if (propertyName != null) {
PathBuilder builder = new PathBuilder();
builder.addLast(propertyName);
relPath = builder.getPath();
}
if (literal == null) {
node = factory.createRelationQueryNode(parent, operationType);
node.setRelativePath(relPath);
} else if (literal.getType() == QueryConstants.TYPE_DATE) {
SimpleDateFormat format = new SimpleDateFormat(DATE_PATTERN);
Date date = format.parse(literal.getValue());
node = factory.createRelationQueryNode(parent, operationType);
node.setRelativePath(relPath);
node.setDateValue(date);
} else if (literal.getType() == QueryConstants.TYPE_DOUBLE) {
double d = Double.parseDouble(literal.getValue());
node = factory.createRelationQueryNode(parent, operationType);
node.setRelativePath(relPath);
node.setDoubleValue(d);
} else if (literal.getType() == QueryConstants.TYPE_LONG) {
long l = Long.parseLong(literal.getValue());
node = factory.createRelationQueryNode(parent, operationType);
node.setRelativePath(relPath);
node.setLongValue(l);
} else if (literal.getType() == QueryConstants.TYPE_STRING) {
node = factory.createRelationQueryNode(parent, operationType);
node.setRelativePath(relPath);
node.setStringValue(literal.getValue());
} else if (literal.getType() == QueryConstants.TYPE_TIMESTAMP) {
Calendar c = ISO8601.parse(literal.getValue());
node = factory.createRelationQueryNode(parent, operationType);
node.setRelativePath(relPath);
node.setDateValue(c.getTime());
}
} catch (java.text.ParseException e) {
throw new IllegalArgumentException(e.toString());
} catch (NumberFormatException e) {
throw new IllegalArgumentException(e.toString());
} catch (MalformedPathException e) {
// path is always valid, but throw anyway
throw new IllegalArgumentException(e.getMessage());
}
if (node == null) {
throw new IllegalArgumentException("Unknown type for literal: " + literal.getType());
}
return node;
}
use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode in project jackrabbit by apache.
the class JCRSQLQueryBuilder method visit.
public Object visit(ASTPredicate node, Object data) {
NAryQueryNode parent = (NAryQueryNode) data;
int type = node.getOperationType();
QueryNode predicateNode;
try {
final Name[] tmp = new Name[2];
final ASTLiteral[] value = new ASTLiteral[1];
node.childrenAccept(new DefaultParserVisitor() {
public Object visit(ASTIdentifier node, Object data) {
if (tmp[0] == null) {
tmp[0] = node.getName();
} else if (tmp[1] == null) {
tmp[1] = node.getName();
}
return data;
}
public Object visit(ASTLiteral node, Object data) {
value[0] = node;
return data;
}
public Object visit(ASTLowerFunction node, Object data) {
getIdentifier(node);
return data;
}
public Object visit(ASTUpperFunction node, Object data) {
getIdentifier(node);
return data;
}
private void getIdentifier(SimpleNode node) {
if (node.jjtGetNumChildren() > 0) {
Node n = node.jjtGetChild(0);
if (n instanceof ASTIdentifier) {
ASTIdentifier identifier = (ASTIdentifier) n;
if (tmp[0] == null) {
tmp[0] = identifier.getName();
} else if (tmp[1] == null) {
tmp[1] = identifier.getName();
}
}
}
}
}, data);
Name identifier = tmp[0];
if (identifier != null && identifier.equals(NameConstants.JCR_PATH)) {
if (tmp[1] != null) {
// simply ignore, this is a join of a mixin node type
} else {
createPathQuery(value[0].getValue(), parent.getType());
}
// done
return data;
}
if (type == QueryConstants.OPERATION_BETWEEN) {
AndQueryNode between = factory.createAndQueryNode(parent);
RelationQueryNode rel = createRelationQueryNode(between, identifier, QueryConstants.OPERATION_GE_GENERAL, (ASTLiteral) node.children[1]);
node.childrenAccept(this, rel);
between.addOperand(rel);
rel = createRelationQueryNode(between, identifier, QueryConstants.OPERATION_LE_GENERAL, (ASTLiteral) node.children[2]);
node.childrenAccept(this, rel);
between.addOperand(rel);
predicateNode = between;
} else if (type == QueryConstants.OPERATION_GE_GENERAL || type == QueryConstants.OPERATION_GT_GENERAL || type == QueryConstants.OPERATION_LE_GENERAL || type == QueryConstants.OPERATION_LT_GENERAL || type == QueryConstants.OPERATION_NE_GENERAL || type == QueryConstants.OPERATION_EQ_GENERAL) {
predicateNode = createRelationQueryNode(parent, identifier, type, value[0]);
node.childrenAccept(this, predicateNode);
} else if (type == QueryConstants.OPERATION_LIKE) {
ASTLiteral pattern = value[0];
if (node.getEscapeString() != null) {
if (node.getEscapeString().length() == 1) {
// backslash is the escape character we use internally
pattern.setValue(translateEscaping(pattern.getValue(), node.getEscapeString().charAt(0), '\\'));
} else {
throw new IllegalArgumentException("ESCAPE string value must have length 1: '" + node.getEscapeString() + "'");
}
} else {
// no escape character specified.
// if the pattern contains any backslash characters we need
// to escape them.
pattern.setValue(pattern.getValue().replaceAll("\\\\", "\\\\\\\\"));
}
predicateNode = createRelationQueryNode(parent, identifier, type, pattern);
node.childrenAccept(this, predicateNode);
} else if (type == QueryConstants.OPERATION_IN) {
OrQueryNode in = factory.createOrQueryNode(parent);
for (int i = 1; i < node.children.length; i++) {
RelationQueryNode rel = createRelationQueryNode(in, identifier, QueryConstants.OPERATION_EQ_VALUE, (ASTLiteral) node.children[i]);
node.childrenAccept(this, rel);
in.addOperand(rel);
}
predicateNode = in;
} else if (type == QueryConstants.OPERATION_NULL || type == QueryConstants.OPERATION_NOT_NULL) {
predicateNode = createRelationQueryNode(parent, identifier, type, null);
} else if (type == QueryConstants.OPERATION_SIMILAR) {
ASTLiteral literal;
if (node.children.length == 1) {
literal = (ASTLiteral) node.children[0];
} else {
literal = (ASTLiteral) node.children[1];
}
predicateNode = createRelationQueryNode(parent, identifier, type, literal);
} else if (type == QueryConstants.OPERATION_SPELLCHECK) {
predicateNode = createRelationQueryNode(parent, NameConstants.JCR_PRIMARYTYPE, type, (ASTLiteral) node.children[0]);
} else {
throw new IllegalArgumentException("Unknown operation type: " + type);
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException("Too few arguments in predicate");
}
if (predicateNode != null) {
parent.addOperand(predicateNode);
}
return data;
}
use of org.apache.jackrabbit.spi.commons.query.RelationQueryNode in project jackrabbit by apache.
the class JCRSQLQueryBuilder method visit.
public Object visit(ASTUpperFunction node, Object data) {
RelationQueryNode parent = (RelationQueryNode) data;
if (parent.getValueType() != QueryConstants.TYPE_STRING) {
String msg = "UPPER() function is only supported for String literal";
throw new IllegalArgumentException(msg);
}
parent.addOperand(factory.createPropertyFunctionQueryNode(parent, PropertyFunctionQueryNode.UPPER_CASE));
return parent;
}
Aggregations