You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2005/01/20 16:10:25 UTC
svn commit: r125778 - in incubator/jackrabbit/trunk/src: grammar/sql java/org/apache/jackrabbit/core java/org/apache/jackrabbit/core/search java/org/apache/jackrabbit/core/search/jcrql java/org/apache/jackrabbit/core/search/lucene java/org/apache/jackrabbit/core/search/sql java/org/apache/jackrabbit/core/search/xpath test/org/apache/jackrabbit/test/search
Author: mreutegg
Date: Thu Jan 20 07:10:22 2005
New Revision: 125778
URL: http://svn.apache.org/viewcvs?view=rev&rev=125778
Log:
- Removed JCRQL implementation
- Added proper QName support to search
- redesigned parsing and formating of queries (better separation of abstract query tree and concrete syntax)
- Some improvements in SQL: colon is now supported in identifier without having to use double quotes, LIKE now supports escaping
Added:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java (contents, props changed)
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/ISO9075.java (contents, props changed)
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/QueryFormat.java (contents, props changed)
Removed:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/jcrql/
Modified:
incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/AndQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/ExactQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/LocationStepQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NAryQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NodeTypeQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NotQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrderQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/PathQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryParser.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryRootNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RangeQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RelationQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/TextsearchQueryNode.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/FilteredPropertyIterator.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllQuery.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIndexer.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/PropertyIteratorImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTIdentifier.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTPredicate.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/FulltextQueryTest.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SimpleQueryTest.java
Modified: incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt&r1=125777&p2=incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt (original)
+++ incubator/jackrabbit/trunk/src/grammar/sql/JCRSQL.jjt Thu Jan 20 07:10:22 2005
@@ -41,23 +41,34 @@
*/
package org.apache.jackrabbit.core.search.sql;
+import org.apache.jackrabbit.core.IllegalNameException;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.UnknownPrefixException;
import org.apache.jackrabbit.core.search.Constants;
public class JCRSQLParser {
private String statement;
+ private NamespaceResolver resolver;
+
public static void main(String args[]) throws ParseException {
JCRSQLParser parser = new JCRSQLParser(System.in);
parser.Query().dump("");
}
- public static ASTQuery parse(String statement) throws ParseException {
+ public static ASTQuery parse(String statement, NamespaceResolver resolver) throws ParseException {
java.io.StringReader sReader = new java.io.StringReader(statement);
JCRSQLParser parser = new JCRSQLParser(sReader);
+ parser.setNamespaceResolver(resolver);
return parser.Query();
}
+ private void setNamespaceResolver(NamespaceResolver resolver) {
+ this.resolver = resolver;
+ }
+
}
PARSER_END(JCRSQLParser)
@@ -88,6 +99,7 @@
| < FROM: "FROM" >
| < ORDER: "ORDER" >
| < WHERE: "WHERE" >
+| < ESCAPE: "ESCAPE" >
| < SELECT: "SELECT" >
| < BETWEEN: "BETWEEN" >
| < CONTAINS: "CONTAINS" >
@@ -179,7 +191,7 @@
| < REGULAR_IDENTIFIER: <IDENTIFIER_BODY> >
-| < #IDENTIFIER_BODY: <IDENTIFIER_START> (<UNDERSCORE> | <IDENTIFIER_PART>)* >
+| < #IDENTIFIER_BODY: <IDENTIFIER_START> (<UNDERSCORE> | <COLON> | <IDENTIFIER_PART>)* >
| < #IDENTIFIER_START: <LETTER> > // syntax rules 5.2
| < #IDENTIFIER_PART: <IDENTIFIER_START> | <DIGIT> >
@@ -282,9 +294,9 @@
void Predicate() :
{
int operationType;
- String identifier;
- Token t;
+ QName identifier;
String value;
+ String escapeString;
}
{
identifier = Identifier() { jjtThis.setIdentifier(identifier); }
@@ -306,9 +318,9 @@
ASTLiteral s = new ASTLiteral(JJTLITERAL);
s.setType(Constants.TYPE_STRING);
s.setValue(value);
- s.jjtSetParent(jjtThis);
- jjtThis.jjtAddChild(s, jjtThis.jjtGetNumChildren());
+ jjtree.pushNode(s);
}
+ (<ESCAPE> escapeString = CharStringLiteral() { jjtThis.setEscapeString(escapeString); })?
)
)
)
@@ -457,16 +469,34 @@
}
}
-String Identifier() :
+QName Identifier() :
{
Token t = null;
- String name = null;
+ QName name = null;
}
{
(
- t = <REGULAR_IDENTIFIER> { jjtThis.setName(t.image); }
+ t = <REGULAR_IDENTIFIER>
+ {
+ try {
+ jjtThis.setName(QName.fromJCRName(t.image, resolver));
+ } catch (IllegalNameException e) {
+ throw new ParseException(e.getMessage());
+ } catch (UnknownPrefixException e) {
+ throw new ParseException(e.getMessage());
+ }
+ }
|
- t = <DELIMITED_IDENTIFIER> { jjtThis.setName(t.image.substring(1, t.image.length()-1)); }
+ t = <DELIMITED_IDENTIFIER>
+ {
+ try {
+ jjtThis.setName(QName.fromJCRName(t.image.substring(1, t.image.length()-1), resolver));
+ } catch (IllegalNameException e) {
+ throw new ParseException(e.getMessage());
+ } catch (UnknownPrefixException e) {
+ throw new ParseException(e.getMessage());
+ }
+ }
|
(
(
@@ -485,7 +515,15 @@
| t = <SELECT>
| t = <BETWEEN>
)
- { jjtThis.setName(t.image); }
+ {
+ try {
+ jjtThis.setName(QName.fromJCRName(t.image, resolver));
+ } catch (IllegalNameException e) {
+ throw new ParseException(e.getMessage());
+ } catch (UnknownPrefixException e) {
+ throw new ParseException(e.getMessage());
+ }
+ }
)
)
{
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java Thu Jan 20 07:10:22 2005
@@ -40,6 +40,13 @@
/**
* Acts as a global entry point to execute queries and index nodes.
+ *
+ * @todo The SearchManager currently uses the system session to obtain an
+ * ItemStateManager from where it reads persistent ItemStates. This is kind
+ * of nasty, because the system session it is possible to change content through
+ * the system session as well.
+ * After switch to version 0.16 there is a shared ItemStateManager which
+ * represents the persistent view of item states.
*/
public class SearchManager implements SynchronousEventListener {
@@ -55,6 +62,11 @@
private static final String NS_XS_PREFIX = "xs";
public static final String NS_XS_URI = "http://www.w3.org/2001/XMLSchema";
+ /** Namespace URI for JCR functions */
+ // @todo check if consistent with spec
+ private static final String NS_JCRFN_PREFIX = "jcrfn";
+ public static final String NS_JCRFN_URI = "http://www.jcp.org/jcr/xpath-functions/1.0";
+
/** HierarchyManager for path resolution */
private final HierarchyManager hmgr;
@@ -86,6 +98,12 @@
} catch (RepositoryException e) {
// not yet known
nsReg.registerNamespace(NS_FN_PREFIX, NS_FN_URI);
+ }
+ try {
+ nsReg.getPrefix(NS_JCRFN_URI);
+ } catch (RepositoryException e) {
+ // not yet known
+ nsReg.registerNamespace(NS_JCRFN_PREFIX, NS_JCRFN_URI);
}
// initialize query handler
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/AndQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/AndQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/AndQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/AndQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/AndQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/AndQueryNode.java Thu Jan 20 07:10:22 2005
@@ -55,74 +55,4 @@
return visitor.visit(this, data);
}
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in JCRQL syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toJCRQLString() {
- StringBuffer sb = new StringBuffer();
- boolean bracket = false;
- if (getParent() instanceof NotQueryNode) {
- bracket = true;
- }
- if (bracket) {
- sb.append("(");
- }
- String and = "";
- for (Iterator it = operands.iterator(); it.hasNext();) {
- sb.append(and);
- sb.append(((QueryNode) it.next()).toJCRQLString());
- and = " AND ";
- }
- if (bracket) {
- sb.append(")");
- }
- return sb.toString();
- }
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in JCR SQL syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toJCRSQLString() {
- StringBuffer sb = new StringBuffer();
- boolean bracket = false;
- if (getParent() instanceof NotQueryNode) {
- bracket = true;
- }
- if (bracket) {
- sb.append("(");
- }
- String and = "";
- for (Iterator it = operands.iterator(); it.hasNext();) {
- sb.append(and);
- sb.append(((QueryNode) it.next()).toJCRSQLString());
- and = " AND ";
- }
- if (bracket) {
- sb.append(")");
- }
- return sb.toString();
- }
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in XPath syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toXPathString() {
- StringBuffer sb = new StringBuffer();
- String and = "";
- for (Iterator it = operands.iterator(); it.hasNext();) {
- sb.append(and);
- sb.append(((QueryNode) it.next()).toXPathString());
- and = " and ";
- }
- return sb.toString();
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/ExactQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/ExactQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/ExactQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/ExactQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/ExactQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/ExactQueryNode.java Thu Jan 20 07:10:22 2005
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.core.search;
+import org.apache.jackrabbit.core.QName;
+
/**
* Implements a query node that defines an exact match of a property and a
* value.
@@ -25,12 +27,12 @@
/**
* The name of the property to match
*/
- private final String property;
+ private final QName property;
/**
* The value of the property to match
*/
- private final String value;
+ private final QName value;
/**
* Creates a new <code>ExactQueryNode</code> instance.
@@ -39,7 +41,7 @@
* @param property the name of the property to match.
* @param value the value of the property to match.
*/
- public ExactQueryNode(QueryNode parent, String property, String value) {
+ public ExactQueryNode(QueryNode parent, QName property, QName value) {
super(parent);
if (parent == null) {
throw new NullPointerException("parent");
@@ -60,7 +62,7 @@
*
* @return the name of the property to match.
*/
- public String getPropertyName() {
+ public QName getPropertyName() {
return property;
}
@@ -69,38 +71,8 @@
*
* @return the value of the property to match.
*/
- public String getValue() {
+ public QName getValue() {
return value;
}
- /**
- * Returns a JCRQL representation for this query node.
- *
- * @return a JCRQL representation for this query node.
- */
- public String toJCRQLString() {
- if (property.indexOf(' ') > -1) {
- return "\"" + property + "\"=\"" + value + "\"";
- }
- return property + "=\"" + value + "\"";
- }
-
- /**
- * Returns a JCR SQL representation for this query node.
- *
- * @return a JCR SQL representation for this query node.
- */
- public String toJCRSQLString() {
- return "\"" + property + "\"='" + value + "'";
- }
-
- /**
- * Returns an XPath representation for this query node.
- *
- * @return an XPath representation for this query node.
- */
- public String toXPathString() {
- // todo use encoding for property name
- return "@" + property + "='" + value.replaceAll("'", "''") + "'";
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/LocationStepQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/LocationStepQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/LocationStepQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/LocationStepQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/LocationStepQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/LocationStepQueryNode.java Thu Jan 20 07:10:22 2005
@@ -16,7 +16,7 @@
*/
package org.apache.jackrabbit.core.search;
-import java.util.Iterator;
+import org.apache.jackrabbit.core.QName;
/**
* Defines a location step for querying the path of a node.
@@ -37,7 +37,7 @@
* Name test for this location step. A <code>null</code> value indicates
* a '*' name test.
*/
- private String nameTest;
+ private QName nameTest;
/**
* If set to <code>true</code> this location step uses the descendant-or-self
@@ -49,7 +49,7 @@
* If <code>index</code> is larger than 0 this location step contains
* a position index.
*/
- private int index = -1;
+ private int index = 0;
/**
* Creates a new <code>LocationStepQueryNode</code> with a reference to
@@ -60,7 +60,7 @@
* @param descendants if <code>true</code> this location step uses the
* descendant-or-self axis; otherwise the child axis.
*/
- public LocationStepQueryNode(QueryNode parent, String nameTest, boolean descendants) {
+ public LocationStepQueryNode(QueryNode parent, QName nameTest, boolean descendants) {
super(parent);
this.nameTest = nameTest;
this.includeDescendants = descendants;
@@ -71,7 +71,7 @@
* if the name test is '*'.
* @return the label of the node for this location step.
*/
- public String getNameTest() {
+ public QName getNameTest() {
return nameTest;
}
@@ -79,7 +79,7 @@
* Sets a new name test.
* @param nameTest the name test or <code>null</code> to match all names.
*/
- public void setNameTest(String nameTest) {
+ public void setNameTest(QName nameTest) {
this.nameTest = nameTest;
}
@@ -126,15 +126,23 @@
}
/**
- * Sets the position index for this step.
+ * Sets the position index for this step. A value of 0 (zero) indicates
+ * that this location step has no position index assigned. That is, the
+ * step selects all same name siblings.
* @param index the position index.
+ * @exception IllegalArgumentException if index < 0.
*/
public void setIndex(int index) {
+ if (index < 0) {
+ throw new IllegalArgumentException("index < 0");
+ }
this.index = index;
}
/**
- * Returns the position index for this step.
+ * Returns the position index for this step. A value of 0 (zero) indicates
+ * that this location step has no position index assigned. That is, the
+ * step selects all same name siblings.
* @return the position index for this step.
*/
public int getIndex() {
@@ -148,66 +156,4 @@
return visitor.visit(this, data);
}
- /**
- * Returns a JCRQL representation for this query node.
- *
- * @return a JCRQL representation for this query node.
- */
- public String toJCRQLString() {
- StringBuffer sb = new StringBuffer();
- if (nameTest == null) {
- sb.append("*");
- } else {
- sb.append(nameTest);
- }
- if (index > -1) {
- sb.append('[').append(index).append(']');
- }
- return sb.toString();
- }
-
- /**
- * Returns a JCR SQL representation for this query node.
- *
- * @return a JCR SQL representation for this query node.
- */
- public String toJCRSQLString() {
- StringBuffer sb = new StringBuffer();
- if (nameTest == null) {
- sb.append("*");
- } else {
- sb.append(nameTest);
- }
- if (index > -1) {
- sb.append('[').append(index).append(']');
- }
- return sb.toString();
- }
-
- /**
- * Returns an XPath representation for this query node.
- *
- * @return an XPath representation for this query node.
- */
- public String toXPathString() {
- StringBuffer sb = new StringBuffer();
- if (includeDescendants) {
- sb.append('/');
- }
- if (nameTest == null) {
- sb.append("*");
- } else {
- sb.append(nameTest);
- }
- if (index > -1) {
- sb.append('[').append(index).append(']');
- }
- if (operands != null) {
- for (Iterator it = operands.iterator(); it.hasNext();) {
- QueryNode predicate = (QueryNode) it.next();
- sb.append('[').append(predicate.toXPathString()).append(']');
- }
- }
- return sb.toString();
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NAryQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NAryQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NAryQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NAryQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NAryQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NAryQueryNode.java Thu Jan 20 07:10:22 2005
@@ -54,7 +54,10 @@
*/
public NAryQueryNode(QueryNode parent, QueryNode[] operands) {
super(parent);
- this.operands.addAll(Arrays.asList(operands));
+ if (operands.length > 0) {
+ this.operands = new ArrayList();
+ this.operands.addAll(Arrays.asList(operands));
+ }
}
/**
@@ -67,6 +70,20 @@
operands = new ArrayList();
}
operands.add(operand);
+ }
+
+ /**
+ * Returns an array of currently set <code>QueryNode</code> operands of this
+ * <code>QueryNode</code>. Returns an empty array if no operands are set.
+ *
+ * @return currently set <code>QueryNode</code> operands.
+ */
+ public QueryNode[] getOperands() {
+ if (operands == null) {
+ return new QueryNode[0];
+ } else {
+ return (QueryNode[]) operands.toArray(new QueryNode[operands.size()]);
+ }
}
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NodeTypeQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NodeTypeQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NodeTypeQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NodeTypeQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NodeTypeQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NodeTypeQueryNode.java Thu Jan 20 07:10:22 2005
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.core.search;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.core.QName;
/**
* Implements a query node that defines a node type match.
@@ -29,11 +30,11 @@
* @param parent the parent node for this query node.
* @param nodeType the name of the node type.
*/
- public NodeTypeQueryNode(QueryNode parent, String nodeType) {
+ public NodeTypeQueryNode(QueryNode parent, QName nodeType) {
// we only use the jcr primary type as a dummy value
// the property name is actually replaced in the query builder
// when the runtime query is created to search the index.
- super(parent, NodeTypeRegistry.JCR_PRIMARY_TYPE.toString(), nodeType);
+ super(parent, NodeTypeRegistry.JCR_PRIMARY_TYPE, nodeType);
}
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NotQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NotQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NotQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NotQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NotQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/NotQueryNode.java Thu Jan 20 07:10:22 2005
@@ -49,39 +49,4 @@
return visitor.visit(this, data);
}
- /**
- * Returns a JCRQL representation for this query node.
- *
- * @return a JCRQL representation for this query node.
- */
- public String toJCRQLString() {
- if (operands.size() > 0) {
- return "NOT " + ((QueryNode) operands.get(0)).toJCRQLString();
- }
- return "";
- }
-
- /**
- * Returns a JCR SQL representation for this query node.
- *
- * @return a JCR SQL representation for this query node.
- */
- public String toJCRSQLString() {
- if (operands.size() > 0) {
- return "NOT " + ((QueryNode) operands.get(0)).toJCRSQLString();
- }
- return "";
- }
-
- /**
- * Returns an XPath representation for this query node.
- *
- * @return an XPath representation for this query node.
- */
- public String toXPathString() {
- if (operands.size() > 0) {
- return "fn:not(" + ((QueryNode) operands.get(0)).toXPathString() + ")";
- }
- return "";
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrQueryNode.java Thu Jan 20 07:10:22 2005
@@ -16,8 +16,6 @@
*/
package org.apache.jackrabbit.core.search;
-import java.util.Iterator;
-
/**
* Implements a query node that defines an OR operation between arbitrary
* other {@link QueryNode}s.
@@ -53,88 +51,4 @@
return visitor.visit(this, data);
}
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in JCRQL syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toJCRQLString() {
- StringBuffer sb = new StringBuffer();
- boolean bracket = false;
- if (getParent() instanceof LocationStepQueryNode
- || getParent() instanceof AndQueryNode
- || getParent() instanceof NotQueryNode) {
- bracket = true;
- }
- if (bracket) {
- sb.append("(");
- }
- String or = "";
- for (Iterator it = operands.iterator(); it.hasNext();) {
- sb.append(or);
- sb.append(((QueryNode) it.next()).toJCRQLString());
- or = " OR ";
- }
- if (bracket) {
- sb.append(")");
- }
- return sb.toString();
- }
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in JCR SQL syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toJCRSQLString() {
- StringBuffer sb = new StringBuffer();
- boolean bracket = false;
- if (getParent() instanceof LocationStepQueryNode
- || getParent() instanceof AndQueryNode
- || getParent() instanceof NotQueryNode) {
- bracket = true;
- }
- if (bracket) {
- sb.append("(");
- }
- String or = "";
- for (Iterator it = operands.iterator(); it.hasNext();) {
- sb.append(or);
- sb.append(((QueryNode) it.next()).toJCRSQLString());
- or = " OR ";
- }
- if (bracket) {
- sb.append(")");
- }
- return sb.toString();
- }
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in XPath syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toXPathString() {
- StringBuffer sb = new StringBuffer();
- boolean bracket = false;
- if (getParent() instanceof AndQueryNode) {
- bracket = true;
- }
- if (bracket) {
- sb.append("(");
- }
- String or = "";
- for (Iterator it = operands.iterator(); it.hasNext();) {
- sb.append(or);
- sb.append(((QueryNode) it.next()).toXPathString());
- or = " or ";
- }
- if (bracket) {
- sb.append(")");
- }
- return sb.toString();
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrderQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrderQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrderQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrderQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrderQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/OrderQueryNode.java Thu Jan 20 07:10:22 2005
@@ -16,6 +16,8 @@
*/
package org.apache.jackrabbit.core.search;
+import org.apache.jackrabbit.core.QName;
+
/**
* Implements a query node that defines the order of nodes according to the
* values of properties.
@@ -25,7 +27,7 @@
/**
* The name of the properties to order
*/
- private String[] properties;
+ private QName[] properties;
/**
* Array of flag indicating whether a node is ordered ascending or descending
@@ -41,9 +43,11 @@
* @param orderSpecs if <code>true</code> a result node is orderd ascending;
* otherwise descending.
*/
- public OrderQueryNode(QueryNode parent, String[] properties, boolean[] orderSpecs) {
+ public OrderQueryNode(QueryNode parent, QName[] properties, boolean[] orderSpecs) {
super(parent);
- if (properties.length != orderSpecs.length)
+ if (properties.length != orderSpecs.length) {
+ throw new IllegalArgumentException("Number of propertes and orderSpecs must be the same");
+ }
this.properties = properties;
this.orderSpecs = orderSpecs;
}
@@ -71,12 +75,12 @@
}
/**
- * Returns a String array that contains the name of the properties
+ * Returns a <code>QName</code> array that contains the name of the properties
* to sort the result nodes.
*
* @return names of order properties.
*/
- public String[] getOrderByProperties() {
+ public QName[] getOrderByProperties() {
return properties;
}
@@ -89,59 +93,4 @@
return orderSpecs;
}
- /**
- * Returns a JCRQL representation for this query node.
- *
- * @return a JCRQL representation for this query node.
- */
- public String toJCRQLString() {
- StringBuffer sb = new StringBuffer("ORDER BY");
- if (properties.length > 0) {
- String comma = "";
- for (int i = 0; i < properties.length; i++) {
- sb.append(comma).append(" ");
- sb.append(properties[i]);
- if (isAscending(i)) {
- // FIXME really default to descending?
- sb.append(" ASCENDING");
- }
- comma = ",";
- }
- } else {
- sb.append(" SCORE");
- }
- return sb.toString();
- }
-
- /**
- * Returns a JCR SQL representation for this query node.
- *
- * @return a JCR SQL representation for this query node.
- */
- public String toJCRSQLString() {
- StringBuffer sb = new StringBuffer("ORDER BY");
- if (properties.length > 0) {
- String comma = "";
- for (int i = 0; i < properties.length; i++) {
- sb.append(comma).append(" \"");
- sb.append(properties[i]).append("\"");
- if (!isAscending(i)) {
- sb.append(" DESC");
- }
- comma = ",";
- }
- } else {
- sb.append(" SCORE");
- }
- return sb.toString();
- }
-
- /**
- * Returns an XPath representation for this query node.
- *
- * @return an XPath representation for this query node.
- */
- public String toXPathString() {
- return "";
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/PathQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/PathQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/PathQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/PathQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/PathQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/PathQueryNode.java Thu Jan 20 07:10:22 2005
@@ -57,61 +57,4 @@
}
}
- /**
- * Returns a JCRQL representation for this query node.
- *
- * @return a JCRQL representation for this query node.
- */
- public String toJCRQLString() {
- StringBuffer sb = new StringBuffer("LOCATION \"");
- LocationStepQueryNode[] steps = getPathSteps();
- for (int i = 0; i < steps.length; i++) {
- if (steps[i].getNameTest() == null
- || steps[i].getNameTest().length() > 0) {
- sb.append('/');
- }
- sb.append(steps[i].toJCRQLString());
- }
- sb.append('"');
- return sb.toString();
- }
-
-
- /**
- * Returns a JCR SQL representation for this query node.
- *
- * @return a JCR SQL representation for this query node.
- */
- public String toJCRSQLString() {
- // FIXME implement namespace awareness
- StringBuffer sb = new StringBuffer("\"jcr:path\"='");
- LocationStepQueryNode[] steps = getPathSteps();
- for (int i = 0; i < steps.length; i++) {
- if (steps[i].getNameTest() == null
- || steps[i].getNameTest().length() > 0) {
- sb.append('/');
- }
- sb.append(steps[i].toJCRSQLString());
- }
- sb.append('\'');
- return sb.toString();
- }
-
- /**
- * Returns an XPath representation for this query node.
- *
- * @return an XPath representation for this query node.
- */
- public String toXPathString() {
- StringBuffer sb = new StringBuffer();
- LocationStepQueryNode[] steps = getPathSteps();
- for (int i = 0; i < steps.length; i++) {
- if (steps[i].getNameTest() == null
- || steps[i].getNameTest().length() > 0) {
- sb.append('/');
- }
- sb.append(steps[i].toXPathString());
- }
- return sb.toString();
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryNode.java Thu Jan 20 07:10:22 2005
@@ -61,27 +61,4 @@
*/
public abstract Object accept(QueryNodeVisitor visitor, Object data);
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in JCRQL syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public abstract String toJCRQLString();
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in JCRQL syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public abstract String toJCRSQLString();
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in XPath syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public abstract String toXPathString();
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryParser.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryParser.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryParser.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryParser.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryParser.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryParser.java Thu Jan 20 07:10:22 2005
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.core.search;
-import org.apache.jackrabbit.core.search.jcrql.JCRQLQueryBuilder;
import org.apache.jackrabbit.core.search.xpath.XPathQueryBuilder;
import org.apache.jackrabbit.core.search.sql.JCRSQLQueryBuilder;
import org.apache.jackrabbit.core.NamespaceResolver;
@@ -55,14 +54,45 @@
NamespaceResolver resolver)
throws InvalidQueryException {
- if (Query.JCRQL.equals(language)) {
- return JCRQLQueryBuilder.createQuery(statement);
- } else if (Query.XPATH_DOCUMENT_VIEW.equals(language)) {
+ if (Query.XPATH_DOCUMENT_VIEW.equals(language)) {
return XPathQueryBuilder.createQuery(statement, resolver);
} else if ("sql".equals(language)) {
return JCRSQLQueryBuilder.createQuery(statement, resolver);
} else {
- throw new InvalidQueryException("unknown language");
+ throw new InvalidQueryException("Unsupported language: " + language);
+ }
+ }
+
+ /**
+ * Creates a String representation of the QueryNode tree argument
+ * <code>root</code>. The argument <code>language</code> specifies the
+ * syntax.
+ * See also: {@link javax.jcr.query.QueryManager#getSupportedQueryLanguages()}.
+ *
+ * @param root the query node tree.
+ * @param language one of the languages returned by:
+ * {@link javax.jcr.query.QueryManager#getSupportedQueryLanguages()}.
+ * @param resolver to resolve QNames.
+ *
+ * @return a String representation of the query node tree.
+ *
+ * @throws InvalidQueryException if the query node tree cannot be converted
+ * into a String representation of the given language. This might be due to
+ * syntax restrictions of the given language. This exception is also thrown
+ * if <code>language</code> is not one of the supported query languages
+ * returned by the {@link javax.jcr.query.QueryManager}.
+ */
+ public static String toString(QueryRootNode root,
+ String language,
+ NamespaceResolver resolver)
+ throws InvalidQueryException {
+
+ if (Query.XPATH_DOCUMENT_VIEW.equals(language)) {
+ return XPathQueryBuilder.toString(root, resolver);
+ } else if ("sql".equals(language)) {
+ return JCRSQLQueryBuilder.toString(root, resolver);
+ } else {
+ throw new InvalidQueryException("Unsupported language: " + language);
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryRootNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryRootNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryRootNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryRootNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryRootNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryRootNode.java Thu Jan 20 07:10:22 2005
@@ -16,8 +16,9 @@
*/
package org.apache.jackrabbit.core.search;
+import org.apache.jackrabbit.core.QName;
+
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
/**
@@ -31,13 +32,8 @@
private PathQueryNode locationNode;
/**
- * The list of nodeType constraints. Might be null
- * @todo not used anymore, node types can be specified in any predicate.
- */
- private List nodeTypes = new ArrayList();
-
- /**
- * The list of property names to select. Might be null
+ * The list of property names (as {@link org.apache.jackrabbit.core.QName}s
+ * to select.
*/
private List selectProperties = new ArrayList();
@@ -78,7 +74,7 @@
*
* @param propName the name of the property to select.
*/
- public void addSelectProperty(String propName) {
+ public void addSelectProperty(QName propName) {
selectProperties.add(propName);
}
@@ -87,8 +83,8 @@
*
* @return an array of select properties.
*/
- public String[] getSelectProperties() {
- return (String[]) selectProperties.toArray(new String[selectProperties.size()]);
+ public QName[] getSelectProperties() {
+ return (QName[]) selectProperties.toArray(new QName[selectProperties.size()]);
}
/**
@@ -108,7 +104,6 @@
public void setOrderNode(OrderQueryNode orderNode) {
this.orderNode = orderNode;
}
- //--------------------------------------------------------------------------
/**
* @see QueryNode#accept(org.apache.jackrabbit.core.search.QueryNodeVisitor, java.lang.Object)
@@ -117,89 +112,4 @@
return visitor.visit(this, data);
}
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in JCRQL syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toJCRQLString() {
- StringBuffer sb = new StringBuffer("SELECT *");
- String comma = "";
- if (nodeTypes.size() > 0) {
- sb.append(" FROM");
- }
- for (Iterator it = nodeTypes.iterator(); it.hasNext();) {
- NodeTypeQueryNode nodeType = (NodeTypeQueryNode) it.next();
- sb.append(comma);
- sb.append(" ").append(nodeType.getValue());
- comma = ",";
- }
- if (locationNode != null) {
- sb.append(" ").append(locationNode.toJCRQLString());
- }
- LocationStepQueryNode[] steps = locationNode.getPathSteps();
- QueryNode[] predicates = steps[steps.length - 1].getPredicates();
- String and = "";
- for (int i = 0; i < predicates.length; i++) {
- if (i == 0) {
- sb.append(" WHERE ");
- }
- sb.append(and).append(predicates[i].toJCRQLString());
- and = " AND ";
- }
- return sb.toString();
- }
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in JCR SQL syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toJCRSQLString() {
- StringBuffer sb = new StringBuffer("SELECT *");
- sb.append(" FROM");
- String comma = "";
- if (nodeTypes.size() > 0) {
- for (Iterator it = nodeTypes.iterator(); it.hasNext();) {
- NodeTypeQueryNode nodeType = (NodeTypeQueryNode) it.next();
- sb.append(comma);
- sb.append(" \"").append(nodeType.getValue()).append("\"");
- comma = ",";
- }
- } else {
- sb.append(" nt:base");
- }
- LocationStepQueryNode[] steps = locationNode.getPathSteps();
- QueryNode[] predicates = steps[steps.length - 1].getPredicates();
- String and = "";
- for (int i = 0; i < predicates.length; i++) {
- if (i == 0) {
- sb.append(" WHERE ");
- }
- sb.append(and).append(predicates[i].toJCRSQLString());
- and = " AND ";
- }
-
- if (steps.length == 2
- && steps[1].getIncludeDescendants()
- && steps[1].getNameTest() == null) {
- // then this query selects all paths
- } else {
- sb.append(" AND ").append(locationNode.toJCRSQLString());
- }
- return sb.toString();
- }
-
- /**
- * Returns a string representation of this query node including its sub-nodes.
- * The returned string is formatted in XPath syntax.
- *
- * @return a string representation of this query node including its sub-nodes.
- */
- public String toXPathString() {
- return locationNode.toXPathString();
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RangeQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RangeQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RangeQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RangeQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RangeQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RangeQueryNode.java Thu Jan 20 07:10:22 2005
@@ -27,6 +27,7 @@
* <li><code>String</code></li>
* <li><code>Date</code></li>
* </ul>
+ * @todo remove this class. not used anymore
*/
public class RangeQueryNode extends QueryNode implements Constants {
@@ -167,30 +168,4 @@
return type;
}
- /**
- * Returns a JCRQL representation for this query node.
- *
- * @return a JCRQL representation for this query node.
- */
- public String toJCRQLString() {
- return "";
- }
-
- /**
- * Returns a JCR SQL representation for this query node.
- *
- * @return a JCR SQL representation for this query node.
- */
- public String toJCRSQLString() {
- return "";
- }
-
- /**
- * Returns an XPath representation for this query node.
- *
- * @return an XPath representation for this query node.
- */
- public String toXPathString() {
- return "";
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RelationQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RelationQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RelationQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RelationQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RelationQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/RelationQueryNode.java Thu Jan 20 07:10:22 2005
@@ -16,10 +16,9 @@
*/
package org.apache.jackrabbit.core.search;
-import javax.jcr.util.ISO8601;
-import java.util.Calendar;
+import org.apache.jackrabbit.core.QName;
+
import java.util.Date;
-import java.util.TimeZone;
/**
* Implements a query node that defines property value relation.
@@ -29,7 +28,7 @@
/**
* The name of the property
*/
- private String property;
+ private QName property;
/**
* The <code>long</code> value of the relation if this is a query is of type
@@ -87,7 +86,7 @@
* @param value a property value
* @param operation the type of the relation.
*/
- public RelationQueryNode(QueryNode parent, String property, long value, int operation) {
+ public RelationQueryNode(QueryNode parent, QName property, long value, int operation) {
super(parent);
this.property = property;
this.valueLong = value;
@@ -104,7 +103,7 @@
* @param value a property value
* @param operation the type of the relation.
*/
- public RelationQueryNode(QueryNode parent, String property, double value, int operation) {
+ public RelationQueryNode(QueryNode parent, QName property, double value, int operation) {
super(parent);
this.property = property;
this.valueDouble = value;
@@ -121,7 +120,7 @@
* @param value a property value
* @param operation the type of the relation.
*/
- public RelationQueryNode(QueryNode parent, String property, Date value, int operation) {
+ public RelationQueryNode(QueryNode parent, QName property, Date value, int operation) {
super(parent);
this.property = property;
this.valueDate = value;
@@ -138,7 +137,7 @@
* @param value a property value
* @param operation the type of the relation.
*/
- public RelationQueryNode(QueryNode parent, String property, String value, int operation) {
+ public RelationQueryNode(QueryNode parent, QName property, String value, int operation) {
super(parent);
this.property = property;
this.valueString = value;
@@ -167,7 +166,7 @@
*
* @return the name of the property in this relation query node.
*/
- public String getProperty() {
+ public QName getProperty() {
return property;
}
@@ -175,7 +174,7 @@
* Sets a new property name for this relation query node.
* @param name the new property name.
*/
- public void setProperty(String name) {
+ public void setProperty(QName name) {
property = name;
}
@@ -264,142 +263,4 @@
return operation;
}
- /**
- * Returns a JCRQL representation for this query node.
- *
- * @return a JCRQL representation for this query node.
- */
- public String toJCRQLString() {
- StringBuffer sb = new StringBuffer();
- if (property.indexOf(' ') > -1) {
- sb.append("\"" + property + "\"");
- } else {
- sb.append(property);
- }
-
- if (operation == OPERATION_EQ) {
- sb.append(" = ");
- } else if (operation == OPERATION_GE) {
- sb.append(" >= ");
- } else if (operation == OPERATION_GT) {
- sb.append(" > ");
- } else if (operation == OPERATION_LE) {
- sb.append(" <= ");
- } else if (operation == OPERATION_LIKE) {
- sb.append(" LIKE ");
- } else if (operation == OPERATION_LT) {
- sb.append(" < ");
- } else if (operation == OPERATION_NE) {
- sb.append(" <> ");
- } else {
- throw new RuntimeException("invalid operation: " + operation);
- }
-
-
- if (type == TYPE_LONG) {
- sb.append(valueLong);
- } else if (type == TYPE_DOUBLE) {
- sb.append(valueDouble);
- } else if (type == TYPE_STRING) {
- sb.append("\"").append(valueString).append("\"");
- } else if (type == TYPE_DATE || type == TYPE_TIMESTAMP) {
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- cal.setTime(valueDate);
- sb.append(ISO8601.format(cal));
- } else {
- throw new RuntimeException("Invalid type: " + type);
- }
- return sb.toString();
- }
-
- /**
- * Returns a JCR SQL representation for this query node.
- *
- * @return a JCR SQL representation for this query node.
- */
- public String toJCRSQLString() {
- StringBuffer sb = new StringBuffer();
- sb.append("\"" + property + "\"");
-
- if (operation == OPERATION_EQ) {
- sb.append(" = ");
- } else if (operation == OPERATION_GE) {
- sb.append(" >= ");
- } else if (operation == OPERATION_GT) {
- sb.append(" > ");
- } else if (operation == OPERATION_LE) {
- sb.append(" <= ");
- } else if (operation == OPERATION_LIKE) {
- sb.append(" LIKE ");
- } else if (operation == OPERATION_LT) {
- sb.append(" < ");
- } else if (operation == OPERATION_NE) {
- sb.append(" <> ");
- } else {
- throw new RuntimeException("invalid operation: " + operation);
- }
-
-
- if (type == TYPE_LONG) {
- sb.append(valueLong);
- } else if (type == TYPE_DOUBLE) {
- sb.append(valueDouble);
- } else if (type == TYPE_STRING) {
- sb.append("'").append(valueString.replaceAll("'", "''")).append("'");
- } else if (type == TYPE_DATE || type == TYPE_TIMESTAMP) {
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- cal.setTime(valueDate);
- sb.append("TIMESTAMP '").append(ISO8601.format(cal)).append("'");
- } else {
- throw new RuntimeException("Invalid type: " + type);
- }
- return sb.toString();
- }
-
- /**
- * Returns an XPath representation for this query node.
- *
- * @return an XPath representation for this query node.
- */
- public String toXPathString() {
- StringBuffer sb = new StringBuffer();
- // @todo use escaping for property name
- sb.append("@" + property);
-
- if (operation == OPERATION_EQ) {
- sb.append(" = ");
- } else if (operation == OPERATION_GE) {
- sb.append(" >= ");
- } else if (operation == OPERATION_GT) {
- sb.append(" > ");
- } else if (operation == OPERATION_LE) {
- sb.append(" <= ");
- } else if (operation == OPERATION_LIKE) {
- // @todo make namespace aware
- sb.insert(0, "jcrfn:like(").append(",");
- } else if (operation == OPERATION_LT) {
- sb.append(" < ");
- } else if (operation == OPERATION_NE) {
- sb.append(" != ");
- } else {
- throw new RuntimeException("invalid operation: " + operation);
- }
-
-
- if (type == TYPE_LONG) {
- sb.append(valueLong);
- } else if (type == TYPE_DOUBLE) {
- sb.append(valueDouble);
- } else if (type == TYPE_STRING) {
- sb.append("'").append(valueString.replaceAll("'", "''")).append("'");
- } else if (type == TYPE_DATE || type == TYPE_TIMESTAMP) {
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- cal.setTime(valueDate);
- // @todo make namespace aware
- sb.append("xs:dateTime('").append(ISO8601.format(cal)).append("')");
- } else {
- throw new RuntimeException("Invalid type: " + type);
- }
- return sb.toString();
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/TextsearchQueryNode.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/TextsearchQueryNode.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/TextsearchQueryNode.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/TextsearchQueryNode.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/TextsearchQueryNode.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/TextsearchQueryNode.java Thu Jan 20 07:10:22 2005
@@ -54,25 +54,4 @@
return query;
}
- /**
- * Returns a JCRQL representation for this query node.
- *
- * @return a JCRQL representation for this query node.
- */
- public String toJCRQLString() {
- return "TEXTSEARCH \"" + query + "\"";
- }
-
- public String toJCRSQLString() {
- return "CONTAINS('" + query + "')";
- }
-
- /**
- * Returns an XPath representation for this query node.
- *
- * @return an XPath representation for this query node.
- */
- public String toXPathString() {
- return "jcrfn:contains('" + query.replaceAll("'", "''") + "')";
- }
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/FilteredPropertyIterator.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/FilteredPropertyIterator.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/FilteredPropertyIterator.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/FilteredPropertyIterator.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/FilteredPropertyIterator.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/FilteredPropertyIterator.java Thu Jan 20 07:10:22 2005
@@ -17,6 +17,9 @@
package org.apache.jackrabbit.core.search.lucene;
import org.apache.log4j.Logger;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.NoPrefixDeclaredException;
import javax.jcr.Node;
import javax.jcr.Property;
@@ -30,15 +33,18 @@
private static final Logger log = Logger.getLogger(FilteredPropertyIterator.class);
- private String[] props;
+ private QName[] props;
private Node node;
+ private NamespaceResolver resolver;
+
private int propIndex;
- FilteredPropertyIterator(String[] props, Node node) {
+ FilteredPropertyIterator(QName[] props, Node node, NamespaceResolver resolver) {
this.props = props;
this.node = node;
+ this.resolver = resolver;
}
public Property nextProperty() {
@@ -46,11 +52,14 @@
throw new NoSuchElementException();
}
try {
- return node.getProperty(props[propIndex++]);
+ return node.getProperty(props[propIndex++].toJCRName(resolver));
} catch (RepositoryException e) {
// FIXME find better error handling
log.error("Exception retrieving property with name: "
+ props[propIndex - 1]);
+ throw new NoSuchElementException();
+ } catch (NoPrefixDeclaredException e) {
+ log.error("Exception resolving property name: " + e.toString());
throw new NoSuchElementException();
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java Thu Jan 20 07:10:22 2005
@@ -97,17 +97,16 @@
public Object visit(QueryRootNode node, Object data) {
BooleanQuery root = new BooleanQuery();
- String[] props = node.getSelectProperties();
+ QName[] props = node.getSelectProperties();
for (int i = 0; i < props.length; i++) {
- String prop = props[i];
try {
- prop = nsMappings.translatePropertyName(prop, session.getNamespaceResolver());
- } catch (IllegalNameException e) {
- exceptions.add(e);
- } catch (UnknownPrefixException e) {
+ String prop = props[i].toJCRName(nsMappings);
+ // @todo really search nodes that have non null values?
+ root.add(new MatchAllQuery(prop), true, false);
+ } catch (NoPrefixDeclaredException e) {
+ // should never happen actually. prefixes are dynamically created
exceptions.add(e);
}
- root.add(new MatchAllQuery(prop), true, false);
}
Query wrapped = root;
@@ -160,30 +159,25 @@
}
public Object visit(ExactQueryNode node, Object data) {
- String field = node.getPropertyName();
+ String field = "";
+ String value = "";
try {
- field = nsMappings.translatePropertyName(node.getPropertyName(),
- session.getNamespaceResolver());
- } catch (IllegalNameException e) {
- exceptions.add(e);
- } catch (UnknownPrefixException e) {
- exceptions.add(e);
+ field = node.getPropertyName().toJCRName(nsMappings);
+ value = node.getValue().toJCRName(nsMappings);
+ } catch (NoPrefixDeclaredException e) {
+ // will never happen, prefixes are created when unknown
}
- String value = node.getValue();
return new TermQuery(new Term(field, value));
}
public Object visit(NodeTypeQueryNode node, Object data) {
- String field = node.getPropertyName();
+ String field = "";
List values = new ArrayList();
try {
- field = nsMappings.getPrefix(NodeTypeRegistry.JCR_PRIMARY_TYPE.getNamespaceURI())
- + ":" + NodeTypeRegistry.JCR_PRIMARY_TYPE.getLocalName();
-
- values.add(nsMappings.translatePropertyName(node.getValue(),
- session.getNamespaceResolver()));
+ field = NodeTypeRegistry.JCR_PRIMARY_TYPE.toJCRName(nsMappings);
+ values.add(node.getValue().toJCRName(nsMappings));
NodeTypeManager ntMgr = session.getWorkspace().getNodeTypeManager();
- NodeType base = ntMgr.getNodeType(node.getValue());
+ NodeType base = ntMgr.getNodeType(node.getValue().toJCRName(session.getNamespaceResolver()));
NodeTypeIterator allTypes = ntMgr.getAllNodeTypes();
while (allTypes.hasNext()) {
NodeType nt = allTypes.nextNodeType();
@@ -197,6 +191,9 @@
exceptions.add(e);
} catch (UnknownPrefixException e) {
exceptions.add(e);
+ } catch (NoPrefixDeclaredException e) {
+ // should never happen
+ exceptions.add(e);
} catch (RepositoryException e) {
exceptions.add(e);
}
@@ -275,7 +272,7 @@
}
public Object visit(LocationStepQueryNode node, Object data) {
- if (node.getNameTest() != null && node.getNameTest().length() == 0) {
+ if (node.getNameTest() != null && node.getNameTest().getLocalName().length() == 0) {
// select root node
return new TermQuery(new Term(FieldNames.PARENT, ""));
}
@@ -296,12 +293,10 @@
TermQuery nameTest = null;
if (node.getNameTest() != null) {
try {
- String internalName = nsMappings.translatePropertyName(node.getNameTest(),
- session.getNamespaceResolver());
+ String internalName = node.getNameTest().toJCRName(nsMappings);
nameTest = new TermQuery(new Term(FieldNames.LABEL, internalName));
- } catch (IllegalNameException e) {
- exceptions.add(e);
- } catch (UnknownPrefixException e) {
+ } catch (NoPrefixDeclaredException e) {
+ // should never happen
exceptions.add(e);
}
}
@@ -357,13 +352,11 @@
+ node.getType());
}
- String field = node.getProperty();
+ String field = "";
try {
- field = nsMappings.translatePropertyName(node.getProperty(),
- session.getNamespaceResolver());
- } catch (IllegalNameException e) {
- exceptions.add(e);
- } catch (UnknownPrefixException e) {
+ field = node.getProperty().toJCRName(nsMappings);
+ } catch (NoPrefixDeclaredException e) {
+ // should never happen
exceptions.add(e);
}
@@ -381,8 +374,11 @@
query = new RangeQuery(null, new Term(field, stringValue), true);
break;
case Constants.OPERATION_LIKE: // LIKE
- // @todo use MatchAllQuery if stringValue is "*" (or "%" ?)
- query = new WildcardQuery(new Term(field, stringValue));
+ if (stringValue.equals("%")) {
+ query = new MatchAllQuery(field);
+ } else {
+ query = new WildcardQuery(new Term(field, stringValue));
+ }
break;
case Constants.OPERATION_LT: // <
query = new RangeQuery(null, new Term(field, stringValue), false);
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllQuery.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllQuery.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllQuery.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllQuery.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllQuery.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllQuery.java Thu Jan 20 07:10:22 2005
@@ -53,12 +53,12 @@
}
/**
- * Returns the String "*".
+ * Returns the String "%".
*
* @param field default field for the query.
- * @return the String "*".
+ * @return the String "%".
*/
public String toString(String field) {
- return "*";
+ return "%";
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIndexer.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIndexer.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIndexer.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIndexer.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIndexer.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIndexer.java Thu Jan 20 07:10:22 2005
@@ -41,7 +41,7 @@
/**
* Creates a lucene <code>Document</code> object from a {@link javax.jcr.Node}.
*
- * @todo add support for indexing of nt:resource. e.g. when mime type is text/*
+ * todo add support for indexing of nt:resource. e.g. when mime type is text/*
*/
class NodeIndexer {
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/PropertyIteratorImpl.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/PropertyIteratorImpl.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/PropertyIteratorImpl.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/PropertyIteratorImpl.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/PropertyIteratorImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/PropertyIteratorImpl.java Thu Jan 20 07:10:22 2005
@@ -17,6 +17,8 @@
package org.apache.jackrabbit.core.search.lucene;
import org.apache.log4j.Logger;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.NamespaceResolver;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
@@ -30,18 +32,21 @@
private static final Logger log = Logger.getLogger(PropertyIteratorImpl.class);
- private String[] props;
+ private QName[] props;
private NodeIterator nodes;
+ private NamespaceResolver resolver;
+
private Property next;
private PropertyIterator currentProps;
private long pos;
- PropertyIteratorImpl(String[] props, NodeIterator nodes) {
+ PropertyIteratorImpl(QName[] props, NodeIterator nodes, NamespaceResolver resolver) {
this.nodes = nodes;
+ this.resolver = resolver;
if (props != null && props.length > 0) {
this.props = props;
@@ -104,7 +109,7 @@
// try to get next PropertyIterator
if (nodes.hasNext()) {
if (props != null) {
- currentProps = new FilteredPropertyIterator(props, nodes.nextNode());
+ currentProps = new FilteredPropertyIterator(props, nodes.nextNode(), resolver);
} else {
currentProps = nodes.nextNode().getProperties();
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java Thu Jan 20 07:10:22 2005
@@ -146,12 +146,12 @@
// by default. this contrasts to standard sql semantics
// where default is ascending.
boolean[] orderSpecs = null;
- String[] orderProperties = null;
+ QName[] orderProperties = null;
if (orderNode != null) {
orderProperties = orderNode.getOrderByProperties();
orderSpecs = orderNode.getOrderBySpecs();
} else {
- orderProperties = new String[0];
+ orderProperties = new QName[0];
orderSpecs = new boolean[0];
}
@@ -177,7 +177,8 @@
// return QueryResult
return new QueryResultImpl(itemMgr,
(String[]) uuids.toArray(new String[uuids.size()]),
- root.getSelectProperties());
+ root.getSelectProperties(),
+ session.getNamespaceResolver());
}
public String getStatement() {
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java Thu Jan 20 07:10:22 2005
@@ -17,6 +17,8 @@
package org.apache.jackrabbit.core.search.lucene;
import org.apache.jackrabbit.core.ItemManager;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.NamespaceResolver;
import org.apache.log4j.Logger;
import javax.jcr.NodeIterator;
@@ -35,14 +37,18 @@
private final String[] uuids;
- private final String[] selectProps;
+ private final QName[] selectProps;
+
+ private final NamespaceResolver resolver;
public QueryResultImpl(ItemManager itemMgr,
String[] uuids,
- String[] selectProps) {
+ QName[] selectProps,
+ NamespaceResolver resolver) {
this.uuids = uuids;
this.itemMgr = itemMgr;
this.selectProps = selectProps;
+ this.resolver = resolver;
}
/**
@@ -50,7 +56,8 @@
*/
public PropertyIterator getProperties() throws RepositoryException {
return new PropertyIteratorImpl(selectProps,
- new NodeIteratorImpl(itemMgr, uuids));
+ new NodeIteratorImpl(itemMgr, uuids),
+ resolver);
}
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java Thu Jan 20 07:10:22 2005
@@ -23,6 +23,7 @@
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.ItemManager;
+import org.apache.jackrabbit.core.QName;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
@@ -205,7 +206,7 @@
}
Hits executeQuery(Query query,
- String[] orderProps,
+ QName[] orderProps,
boolean[] orderSpecs) throws IOException {
try {
readWriteLock.readLock().acquire();
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java Thu Jan 20 07:10:22 2005
@@ -63,7 +63,7 @@
private Pattern createRegexp(String likePattern) {
// - escape all non alphabetic characters
// - escape constructs like \<alphabetic char> into \\<alphabetic char>
- // - replace non escaped ? _ * % into . and .*
+ // - replace non escaped _ % into . and .*
StringBuffer regexp = new StringBuffer();
boolean escaped = false;
for (int i = 0; i < likePattern.length(); i++) {
@@ -88,11 +88,9 @@
escaped = false;
} else {
switch (likePattern.charAt(i)) {
- case '?':
case '_':
regexp.append('.');
break;
- case '*':
case '%':
regexp.append(".*");
break;
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTIdentifier.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTIdentifier.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTIdentifier.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTIdentifier.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTIdentifier.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTIdentifier.java Thu Jan 20 07:10:22 2005
@@ -16,9 +16,11 @@
*/
package org.apache.jackrabbit.core.search.sql;
+import org.apache.jackrabbit.core.QName;
+
public class ASTIdentifier extends SimpleNode {
- private String name;
+ private QName name;
public ASTIdentifier(int id) {
super(id);
@@ -28,11 +30,11 @@
super(p, id);
}
- public void setName(String name) {
+ public void setName(QName name) {
this.name = name;
}
- public String getName() {
+ public QName getName() {
return name;
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTPredicate.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTPredicate.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTPredicate.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTPredicate.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTPredicate.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/ASTPredicate.java Thu Jan 20 07:10:22 2005
@@ -16,16 +16,20 @@
*/
package org.apache.jackrabbit.core.search.sql;
+import org.apache.jackrabbit.core.QName;
+
public class ASTPredicate extends SimpleNode {
private int operationType;
private boolean negate = false;
- private String identifier;
+ private QName identifier;
private String identifierOperand;
+ private String escapeString;
+
public ASTPredicate(int id) {
super(id);
}
@@ -50,11 +54,11 @@
return this.negate;
}
- public void setIdentifier(String identifier) {
+ public void setIdentifier(QName identifier) {
this.identifier = identifier;
}
- public String getIdentifier() {
+ public QName getIdentifier() {
return identifier;
}
@@ -64,6 +68,14 @@
public String getIdentifierOperand() {
return identifierOperand;
+ }
+
+ public void setEscapeString(String esc) {
+ this.escapeString = esc;
+ }
+
+ public String getEscapeString() {
+ return escapeString;
}
/** Accept the visitor. **/
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java Thu Jan 20 07:10:22 2005
@@ -33,6 +33,9 @@
import org.apache.jackrabbit.core.QName;
import org.apache.jackrabbit.core.NamespaceRegistryImpl;
import org.apache.jackrabbit.core.NoPrefixDeclaredException;
+import org.apache.jackrabbit.core.IllegalNameException;
+import org.apache.jackrabbit.core.UnknownPrefixException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
import org.apache.log4j.Logger;
import javax.jcr.query.InvalidQueryException;
@@ -60,7 +63,7 @@
/**
* QName for jcr:path
*/
- private static final QName JCR_PATH = new QName(NamespaceRegistryImpl.NS_JCR_URI, "path");
+ static final QName JCR_PATH = new QName(NamespaceRegistryImpl.NS_JCR_URI, "path");
/** The root node of the sql query syntax tree */
private final ASTQuery stmt;
@@ -68,27 +71,25 @@
/** The root query node */
private QueryRootNode root;
+ /** To resolve QNames */
+ private NamespaceResolver resolver;
+
/** Query node to gather the constraints defined in the WHERE clause */
private final AndQueryNode constraintNode = new AndQueryNode(null);
- /**
- * The resolved jcr:path QName using the NamespaceResolver passed in the
- * constructor.
- */
- private final String jcrPathResolved;
+ public JCRSQLQueryBuilder() {
+ stmt = null;
+ }
/**
* Creates a new <code>JCRSQLQueryBuilder</code>.
* @param statement the root node of the SQL syntax tree.
* @param resolver a namespace resolver to use for names in the
* <code>statement</code>.
- * @throws NoPrefixDeclaredException if a prefix in the statement cannot
- * be resolved.
*/
- private JCRSQLQueryBuilder(ASTQuery statement, NamespaceResolver resolver)
- throws NoPrefixDeclaredException {
+ private JCRSQLQueryBuilder(ASTQuery statement, NamespaceResolver resolver) {
this.stmt = statement;
- jcrPathResolved = JCR_PATH.toJCRName(resolver);
+ this.resolver = resolver;
}
/**
@@ -101,16 +102,29 @@
public static QueryRootNode createQuery(String statement, NamespaceResolver resolver)
throws InvalidQueryException {
try {
- JCRSQLQueryBuilder builder = new JCRSQLQueryBuilder(JCRSQLParser.parse(statement), resolver);
+ JCRSQLQueryBuilder builder = new JCRSQLQueryBuilder(JCRSQLParser.parse(statement, resolver), resolver);
return builder.getRootNode();
} catch (ParseException e) {
throw new InvalidQueryException(e.getMessage());
- } catch (NoPrefixDeclaredException e) {
+ } catch (IllegalArgumentException e) {
throw new InvalidQueryException(e.getMessage());
}
}
/**
+ * Creates a String representation of the query node tree in SQL syntax.
+ * @param root the root of the query node tree.
+ * @param resolver to resolve QNames.
+ * @return a String representation of the query node tree.
+ * @throws InvalidQueryException if the query node tree cannot be converted
+ * into a String representation due to restrictions in SQL.
+ */
+ public static String toString(QueryRootNode root, NamespaceResolver resolver)
+ throws InvalidQueryException {
+ return QueryFormat.toString(root, resolver);
+ }
+
+ /**
* Parses the statement and returns the root node of the <code>QueryNode</code>
* tree.
* @return the root node of the <code>QueryNode</code> tree.
@@ -139,7 +153,7 @@
// use //* if no path has been set
PathQueryNode pathNode = root.getLocationNode();
if (pathNode.getPathSteps().length == 0) {
- pathNode.addPathStep(new LocationStepQueryNode(pathNode, "", false));
+ pathNode.addPathStep(new LocationStepQueryNode(pathNode, new QName("", ""), false));
pathNode.addPathStep(new LocationStepQueryNode(pathNode, null, true));
}
@@ -168,10 +182,16 @@
return node.childrenAccept(new DefaultParserVisitor() {
public Object visit(ASTIdentifier node, Object data) {
- // node is either primary or mixin node type
- NodeTypeQueryNode nodeType
- = new NodeTypeQueryNode(constraintNode, node.getName());
- constraintNode.addOperand(nodeType);
+ try {
+ if (!node.getName().equals(NodeTypeRegistry.NT_BASE.toJCRName(resolver))) {
+ // node is either primary or mixin node type
+ NodeTypeQueryNode nodeType
+ = new NodeTypeQueryNode(constraintNode, node.getName());
+ constraintNode.addOperand(nodeType);
+ }
+ } catch (NoPrefixDeclaredException e) {
+ throw new IllegalArgumentException("No prefix declared for name: " + node.getName());
+ }
return data;
}
}, root);
@@ -191,18 +211,18 @@
int type = node.getOperationType();
QueryNode predicateNode = null;
- String identifier = ((ASTIdentifier) node.children[0]).getName();
- if (identifier.equals(jcrPathResolved)) {
- if (node.children[1] instanceof ASTIdentifier) {
- // simply ignore, this is a join of a mixin node type
- } else {
- createPathQuery(((ASTLiteral) node.children[1]).getValue());
+ try {
+ QName identifier = ((ASTIdentifier) node.children[0]).getName();
+ if (identifier.equals(JCR_PATH)) {
+ if (node.children[1] instanceof ASTIdentifier) {
+ // simply ignore, this is a join of a mixin node type
+ } else {
+ createPathQuery(((ASTLiteral) node.children[1]).getValue());
+ }
+ // done
+ return data;
}
- // done
- return data;
- }
- try {
if (type == Constants.OPERATION_BETWEEN) {
AndQueryNode between = new AndQueryNode(parent);
RelationQueryNode rel = createRelationQueryNode(between,
@@ -222,11 +242,27 @@
} else if (type == Constants.OPERATION_GE
|| type == Constants.OPERATION_GT
|| type == Constants.OPERATION_LE
- || type == Constants.OPERATION_LIKE
|| type == Constants.OPERATION_LT
|| type == Constants.OPERATION_NE) {
predicateNode = createRelationQueryNode(parent,
identifier, type, (ASTLiteral) node.children[1]);
+ } else if (type == Constants.OPERATION_LIKE) {
+ ASTLiteral pattern = (ASTLiteral) node.children[1];
+ 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);
} else if (type == Constants.OPERATION_IN) {
OrQueryNode in = new OrQueryNode(parent);
for (int i = 1; i < node.children.length; i++) {
@@ -238,14 +274,12 @@
} else if (type == Constants.OPERATION_NULL) {
ASTLiteral star = new ASTLiteral(JCRSQLParserTreeConstants.JJTLITERAL);
star.setType(Constants.TYPE_STRING);
- star.setValue("*");
+ star.setValue("%");
predicateNode = createRelationQueryNode(parent,
identifier, Constants.OPERATION_LIKE, star);
}
- } catch (IllegalArgumentException e) {
- log.error(e.toString());
} catch (ArrayIndexOutOfBoundsException e) {
- log.error("Too few arguments");
+ throw new IllegalArgumentException("Too few arguments in predicate");
}
if (predicateNode != null) {
@@ -305,7 +339,9 @@
public Object visit(ASTOrderByClause node, Object data) {
QueryRootNode root = (QueryRootNode) data;
+ // list of QNames
final List identifiers = new ArrayList();
+
// collect identifiers
node.childrenAccept(new DefaultParserVisitor() {
public Object visit(ASTIdentifier node, Object data) {
@@ -314,7 +350,7 @@
}
}, root);
- String[] props = (String[]) identifiers.toArray(new String[identifiers.size()]);
+ QName[] props = (QName[]) identifiers.toArray(new QName[identifiers.size()]);
boolean[] orders = new boolean[props.length];
root.setOrderNode(new OrderQueryNode(root, props, orders));
return root;
@@ -339,7 +375,7 @@
* to its type. E.g. a malformed String representation of a date.
*/
private RelationQueryNode createRelationQueryNode(QueryNode parent,
- String propertyName,
+ QName propertyName,
int operationType,
ASTLiteral literal)
throws IllegalArgumentException {
@@ -359,8 +395,6 @@
long l = Long.parseLong(stringValue);
node = new RelationQueryNode(parent, propertyName, l, operationType);
} else if (literal.getType() == Constants.TYPE_STRING) {
- // @todo convert % and _ into * and ? if opType is LIKE
- // @todo take care of escaping!
node = new RelationQueryNode(parent, propertyName, stringValue, operationType);
} else if (literal.getType() == Constants.TYPE_TIMESTAMP) {
Calendar c = ISO8601.parse(stringValue);
@@ -390,7 +424,7 @@
if (names[i].length() == 0) {
if (i == 0) {
// root
- pathNode.addPathStep(new LocationStepQueryNode(pathNode, "", false));
+ pathNode.addPathStep(new LocationStepQueryNode(pathNode, new QName("", ""), false));
} else {
// descendant '//'
// FIXME this is not possible
@@ -403,26 +437,86 @@
// contains index
name = names[i].substring(0, idx);
String suffix = names[i].substring(idx);
- try {
- index = Integer.parseInt(suffix.substring(1, suffix.length() - 1));
- } catch (NumberFormatException e) {
- log.warn("Unable to parse index for path element: " + names[i]);
+ String indexStr = suffix.substring(1, suffix.length() - 1);
+ if (indexStr.equals("%")) {
+ // select all same name siblings
+ index = 0;
+ } else {
+ try {
+ index = Integer.parseInt(indexStr);
+ } catch (NumberFormatException e) {
+ log.warn("Unable to parse index for path element: " + names[i]);
+ }
}
} else {
// no index
name = names[i];
+ // in SQL this means index 1
+ index = 1;
}
if (name.equals("%")) {
name = null;
}
+ QName qName = null;
+ if (name != null) {
+ try {
+ qName = QName.fromJCRName(name, resolver);
+ } catch (IllegalNameException e) {
+ throw new IllegalArgumentException("Illegal name: " + name);
+ } catch (UnknownPrefixException e) {
+ throw new IllegalArgumentException("Unknown prefix: " + name);
+ }
+ }
// @todo how to specify descendant-or-self?
- LocationStepQueryNode step = new LocationStepQueryNode(pathNode, name, false);
+ LocationStepQueryNode step = new LocationStepQueryNode(pathNode, qName, false);
if (index > 0) {
step.setIndex(index);
}
pathNode.addPathStep(step);
}
}
+ }
+
+ /**
+ * Translates a pattern using the escape character <code>from</code> into
+ * a pattern using the escape character <code>to</code>.
+ * @param pattern the pattern to translate
+ * @param from the currently used escape character.
+ * @param to the new escape character to use.
+ * @return the new pattern using the escape character <code>to</code>.
+ */
+ private static String translateEscaping(String pattern, char from, char to) {
+ // if escape characters are the same OR pattern does not contain any
+ // escape characters -> simply return pattern as is.
+ if (from == to || (pattern.indexOf(from) < 0 && pattern.indexOf(to) < 0)) {
+ return pattern;
+ }
+ StringBuffer translated = new StringBuffer(pattern.length());
+ boolean escaped = false;
+ for (int i = 0; i < pattern.length(); i++) {
+ if (pattern.charAt(i) == from) {
+ if (escaped) {
+ translated.append(from);
+ escaped = false;
+ } else {
+ escaped = true;
+ }
+ } else if (pattern.charAt(i) == to) {
+ if (escaped) {
+ translated.append(to).append(to);
+ escaped = false;
+ } else {
+ translated.append(to).append(to);
+ }
+ } else {
+ if (escaped) {
+ translated.append(to);
+ escaped = false;
+ }
+ translated.append(pattern.charAt(i));
+ }
+ }
+ return translated.toString();
}
}
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java?view=auto&rev=125778
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java Thu Jan 20 07:10:22 2005
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.search.sql;
+
+import org.apache.jackrabbit.core.search.QueryNodeVisitor;
+import org.apache.jackrabbit.core.search.QueryRootNode;
+import org.apache.jackrabbit.core.search.OrQueryNode;
+import org.apache.jackrabbit.core.search.AndQueryNode;
+import org.apache.jackrabbit.core.search.NotQueryNode;
+import org.apache.jackrabbit.core.search.ExactQueryNode;
+import org.apache.jackrabbit.core.search.NodeTypeQueryNode;
+import org.apache.jackrabbit.core.search.RangeQueryNode;
+import org.apache.jackrabbit.core.search.TextsearchQueryNode;
+import org.apache.jackrabbit.core.search.PathQueryNode;
+import org.apache.jackrabbit.core.search.LocationStepQueryNode;
+import org.apache.jackrabbit.core.search.RelationQueryNode;
+import org.apache.jackrabbit.core.search.OrderQueryNode;
+import org.apache.jackrabbit.core.search.QueryNode;
+import org.apache.jackrabbit.core.search.Constants;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.NoPrefixDeclaredException;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+
+import javax.jcr.query.InvalidQueryException;
+import javax.jcr.util.ISO8601;
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * Implements the query node tree serialization into a String.
+ */
+class QueryFormat implements QueryNodeVisitor, Constants {
+
+ /** Will be used to resolve QNames */
+ private final NamespaceResolver resolver;
+
+ /** The String representation of the query node tree */
+ private String statement;
+
+ /** List of exception objects created while creating the SQL string */
+ private List exceptions = new ArrayList();
+
+ /** List of node types */
+ private List nodeTypes = new ArrayList();
+
+ private QueryFormat(QueryRootNode root, NamespaceResolver resolver)
+ throws InvalidQueryException {
+ this.resolver = resolver;
+ statement = root.accept(this, new StringBuffer()).toString();
+ if (exceptions.size() > 0) {
+ Exception e = (Exception) exceptions.get(0);
+ throw new InvalidQueryException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Creates a SQL <code>String</code> representation of the QueryNode tree
+ * argument <code>root</code>.
+ * @param root the query node tree.
+ * @param resolver to resolve QNames.
+ * @return the SQL string representation of the QueryNode tree.
+ * @throws InvalidQueryException the query node tree cannot be represented
+ * as a SQL <code>String</code>.
+ */
+ public static String toString(QueryRootNode root, NamespaceResolver resolver)
+ throws InvalidQueryException {
+ return new QueryFormat(root, resolver).toString();
+ }
+
+ /**
+ * Returns the string representation.
+ * @return the string representation.
+ */
+ public String toString() {
+ return statement;
+ }
+
+ //-------------< QueryNodeVisitor interface >-------------------------------
+
+ public Object visit(QueryRootNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ try {
+ sb.append("SELECT");
+
+ QName[] selectProps = node.getSelectProperties();
+ if (selectProps.length == 0) {
+ sb.append(" *");
+ } else {
+ String comma = "";
+ for (int i = 0; i < selectProps.length; i++) {
+ sb.append(comma).append(" ");
+ appendName(selectProps[i], resolver, sb);
+ comma = ",";
+ }
+ }
+
+ sb.append(" FROM");
+
+ // node type restrictions are within predicates of location nodes
+ // therefore we write the where clause first to a temp string to
+ // collect the node types.
+ StringBuffer tmp = new StringBuffer();
+ LocationStepQueryNode[] steps = node.getLocationNode().getPathSteps();
+ QueryNode[] predicates = steps[steps.length - 1].getPredicates();
+ String and = "";
+ for (int i = 0; i < predicates.length; i++) {
+ if (i == 0) {
+ tmp.append(" WHERE ");
+ }
+ tmp.append(and);
+ predicates[i].accept(this, tmp);
+ and = " AND ";
+ }
+
+ // node types have been collected by now
+ String comma = "";
+ int ntCount = 0;
+ for (Iterator it = nodeTypes.iterator(); it.hasNext(); ntCount++) {
+ QName nt = (QName) it.next();
+ sb.append(comma).append(" ");
+ appendName(nt, resolver, sb);
+ comma = ",";
+ }
+
+ if (ntCount == 0) {
+ sb.append(" ");
+ sb.append(NodeTypeRegistry.NT_BASE.toJCRName(resolver));
+ }
+
+ // append WHERE clause
+ sb.append(tmp.toString());
+
+ if (steps.length == 2
+ && steps[1].getIncludeDescendants()
+ && steps[1].getNameTest() == null) {
+ // then this query selects all paths
+ } else {
+ if (predicates.length > 0) {
+ sb.append(" AND ");
+ } else {
+ sb.append(" WHERE ");
+ }
+ node.getLocationNode().accept(this, sb);
+ }
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+
+ if (node.getOrderNode() != null) {
+ node.getOrderNode().accept(this, sb);
+ }
+
+ return sb;
+ }
+
+ public Object visit(OrQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ boolean bracket = false;
+ if (node.getParent() instanceof LocationStepQueryNode
+ || node.getParent() instanceof AndQueryNode
+ || node.getParent() instanceof NotQueryNode) {
+ bracket = true;
+ }
+ if (bracket) {
+ sb.append("(");
+ }
+ String or = "";
+ QueryNode[] operands = node.getOperands();
+ for (int i = 0; i < operands.length; i++) {
+ sb.append(or);
+ operands[i].accept(this, sb);
+ or = " OR ";
+ }
+ if (bracket) {
+ sb.append(")");
+ }
+ return sb;
+ }
+
+ public Object visit(AndQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ boolean bracket = false;
+ if (node.getParent() instanceof NotQueryNode) {
+ bracket = true;
+ }
+ if (bracket) {
+ sb.append("(");
+ }
+ String and = "";
+ QueryNode[] operands = node.getOperands();
+ for (int i = 0; i < operands.length; i++) {
+ sb.append(and);
+ int len = sb.length();
+ operands[i].accept(this, sb);
+ // check if something has been written at all
+ // might have been a node type query node
+ if (sb.length() - len > 0) {
+ and = " AND ";
+ } else {
+ and = "";
+ }
+ }
+ if (bracket) {
+ sb.append(")");
+ }
+ return sb;
+ }
+
+ public Object visit(NotQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ QueryNode[] operands = node.getOperands();
+ if (operands.length > 0) {
+ sb.append("NOT ");
+ operands[0].accept(this, sb);
+ }
+ return sb;
+ }
+
+ public Object visit(ExactQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ try {
+ appendName(node.getPropertyName(), resolver, sb);
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ sb.append("='").append(node.getValue()).append("'");
+ return sb;
+ }
+
+ public Object visit(NodeTypeQueryNode node, Object data) {
+ nodeTypes.add(node.getValue());
+ return data;
+ }
+
+ public Object visit(RangeQueryNode node, Object data) {
+ return data;
+ }
+
+ public Object visit(TextsearchQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ // escape quote
+ String query = node.getQuery().replaceAll("'", "''");
+ sb.append("CONTAINS('").append(query).append("')");
+ return sb;
+ }
+
+ public Object visit(PathQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ try {
+ sb.append(JCRSQLQueryBuilder.JCR_PATH.toJCRName(resolver));
+ sb.append(" LIKE '");
+ LocationStepQueryNode[] steps = node.getPathSteps();
+ for (int i = 0; i < steps.length; i++) {
+ if (steps[i].getNameTest() == null
+ || steps[i].getNameTest().getLocalName().length() > 0) {
+ sb.append('/');
+ }
+ steps[i].accept(this, sb);
+ }
+ sb.append('\'');
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ return sb;
+ }
+
+ public Object visit(LocationStepQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ if (node.getNameTest() == null) {
+ sb.append("%");
+ } else {
+ if (node.getNameTest().getLocalName().length() > 0) {
+ try {
+ sb.append(node.getNameTest().toJCRName(resolver));
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ if (node.getIndex() == 0) {
+ sb.append("[%]");
+ } else if (node.getIndex() == 1) {
+ // do nothing
+ } else {
+ sb.append('[').append(node.getIndex()).append(']');
+ }
+ } else {
+ // empty name test indicates root node
+ }
+ }
+ return sb;
+ }
+
+ public Object visit(RelationQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ try {
+ appendName(node.getProperty(), resolver, sb);
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+
+ if (node.getOperation() == OPERATION_EQ) {
+ sb.append(" = ");
+ } else if (node.getOperation() == OPERATION_GE) {
+ sb.append(" >= ");
+ } else if (node.getOperation() == OPERATION_GT) {
+ sb.append(" > ");
+ } else if (node.getOperation() == OPERATION_LE) {
+ sb.append(" <= ");
+ } else if (node.getOperation() == OPERATION_LIKE) {
+ sb.append(" LIKE ");
+ } else if (node.getOperation() == OPERATION_LT) {
+ sb.append(" < ");
+ } else if (node.getOperation() == OPERATION_NE) {
+ sb.append(" <> ");
+ } else {
+ exceptions.add(new InvalidQueryException("Invalid operation: " + node.getOperation()));
+ }
+
+
+ if (node.getType() == TYPE_LONG) {
+ sb.append(node.getLongValue());
+ } else if (node.getType() == TYPE_DOUBLE) {
+ sb.append(node.getDoubleValue());
+ } else if (node.getType() == TYPE_STRING) {
+ sb.append("'").append(node.getStringValue().replaceAll("'", "''")).append("'");
+ } else if (node.getType() == TYPE_DATE || node.getType() == TYPE_TIMESTAMP) {
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ cal.setTime(node.getDateValue());
+ sb.append("TIMESTAMP '").append(ISO8601.format(cal)).append("'");
+ } else {
+ exceptions.add(new InvalidQueryException("Invalid type: " + node.getType()));
+ }
+
+ if (node.getOperation() == OPERATION_LIKE && node.getStringValue().indexOf('\\') > -1) {
+ sb.append(" ESCAPE '\\'");
+ }
+
+ return sb;
+ }
+
+ public Object visit(OrderQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ sb.append(" ORDER BY");
+ QName[] properties = node.getOrderByProperties();
+ if (properties.length > 0) {
+ try {
+ String comma = "";
+ for (int i = 0; i < properties.length; i++) {
+ sb.append(comma).append(" ");
+ appendName(properties[i], resolver, sb);
+ if (!node.isAscending(i)) {
+ sb.append(" DESC");
+ }
+ comma = ",";
+ }
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ } else {
+ sb.append(" SCORE");
+ }
+ return sb;
+ }
+
+ //------------------------< internal >--------------------------------------
+
+ /**
+ * Appends the <code>name</code> to the <code>StringBuffer</code>
+ * <code>b</code> using the <code>NamespaceResolver</code>
+ * <code>resolver</code>. The <code>name</code> is put in double quotes
+ * if the local part of <code>name</code> contains a space character.
+ * @param name the <code>QName</code> to print.
+ * @param resolver to resolve <code>name</code>.
+ * @param b where to output the <code>name</code>.
+ * @throws NoPrefixDeclaredException if <code>name</code> contains a uri
+ * that is not declared in <code>resolver</code>.
+ */
+ private static void appendName(QName name,
+ NamespaceResolver resolver,
+ StringBuffer b)
+ throws NoPrefixDeclaredException {
+ boolean quote = name.getLocalName().indexOf(' ') > -1;
+ if (quote) {
+ b.append('"');
+ }
+ b.append(name.toJCRName(resolver));
+ if (quote) {
+ b.append('"');
+ }
+ }
+}
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/ISO9075.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/ISO9075.java?view=auto&rev=125778
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/ISO9075.java Thu Jan 20 07:10:22 2005
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.search.xpath;
+
+import org.apache.jackrabbit.core.QName;
+import org.apache.xerces.util.XMLChar;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Implements the encode and decode routines as specified for XML name to SQL
+ * identifier conversion in ISO 9075-14:2003.<br/>
+ * If a character <code>c</code> is not valid at a certain position in an XML 1.0
+ * Name it is encoded in the form: '_x' + hexValueOf(c) + '_'
+ * todo or is it NCName
+ * <p/>
+ * Note that only the local part of a {@link org.apache.jackrabbit.core.QName}
+ * is encoded / decoded. A URI namespace will always be valid and does not
+ * need encoding.
+ */
+public class ISO9075 {
+
+ /** Pattern on an encoded character */
+ private static Pattern ENCODE_PATTERN = Pattern.compile("_x\\p{XDigit}{4}_");
+
+ /** Padding characters */
+ private static char[] PADDING = new char[] {'0', '0', '0'};
+
+ /**
+ * Encodes the local part of <code>name</code> as specified in ISO 9075.
+ * @param name the <code>QName</code> to encode.
+ * @return the encoded <code>QName</code> or <code>name</code> if it does
+ * not need encoding.
+ */
+ public static QName encode(QName name) {
+ String encoded = encode(name.getLocalName());
+ if (encoded == name.getLocalName()) {
+ return name;
+ } else {
+ return new QName(name.getNamespaceURI(), encoded);
+ }
+ }
+
+ /**
+ * Encodes <code>name</code> as specified in ISO 9075.
+ * @param name the <code>String</code> to encode.
+ * @return the encoded <code>String</code> or <code>name</code> if it does
+ * not need encoding.
+ */
+ public static String encode(String name) {
+ // quick check for root node name
+ if (name.length() == 0) {
+ return name;
+ }
+ if (XMLChar.isValidName(name) && name.indexOf("_x") < 0) {
+ // already valid
+ return name;
+ } else {
+ // encode
+ StringBuffer encoded = new StringBuffer();
+ for (int i = 0; i < name.length(); i++) {
+ if (i == 0) {
+ // first character of name
+ if (XMLChar.isNameStart(name.charAt(i))) {
+ if (name.charAt(i) == '_'
+ && name.length() > (i + 1)
+ && name.charAt(i + 1) == 'x') {
+ // '_x' must be encoded
+ encode('_', encoded);
+ } else {
+ encoded.append(name.charAt(i));
+ }
+ } else {
+ // not valid as first character -> encode
+ encode(name.charAt(i), encoded);
+ }
+ } else if (!XMLChar.isName(name.charAt(i))) {
+ encode(name.charAt(i), encoded);
+ } else {
+ if (name.charAt(i) == '_'
+ && name.length() > (i + 1)
+ && name.charAt(i + 1) == 'x') {
+ // '_x' must be encoded
+ encode('_', encoded);
+ } else {
+ encoded.append(name.charAt(i));
+ }
+ }
+ }
+ return encoded.toString();
+ }
+ }
+
+ /**
+ * Decodes the <code>name</code>.
+ * @param name the <code>QName</code> to decode.
+ * @return the decoded <code>QName</code>.
+ */
+ public static QName decode(QName name) {
+ String decoded = decode(name.getLocalName());
+ if (decoded == name.getLocalName()) {
+ return name;
+ } else {
+ return new QName(name.getNamespaceURI(), decoded.toString());
+ }
+ }
+
+ /**
+ * Decodes the <code>name</code>.
+ * @param name the <code>String</code> to decode.
+ * @return the decoded <code>String</code>.
+ */
+ public static String decode(String name) {
+ // quick check
+ if (name.indexOf("_x") < 0) {
+ // not encoded
+ return name;
+ }
+ StringBuffer decoded = new StringBuffer();
+ Matcher m = ENCODE_PATTERN.matcher(name);
+ while (m.find()) {
+ m.appendReplacement(decoded, Character.toString((char) Integer.parseInt(m.group().substring(2, 6), 16)));
+ }
+ m.appendTail(decoded);
+ return decoded.toString();
+ }
+
+ //-------------------------< internal >-------------------------------------
+
+ /**
+ * Encodes the character <code>c</code> as a String in the following form:
+ * <code>"_x" + hex value of c + "_"</code>. Where the hex value has always
+ * four digits with possibly leading zeros.
+ * <p/>
+ * Example: ' ' (the space character) is encoded to: _x0020_
+ * @param c the character to encode
+ * @param b the encoded character is appended to <code>StringBuffer</code>
+ * <code>b</code>.
+ */
+ private static void encode(char c, StringBuffer b) {
+ b.append("_x");
+ String hex = Integer.toHexString(c);
+ b.append(PADDING, 0, 4 - hex.length());
+ b.append(hex);
+ b.append("_");
+ }
+
+}
Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/QueryFormat.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/QueryFormat.java?view=auto&rev=125778
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/QueryFormat.java Thu Jan 20 07:10:22 2005
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.search.xpath;
+
+import org.apache.jackrabbit.core.search.QueryNodeVisitor;
+import org.apache.jackrabbit.core.search.QueryRootNode;
+import org.apache.jackrabbit.core.search.OrQueryNode;
+import org.apache.jackrabbit.core.search.AndQueryNode;
+import org.apache.jackrabbit.core.search.NotQueryNode;
+import org.apache.jackrabbit.core.search.ExactQueryNode;
+import org.apache.jackrabbit.core.search.NodeTypeQueryNode;
+import org.apache.jackrabbit.core.search.RangeQueryNode;
+import org.apache.jackrabbit.core.search.TextsearchQueryNode;
+import org.apache.jackrabbit.core.search.PathQueryNode;
+import org.apache.jackrabbit.core.search.LocationStepQueryNode;
+import org.apache.jackrabbit.core.search.RelationQueryNode;
+import org.apache.jackrabbit.core.search.OrderQueryNode;
+import org.apache.jackrabbit.core.search.QueryNode;
+import org.apache.jackrabbit.core.search.Constants;
+import org.apache.jackrabbit.core.NamespaceResolver;
+import org.apache.jackrabbit.core.NoPrefixDeclaredException;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+
+import javax.jcr.query.InvalidQueryException;
+import javax.jcr.util.ISO8601;
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implements the query node tree serialization into a String.
+ */
+class QueryFormat implements QueryNodeVisitor, Constants {
+
+ /** Will be used to resolve QNames */
+ private final NamespaceResolver resolver;
+
+ /** The String representation of the query node tree */
+ private String statement;
+
+ /** List of exception objects created while creating the XPath string */
+ private List exceptions = new ArrayList();
+
+ private QueryFormat(QueryRootNode root, NamespaceResolver resolver)
+ throws InvalidQueryException {
+ this.resolver = resolver;
+ statement = root.accept(this, new StringBuffer()).toString();
+ if (exceptions.size() > 0) {
+ Exception e = (Exception) exceptions.get(0);
+ throw new InvalidQueryException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Creates a XPath <code>String</code> representation of the QueryNode tree
+ * argument <code>root</code>.
+ * @param root the query node tree.
+ * @param resolver to resolve QNames.
+ * @return the XPath string representation of the QueryNode tree.
+ * @throws InvalidQueryException the query node tree cannot be represented
+ * as a XPath <code>String</code>.
+ */
+ public static String toString(QueryRootNode root, NamespaceResolver resolver)
+ throws InvalidQueryException {
+ return new QueryFormat(root, resolver).toString();
+ }
+
+ /**
+ * Returns the string representation.
+ * @return the string representation.
+ */
+ public String toString() {
+ return statement;
+ }
+
+ //-------------< QueryNodeVisitor interface >-------------------------------
+
+ public Object visit(QueryRootNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ node.getLocationNode().accept(this, data);
+ if (node.getOrderNode() != null) {
+ node.getOrderNode().accept(this, data);
+ }
+ QName[] selectProps = node.getSelectProperties();
+ if (selectProps.length > 0) {
+ sb.append('/');
+ boolean union = selectProps.length > 1;
+ if (union) {
+ sb.append('(');
+ }
+ String pipe = "";
+ for (int i = 0; i < selectProps.length; i++) {
+ try {
+ sb.append(pipe);
+ sb.append('@');
+ sb.append(ISO9075.encode(selectProps[i]).toJCRName(resolver));
+ pipe = "|";
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ }
+ if (union) {
+ sb.append(')');
+ }
+ }
+ return data;
+ }
+
+ public Object visit(OrQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ boolean bracket = false;
+ if (node.getParent() instanceof AndQueryNode) {
+ bracket = true;
+ }
+ if (bracket) {
+ sb.append("(");
+ }
+ String or = "";
+ QueryNode[] operands = node.getOperands();
+ for (int i = 0; i < operands.length; i++) {
+ sb.append(or);
+ operands[i].accept(this, sb);
+ or = " or ";
+ }
+ if (bracket) {
+ sb.append(")");
+ }
+ return sb;
+ }
+
+ public Object visit(AndQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ String and = "";
+ QueryNode[] operands = node.getOperands();
+ for (int i = 0; i < operands.length; i++) {
+ sb.append(and);
+ operands[i].accept(this, sb);
+ and = " and ";
+ }
+ return sb;
+ }
+
+ public Object visit(NotQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ QueryNode[] operands = node.getOperands();
+ if (operands.length > 0) {
+ try {
+ sb.append(XPathQueryBuilder.FN_NOT_10.toJCRName(resolver));
+ sb.append("(");
+ operands[0].accept(this, sb);
+ sb.append(")");
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ }
+ return sb;
+ }
+
+ public Object visit(ExactQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ sb.append("@");
+ try {
+ sb.append(ISO9075.encode(node.getPropertyName()).toJCRName(resolver));
+ sb.append("='").append(node.getValue().toJCRName(resolver));
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ sb.append("'");
+ return sb;
+ }
+
+ public Object visit(NodeTypeQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ try {
+ sb.append("@");
+ sb.append(NodeTypeRegistry.JCR_PRIMARY_TYPE.toJCRName(resolver));
+ sb.append("='").append(node.getValue().toJCRName(resolver));
+ sb.append("'");
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ return sb;
+ }
+
+ public Object visit(RangeQueryNode node, Object data) {
+ return data;
+ }
+
+ public Object visit(TextsearchQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ try {
+ sb.append(XPathQueryBuilder.JCRFN_CONTAINS.toJCRName(resolver));
+ sb.append("('");
+ sb.append(node.getQuery().replaceAll("'", "''"));
+ sb.append("')");
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ return sb;
+ }
+
+ public Object visit(PathQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ LocationStepQueryNode[] steps = node.getPathSteps();
+ for (int i = 0; i < steps.length; i++) {
+ if (steps[i].getNameTest() == null
+ || steps[i].getNameTest().getLocalName().length() > 0) {
+ sb.append('/');
+ }
+ steps[i].accept(this, sb);
+ }
+ return sb;
+ }
+
+ public Object visit(LocationStepQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ if (node.getIncludeDescendants()) {
+ sb.append('/');
+ }
+ if (node.getNameTest() == null) {
+ sb.append("*");
+ } else {
+ try {
+ sb.append(ISO9075.encode(node.getNameTest()).toJCRName(resolver));
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ }
+ if (node.getIndex() > 0) {
+ sb.append('[').append(node.getIndex()).append(']');
+ }
+ QueryNode[] predicates = node.getPredicates();
+ for (int i = 0; i < predicates.length; i++) {
+ sb.append('[');
+ predicates[i].accept(this, sb);
+ sb.append(']');
+ }
+ return sb;
+ }
+
+ public Object visit(RelationQueryNode node, Object data) {
+ StringBuffer sb = (StringBuffer) data;
+ try {
+
+ int propIdx = sb.length();
+ sb.append("@" + ISO9075.encode(node.getProperty()).toJCRName(resolver));
+
+ if (node.getOperation() == OPERATION_EQ) {
+ sb.append(" = ");
+ } else if (node.getOperation() == OPERATION_GE) {
+ sb.append(" >= ");
+ } else if (node.getOperation() == OPERATION_GT) {
+ sb.append(" > ");
+ } else if (node.getOperation() == OPERATION_LE) {
+ sb.append(" <= ");
+ } else if (node.getOperation() == OPERATION_LIKE) {
+ sb.insert(propIdx, XPathQueryBuilder.JCRFN_LIKE.toJCRName(resolver) + "(");
+ sb.append(",");
+ } else if (node.getOperation() == OPERATION_LT) {
+ sb.append(" < ");
+ } else if (node.getOperation() == OPERATION_NE) {
+ sb.append(" != ");
+ } else {
+ exceptions.add(new InvalidQueryException("Invalid operation: " + node.getOperation()));
+ }
+
+ if (node.getType() == TYPE_LONG) {
+ sb.append(node.getLongValue());
+ } else if (node.getType() == TYPE_DOUBLE) {
+ sb.append(node.getDoubleValue());
+ } else if (node.getType() == TYPE_STRING) {
+ sb.append("'").append(node.getStringValue().replaceAll("'", "''")).append("'");
+ } else if (node.getType() == TYPE_DATE || node.getType() == TYPE_TIMESTAMP) {
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ cal.setTime(node.getDateValue());
+ sb.append(XPathQueryBuilder.XS_DATETIME.toJCRName(resolver));
+ sb.append("('").append(ISO8601.format(cal)).append("')");
+ } else {
+ exceptions.add(new InvalidQueryException("Invalid type: " + node.getType()));
+ }
+
+ if (node.getOperation() == OPERATION_LIKE) {
+ sb.append(")");
+ }
+ } catch (NoPrefixDeclaredException e) {
+ exceptions.add(e);
+ }
+ return sb;
+ }
+
+ public Object visit(OrderQueryNode node, Object data) {
+ // @todo implement
+ return data;
+ }
+}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java&r1=125777&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java Thu Jan 20 07:10:22 2005
@@ -25,10 +25,15 @@
import org.apache.jackrabbit.core.search.OrQueryNode;
import org.apache.jackrabbit.core.search.RelationQueryNode;
import org.apache.jackrabbit.core.search.NotQueryNode;
+import org.apache.jackrabbit.core.search.TextsearchQueryNode;
+import org.apache.jackrabbit.core.search.NodeTypeQueryNode;
import org.apache.jackrabbit.core.NamespaceResolver;
import org.apache.jackrabbit.core.QName;
import org.apache.jackrabbit.core.SearchManager;
import org.apache.jackrabbit.core.NoPrefixDeclaredException;
+import org.apache.jackrabbit.core.IllegalNameException;
+import org.apache.jackrabbit.core.UnknownPrefixException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.util.ISO8601;
@@ -43,13 +48,19 @@
public class XPathQueryBuilder implements XPathVisitor {
/** QName for 'fn:not' */
- private static final QName FN_NOT = new QName(SearchManager.NS_FN_URI, "not");
+ static final QName FN_NOT = new QName(SearchManager.NS_FN_URI, "not");
/** QName for 'not' as defined in XPath 1.0 (no prefix) */
- private static final QName FN_NOT_10 = new QName("", "not");
+ static final QName FN_NOT_10 = new QName("", "not");
/** QName for xs:dateTime */
- private static final QName XS_DATETIME = new QName(SearchManager.NS_XS_URI, "dateTime");
+ static final QName XS_DATETIME = new QName(SearchManager.NS_XS_URI, "dateTime");
+
+ /** QName for jcrfn:like */
+ static final QName JCRFN_LIKE = new QName(SearchManager.NS_JCRFN_URI, "like");
+
+ /** QName for jcrfn:contains */
+ static final QName JCRFN_CONTAINS = new QName(SearchManager.NS_JCRFN_URI, "contains");
/** String constant for operator 'eq' */
private static final String OP_EQ = "eq";
@@ -140,8 +151,8 @@
QueryRootNode root = new XPathQueryBuilder(statement, resolver).getRootNode();
LocationStepQueryNode[] steps = root.getLocationNode().getPathSteps();
if (steps.length > 0) {
- String nameTest = steps[0].getNameTest();
- if (nameTest == null || nameTest.length() > 0) {
+ QName nameTest = steps[0].getNameTest();
+ if (nameTest == null || nameTest.getLocalName().length() > 0) {
throw new InvalidQueryException("Path must be absolute: " + statement);
}
}
@@ -149,6 +160,19 @@
}
/**
+ * Creates a String representation of the query node tree in XPath syntax.
+ * @param root the root of the query node tree.
+ * @param resolver to resolve QNames.
+ * @return a String representation of the query node tree.
+ * @throws InvalidQueryException if the query node tree cannot be converted
+ * into a String representation due to restrictions in XPath.
+ */
+ public static String toString(QueryRootNode root, NamespaceResolver resolver)
+ throws InvalidQueryException {
+ return QueryFormat.toString(root, resolver);
+ }
+
+ /**
* Returns the root node of the <code>QueryNode</code> tree.
* @return the root node of the <code>QueryNode</code> tree.
*/
@@ -172,14 +196,13 @@
data = createPathQueryNode(node);
break;
case XPathTreeConstants.JJTROOT:
- ((PathQueryNode) data).addPathStep(new LocationStepQueryNode((QueryNode) data, "", false));
+ ((PathQueryNode) data).addPathStep(new LocationStepQueryNode((QueryNode) data, new QName("", ""), false));
break;
case XPathTreeConstants.JJTROOTDESCENDANTS:
- ((PathQueryNode) data).addPathStep(new LocationStepQueryNode((QueryNode) data, "", false));
+ ((PathQueryNode) data).addPathStep(new LocationStepQueryNode((QueryNode) data, new QName("", ""), false));
break;
case XPathTreeConstants.JJTSTEPEXPR:
if (isAttributeAxis(node)) {
- // @todo do what?
// traverse
node.childrenAccept(this, data);
} else {
@@ -192,7 +215,8 @@
break;
case XPathTreeConstants.JJTNAMETEST:
if (data instanceof LocationStepQueryNode
- || data instanceof RelationQueryNode) {
+ || data instanceof RelationQueryNode
+ || data instanceof PathQueryNode) {
createNameTest(node, (QueryNode) data);
} else {
// traverse
@@ -276,10 +300,21 @@
if (node.jjtGetNumChildren() > 0) {
SimpleNode child = (SimpleNode) node.jjtGetChild(0);
if (child.getId() == XPathTreeConstants.JJTQNAME) {
- if (queryNode instanceof LocationStepQueryNode) {
- ((LocationStepQueryNode) queryNode).setNameTest(child.getValue());
- } else if (queryNode instanceof RelationQueryNode) {
- ((RelationQueryNode) queryNode).setProperty(child.getValue());
+ try {
+ if (queryNode instanceof LocationStepQueryNode) {
+ QName name = ISO9075.decode(QName.fromJCRName(child.getValue(), resolver));
+ ((LocationStepQueryNode) queryNode).setNameTest(name);
+ } else if (queryNode instanceof RelationQueryNode) {
+ QName name = ISO9075.decode(QName.fromJCRName(child.getValue(), resolver));
+ ((RelationQueryNode) queryNode).setProperty(name);
+ } else if (queryNode instanceof PathQueryNode) {
+ QName name = ISO9075.decode(QName.fromJCRName(child.getValue(), resolver));
+ root.addSelectProperty(name);
+ }
+ } catch (IllegalNameException e) {
+ exceptions.add(new InvalidQueryException("Illegal name: " + child.getValue()));
+ } catch (UnknownPrefixException e) {
+ exceptions.add(new InvalidQueryException("Unknown prefix: " + child.getValue()));
}
} else if (child.getId() == XPathTreeConstants.JJTSTAR) {
if (queryNode instanceof LocationStepQueryNode) {
@@ -324,7 +359,27 @@
// traverse
node.childrenAccept(this, rqn);
- queryNode.addOperand(rqn);
+
+ // if property name is jcr:primaryType treat special
+ if (rqn.getProperty().equals(NodeTypeRegistry.JCR_PRIMARY_TYPE)) {
+ if (rqn.getType() == RelationQueryNode.TYPE_STRING) {
+ try {
+ QName ntName = QName.fromJCRName(rqn.getStringValue(), resolver);
+ NodeTypeQueryNode ntNode = new NodeTypeQueryNode(queryNode, ntName);
+ queryNode.addOperand(ntNode);
+ } catch (IllegalNameException e) {
+ exceptions.add(new InvalidQueryException("Not a valid name: " + rqn.getStringValue()));
+ } catch (UnknownPrefixException e) {
+ exceptions.add(new InvalidQueryException("Unknown prefix in name: " + rqn.getStringValue()));
+ }
+ } else {
+ // value is not of type string
+ exceptions.add(new InvalidQueryException("Invalid type: jcr:primaryType must be a string"));
+ }
+ } else {
+ // property name is <> jcr:primaryType
+ queryNode.addOperand(rqn);
+ }
}
/**
@@ -380,6 +435,7 @@
if (queryNode instanceof NAryQueryNode) {
QueryNode not = new NotQueryNode(queryNode);
((NAryQueryNode) queryNode).addOperand(not);
+ // @todo is this needed?
queryNode = not;
// traverse
if (node.jjtGetNumChildren() == 2) {
@@ -415,6 +471,57 @@
} else {
// wrong number of arguments
exceptions.add(new InvalidQueryException("Wrong number of arguments for xs:dateTime"));
+ }
+ } else if (JCRFN_CONTAINS.toJCRName(resolver).equals(fName)) {
+ // check number of arguments
+ if (node.jjtGetNumChildren() == 2) {
+ SimpleNode literal = (SimpleNode) node.jjtGetChild(1).jjtGetChild(0);
+ if (queryNode instanceof NAryQueryNode) {
+ if (literal.getId() == XPathTreeConstants.JJTSTRINGLITERAL) {
+ String value = literal.getValue();
+ // strip quotes
+ value = value.substring(1, value.length() - 1);
+ TextsearchQueryNode contains = new TextsearchQueryNode(queryNode, value);
+ ((NAryQueryNode) queryNode).addOperand(contains);
+ } else {
+ exceptions.add(new InvalidQueryException("Wrong argument type for jcrfn:contains"));
+ }
+ } else {
+ exceptions.add(new InvalidQueryException("Unsupported location for function jcrfn:contains"));
+ }
+ } else {
+ // wrong number of arguments
+ exceptions.add(new InvalidQueryException("Wrong number of arguments for jcrfn:contains"));
+ }
+ } else if (JCRFN_LIKE.toJCRName(resolver).equals(fName)) {
+ // check number of arguments
+ if (node.jjtGetNumChildren() == 3) {
+ if (queryNode instanceof NAryQueryNode) {
+ RelationQueryNode like = new RelationQueryNode(queryNode, RelationQueryNode.OPERATION_LIKE);
+ ((NAryQueryNode) queryNode).addOperand(like);
+
+ // assign property name
+ node.jjtGetChild(1).jjtAccept(this, like);
+ // check property name
+ if (like.getProperty() == null) {
+ exceptions.add(new InvalidQueryException("Wrong first argument type for jcrfn:like"));
+ }
+
+ SimpleNode literal = (SimpleNode) node.jjtGetChild(2).jjtGetChild(0);
+ if (literal.getId() == XPathTreeConstants.JJTSTRINGLITERAL) {
+ String value = literal.getValue();
+ // strip quotes
+ value = value.substring(1, value.length() - 1);
+ like.setStringValue(value);
+ } else {
+ exceptions.add(new InvalidQueryException("Wrong second argument type for jcrfn:like"));
+ }
+ } else {
+ exceptions.add(new InvalidQueryException("Unsupported location for function jcrfn:like"));
+ }
+ } else {
+ // wrong number of arguments
+ exceptions.add(new InvalidQueryException("Wrong number of arguments for jcrfn:like"));
}
} else {
exceptions.add(new InvalidQueryException("Unsupported function: " + fName));
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/FulltextQueryTest.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/FulltextQueryTest.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/FulltextQueryTest.java&r1=125777&p2=incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/FulltextQueryTest.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/FulltextQueryTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/FulltextQueryTest.java Thu Jan 20 07:10:22 2005
@@ -25,18 +25,6 @@
*/
public class FulltextQueryTest extends AbstractQueryTest {
- public void testFulltextSimple() throws Exception {
- Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
- foo.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
-
- testRootNode.save();
-
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// TEXTSEARCH \"fox\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 1);
- }
-
public void testFulltextSimpleSQL1() throws Exception {
Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
foo.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
@@ -65,23 +53,6 @@
checkResult(result, 1);
}
- public void testFulltextMultiWord() throws Exception {
- Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"test text"});
- n.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
-
- n = testRootNode.addNode("node2", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"other text"});
- n.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
-
- testRootNode.save();
-
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// TEXTSEARCH \"fox test\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 1);
- }
-
public void testFulltextMultiWordSQL() throws Exception {
Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
n.setProperty("title", new String[]{"test text"});
@@ -101,23 +72,6 @@
checkResult(result, 1);
}
- public void testFulltextPhrase() throws Exception {
- Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"test text"});
- n.setProperty("mytext", new String[]{"the quick brown jumps fox over the lazy dog."});
-
- n = testRootNode.addNode("node2", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"other text"});
- n.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
-
- testRootNode.save();
-
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// TEXTSEARCH \"text 'fox jumps'\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 1);
- }
-
public void testFulltextPhraseSQL() throws Exception {
Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
n.setProperty("title", new String[]{"test text"});
@@ -137,23 +91,6 @@
checkResult(result, 1);
}
- public void testFulltextExclude() throws Exception {
- Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"test text"});
- n.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
-
- n = testRootNode.addNode("node2", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"other text"});
- n.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
-
- superuser.getRootNode().save();
-
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// TEXTSEARCH \"text 'fox jumps' -other\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 1);
- }
-
public void testFulltextExcludeSQL() throws Exception {
Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
n.setProperty("title", new String[]{"test text"});
@@ -173,23 +110,6 @@
checkResult(result, 1);
}
- public void testFulltextOr() throws Exception {
- Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"test text"});
- n.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
-
- n = testRootNode.addNode("node2", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"other text"});
- n.setProperty("mytext", new String[]{"the quick brown fox jumps over the lazy dog."});
-
- testRootNode.save();
-
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// TEXTSEARCH \"'fox jumps' test OR other\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 2);
- }
-
public void testFulltextOrSQL() throws Exception {
Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
n.setProperty("title", new String[]{"test text"});
@@ -205,23 +125,6 @@
+ "\" WHERE \"jcr:path\" LIKE '" + testRoot + "/%"
+ "' AND CONTAINS('''fox jumps'' test OR other')";
Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
- QueryResult result = q.execute();
- checkResult(result, 2);
- }
-
- public void testFulltextIntercap() throws Exception {
- Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"tEst text"});
- n.setProperty("mytext", new String[]{"The quick brown Fox jumps over the lazy dog."});
-
- n = testRootNode.addNode("node2", NT_UNSTRUCTURED);
- n.setProperty("title", new String[]{"Other text"});
- n.setProperty("mytext", new String[]{"the quick brown FOX jumPs over the lazy dog."});
-
- testRootNode.save();
-
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// TEXTSEARCH \"'fox juMps' Test OR otheR\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
QueryResult result = q.execute();
checkResult(result, 2);
}
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java&r1=125777&p2=incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java Thu Jan 20 07:10:22 2005
@@ -26,32 +26,6 @@
*/
public class SelectClauseTest extends AbstractQueryTest {
- public void testSelect() throws RepositoryException {
- Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
- n.setProperty("myvalue", new String[]{"foo"});
- n = testRootNode.addNode("node2", NT_UNSTRUCTURED);
- n.setProperty("myvalue", new String[]{"bar"});
- n = testRootNode.addNode("node3", NT_UNSTRUCTURED);
- n.setProperty("yourvalue", new String[]{"foo"});
-
- testRootNode.save();
-
- String jcrql = "SELECT myvalue FROM * LOCATION " + testRoot + "//";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 2);
-
- jcrql = "SELECT myvalue FROM * LOCATION " + testRoot + "// WHERE yourvalue = \"foo\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 0);
-
- jcrql = "SELECT myvalue FROM *";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 2);
- }
-
public void testSelectSQL() throws RepositoryException {
Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
n.setProperty("myvalue", new String[]{"foo"});
@@ -81,37 +55,6 @@
checkResult(result, 2);
}
- public void testPropertyCount() throws RepositoryException {
- Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
- n.setProperty("myvalue", new String[]{"foo"});
- n = testRootNode.addNode("node2", NT_UNSTRUCTURED);
- n.setProperty("myvalue", new String[]{"bar"});
- n = testRootNode.addNode("node3", NT_UNSTRUCTURED);
- n.setProperty("yourvalue", new String[]{"foo"});
-
- testRootNode.save();
-
- String jcrql = "SELECT myvalue FROM * LOCATION " + testRoot + "//";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 2, 2);
-
- jcrql = "SELECT myvalue FROM * LOCATION " + testRoot + "// WHERE yourvalue = \"foo\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 0, 0);
-
- jcrql = "SELECT myvalue FROM *";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 2, 2);
-
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE myvalue LIKE \"*\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 2, 4);
- }
-
public void testPropertyCountSQL() throws RepositoryException {
Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
n.setProperty("myvalue", new String[]{"foo"});
@@ -146,23 +89,6 @@
q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 2, 4);
- }
-
- public void testSameNameSibling() throws RepositoryException {
- Node n = testRootNode.addNode("node", NT_UNSTRUCTURED);
- n.setProperty("myvalue", new String[]{"foo"});
- n = testRootNode.addNode("node", NT_UNSTRUCTURED);
- n.setProperty("myvalue", new String[]{"bar"});
- n = testRootNode.addNode("node", NT_UNSTRUCTURED);
- n.setProperty("yourvalue", new String[]{"foo"});
-
- testRootNode.save();
-
- String jcrql = "SELECT myvalue FROM * LOCATION " + testRoot + "/node";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 2, 2);
-
}
public void testSameNameSiblingSQL() throws RepositoryException {
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SimpleQueryTest.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SimpleQueryTest.java?view=diff&rev=125778&p1=incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SimpleQueryTest.java&r1=125777&p2=incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SimpleQueryTest.java&r2=125778
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SimpleQueryTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SimpleQueryTest.java Thu Jan 20 07:10:22 2005
@@ -27,46 +27,20 @@
public class SimpleQueryTest extends AbstractQueryTest {
- public void testSimpleQuery1() throws Exception {
- Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
- foo.setProperty("bla", new String[]{"bla"});
-
- testRootNode.save();
-
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "/foo WHERE bla=\"bla\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 1);
- }
-
public void testSimpleQuerySQL1() throws Exception {
Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
foo.setProperty("bla", new String[]{"bla"});
testRootNode.save();
- String sql = "SELECT * FROM \"" + NT_BASE
- + "\" WHERE \"jcr:path\" LIKE '" + testRoot + "/foo'"
+ String sql = "SELECT * FROM nt:base"
+ + " WHERE jcr:path LIKE '" + testRoot + "/foo'"
+ " AND bla = 'bla'";
Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 1);
}
- public void testSimpleQuery2() throws Exception {
- Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
- foo.setProperty("bla", new String[]{"bla"});
- Node bla = testRootNode.addNode("bla", NT_UNSTRUCTURED);
- bla.setProperty("bla", new String[]{"bla"});
-
- testRootNode.save();
-
- String jcrql = "SELECT * FROM nt:file LOCATION " + testRoot + "// WHERE bla=\"bla\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 0);
- }
-
public void testSimpleQuerySQL2() throws Exception {
Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
foo.setProperty("bla", new String[]{"bla"});
@@ -75,28 +49,14 @@
superuser.getRootNode().save();
- String sql = "SELECT * FROM \"nt:file\"" +
- " WHERE \"jcr:path\" LIKE '" + testRoot + "/%'"
+ String sql = "SELECT * FROM nt:file" +
+ " WHERE jcr:path LIKE '" + testRoot + "/%'"
+ " AND bla = 'bla'";
Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 0);
}
- public void testSimpleQuery3() throws Exception {
- Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
- foo.setProperty("bla", new String[]{"bla"});
- Node bla = testRootNode.addNode("bla", NT_UNSTRUCTURED);
- bla.setProperty("bla", new String[]{"bla"});
-
- testRootNode.save();
-
- String jcrql = "SELECT * FROM nt:unstructured LOCATION " + testRoot + "// WHERE bla=\"bla\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- QueryResult result = q.execute();
- checkResult(result, 2);
- }
-
public void testSimpleQuerySQL3() throws Exception {
Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
foo.setProperty("bla", new String[]{"bla"});
@@ -105,15 +65,15 @@
testRootNode.save();
- String sql = "SELECT * FROM \"nt:unstructured\"" +
- " WHERE \"jcr:path\" LIKE '" + testRoot + "/%'"
+ String sql = "SELECT * FROM nt:unstructured" +
+ " WHERE jcr:path LIKE '" + testRoot + "/%'"
+ " AND bla = 'bla'";
Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 2);
}
- public void testSimpleQuery4() throws Exception {
+ public void testSimpleQuerySQL4() throws Exception {
Node foo = testRootNode.addNode("foo", NT_UNSTRUCTURED);
foo.setProperty("bla", new String[]{"bla"});
Node bla = testRootNode.addNode("bla", NT_UNSTRUCTURED);
@@ -121,8 +81,8 @@
testRootNode.save();
- String jcrql = "SELECT * FROM nt:unstructured LOCATION " + testRoot + "/*";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String sql = "SELECT * FROM nt:unstructured WHERE jcr:path LIKE '" + testRoot + "/%'";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 2);
}
@@ -140,13 +100,13 @@
testRootNode.save();
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE birth > 1976-01-01T00:00:00.000+01:00";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND birth > TIMESTAMP '1976-01-01T00:00:00.000+01:00'";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 1);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE birth > 1975-01-01T00:00:00.000+01:00";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND birth > TIMESTAMP '1975-01-01T00:00:00.000+01:00'";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 2);
}
@@ -161,18 +121,18 @@
testRootNode.save();
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value > 0.1e-0";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value > 0.1e-0";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 1);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value > -0.1";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value > -0.1";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 2);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value > -1.5";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value > -1.5";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 3);
}
@@ -187,18 +147,18 @@
testRootNode.save();
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value > 0";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value > 0";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 1);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value > -1";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value > -1";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 2);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value > -2";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value > -2";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 3);
}
@@ -213,28 +173,18 @@
testRootNode.save();
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"ping\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'ping'";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 1);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"?ing\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE '_ing'";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 2);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"*ing\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 3);
-
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"_ing\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 2);
-
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"%ing\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE '%ing'";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 3);
}
@@ -249,28 +199,18 @@
testRootNode.save();
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"ping\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'ping'";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 1);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"p?ng\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'p_ng'";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 2);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"p*ng\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 3);
-
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"p_ng\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 2);
-
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"p%ng\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'p%ng'";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 3);
}
@@ -285,64 +225,58 @@
testRootNode.save();
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"bli\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'bli'";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 1);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"bl?\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 2);
-
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"bl*\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
- result = q.execute();
- checkResult(result, 3);
-
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"bl_\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'bl_'";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 2);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"bl%\"";
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'bl%'";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 3);
}
public void testLikePatternEscaped() throws Exception {
Node n = testRootNode.addNode("node1", NT_UNSTRUCTURED);
- n.setProperty("value", new String[]{"foo\\?bar"});
+ n.setProperty("value", new String[]{"foo\\_bar"});
n = testRootNode.addNode("node2", NT_UNSTRUCTURED);
n.setProperty("value", new String[]{"foobar"});
n = testRootNode.addNode("node3", NT_UNSTRUCTURED);
- n.setProperty("value", new String[]{"foo?bar"});
+ n.setProperty("value", new String[]{"foo_bar"});
n = testRootNode.addNode("node4", NT_UNSTRUCTURED);
n.setProperty("value", new String[]{"foolbar"});
testRootNode.save();
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"foo\\?bar\""; // matches node3
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'foo\\_bar' ESCAPE '\\'"; // matches node3
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
QueryResult result = q.execute();
checkResult(result, 1);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"foo?bar\""; // matches node3 and node4
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'foo_bar'"; // matches node3 and node4
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 2);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"foo*bar\""; // matches all nodes
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'foo%bar'"; // matches all nodes
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 4);
- jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value LIKE \"foo\\\\\\?bar\""; // matches node1
- q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'foo\\\\\\_bar' ESCAPE '\\'"; // matches node1
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
result = q.execute();
checkResult(result, 1);
+ sql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value LIKE 'foo\\_bar'"; // matches node1
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
+ result = q.execute();
+ checkResult(result, 1);
}
public void testNotEqual() throws Exception {
@@ -355,8 +289,8 @@
testRootNode.save();
- String jcrql = "SELECT * FROM * LOCATION " + testRoot + "// WHERE value <> \"bar\"";
- Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, Query.JCRQL);
+ String jcrql = "SELECT * FROM nt:base WHERE jcr:path LIKE '" + testRoot + "/%' AND value <> 'bar'";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(jcrql, "sql");
QueryResult result = q.execute();
checkResult(result, 2);