Author: alexparvulescu
Date: Fri Dec 2 10:58:41 2011
New Revision: 1209402
URL: http://svn.apache.org/viewvc?rev=1209402&view=rev
Log:
JCR-3165 Consolidate compare behaviour for Value(s) and Comparable(s)
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ValueComparator.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/sort/RowComparator.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/sort/ValueComparableWrapper.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java?rev=1209402&r1=1209401&r2=1209402&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/Util.java Fri Dec 2 10:58:41 2011
@@ -16,24 +16,24 @@
*/
package org.apache.jackrabbit.core.query.lucene;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Fieldable;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.index.IndexReader;
-import org.apache.jackrabbit.core.value.InternalValue;
-import org.slf4j.LoggerFactory;
-import org.slf4j.Logger;
-
-import java.util.regex.Pattern;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
+import java.util.regex.Pattern;
import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
-import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Fieldable;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Query;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Util provides various static utility methods.
@@ -48,8 +48,9 @@ public class Util {
/**
* Disposes the document old. Closes any potentially open
* readers held by the document.
- *
- * @param old the document to dispose.
+ *
+ * @param old
+ * the document to dispose.
*/
public static void disposeDocument(Document old) {
for (Fieldable f : old.getFields()) {
@@ -69,8 +70,9 @@ public class Util {
/**
* Returns true if the document is ready to be added to the
* index. That is all text extractors have finished their work.
- *
- * @param doc the document to check.
+ *
+ * @param doc
+ * the document to check.
* @return true if the document is ready; false
* otherwise.
*/
@@ -89,17 +91,20 @@ public class Util {
/**
* Depending on the index format this method returns a query that matches
* all nodes that have a property with a given name.
- *
- * @param name the property name.
- * @param version the index format version.
+ *
+ * @param name
+ * the property name.
+ * @param version
+ * the index format version.
* @return Query that matches all nodes that have a property with the given
* name.
*/
- public static Query createMatchAllQuery(
- String name, IndexFormatVersion version, PerQueryCache cache) {
+ public static Query createMatchAllQuery(String name,
+ IndexFormatVersion version, PerQueryCache cache) {
if (version.getVersion() >= IndexFormatVersion.V2.getVersion()) {
// new index format style
- return new JackrabbitTermQuery(new Term(FieldNames.PROPERTIES_SET, name));
+ return new JackrabbitTermQuery(new Term(FieldNames.PROPERTIES_SET,
+ name));
} else {
return new MatchAllQuery(name, cache);
}
@@ -107,8 +112,9 @@ public class Util {
/**
* Creates an {@link IOException} with t as its cause.
- *
- * @param t the cause.
+ *
+ * @param t
+ * the cause.
*/
public static IOException createIOException(Throwable t) {
IOException ex = new IOException(t.getMessage());
@@ -120,10 +126,12 @@ public class Util {
* Depending on the type of the reader this method either
* closes or releases the reader. The reader is released if it implements
* {@link ReleaseableIndexReader}.
- *
- * @param reader the index reader to close or release.
- * @throws IOException if an error occurs while closing or releasing the
- * index reader.
+ *
+ * @param reader
+ * the index reader to close or release.
+ * @throws IOException
+ * if an error occurs while closing or releasing the index
+ * reader.
*/
public static void closeOrRelease(IndexReader reader) throws IOException {
if (reader instanceof ReleaseableIndexReader) {
@@ -135,88 +143,94 @@ public class Util {
/**
* Returns a comparable for the internal value.
- *
- * @param value an internal value.
+ *
+ * @param value
+ * an internal value.
* @return a comparable for the given value.
- * @throws RepositoryException if retrieving the Comparable fails.
+ * @throws RepositoryException
+ * if retrieving the Comparable fails.
*/
- public static Comparable getComparable(InternalValue value) throws RepositoryException {
+ public static Comparable getComparable(InternalValue value)
+ throws RepositoryException {
switch (value.getType()) {
- case PropertyType.BINARY:
- return null;
- case PropertyType.BOOLEAN:
- return value.getBoolean();
- case PropertyType.DATE:
- return value.getDate().getTimeInMillis();
- case PropertyType.DOUBLE:
- return value.getDouble();
- case PropertyType.LONG:
- return value.getLong();
- case PropertyType.DECIMAL:
- return value.getDecimal();
- case PropertyType.NAME:
- return value.getName().toString();
- case PropertyType.PATH:
- return value.getPath().toString();
- case PropertyType.URI:
- case PropertyType.WEAKREFERENCE:
- case PropertyType.REFERENCE:
- case PropertyType.STRING:
- return value.getString();
- default:
- return null;
+ case PropertyType.BINARY:
+ return null;
+ case PropertyType.BOOLEAN:
+ return value.getBoolean();
+ case PropertyType.DATE:
+ return value.getDate().getTimeInMillis();
+ case PropertyType.DOUBLE:
+ return value.getDouble();
+ case PropertyType.LONG:
+ return value.getLong();
+ case PropertyType.DECIMAL:
+ return value.getDecimal();
+ case PropertyType.NAME:
+ return value.getName().toString();
+ case PropertyType.PATH:
+ return value.getPath().toString();
+ case PropertyType.URI:
+ case PropertyType.WEAKREFERENCE:
+ case PropertyType.REFERENCE:
+ case PropertyType.STRING:
+ return value.getString();
+ default:
+ return null;
}
}
/**
* Returns a comparable for the internal value.
- *
- * @param value an internal value.
+ *
+ * @param value
+ * an internal value.
* @return a comparable for the given value.
- * @throws ValueFormatException if the given value cannot be
- * converted into a comparable (i.e.
- * unsupported type).
- * @throws RepositoryException if an error occurs while converting the
- * value.
+ * @throws ValueFormatException
+ * if the given value cannot be converted into a
+ * comparable (i.e. unsupported type).
+ * @throws RepositoryException
+ * if an error occurs while converting the value.
*/
public static Comparable getComparable(Value value)
throws ValueFormatException, RepositoryException {
switch (value.getType()) {
- case PropertyType.BOOLEAN:
- return value.getBoolean();
- case PropertyType.DATE:
- return value.getDate().getTimeInMillis();
- case PropertyType.DOUBLE:
- return value.getDouble();
- case PropertyType.LONG:
- return value.getLong();
- case PropertyType.DECIMAL:
- return value.getDecimal();
- case PropertyType.NAME:
- case PropertyType.PATH:
- case PropertyType.URI:
- case PropertyType.WEAKREFERENCE:
- case PropertyType.REFERENCE:
- case PropertyType.STRING:
- return value.getString();
- default:
- throw new RepositoryException("Unsupported type: "
- + PropertyType.nameFromValue(value.getType()));
+ case PropertyType.BOOLEAN:
+ return value.getBoolean();
+ case PropertyType.DATE:
+ return value.getDate().getTimeInMillis();
+ case PropertyType.DOUBLE:
+ return value.getDouble();
+ case PropertyType.LONG:
+ return value.getLong();
+ case PropertyType.DECIMAL:
+ return value.getDecimal();
+ case PropertyType.NAME:
+ case PropertyType.PATH:
+ case PropertyType.URI:
+ case PropertyType.WEAKREFERENCE:
+ case PropertyType.REFERENCE:
+ case PropertyType.STRING:
+ return value.getString();
+ default:
+ throw new RepositoryException("Unsupported type: "
+ + PropertyType.nameFromValue(value.getType()));
}
}
/**
- * Compares values c1 and c2. If the
- * values have differing types, then the order is defined on
- * the type itself by calling compareTo() on the respective
- * type class names.
- *
- * @param c1 the first value.
- * @param c2 the second value.
+ * Compares values c1 and c2. If the values have
+ * differing types, then the order is defined on the type itself by calling
+ * compareTo() on the respective type class names.
+ *
+ * @param c1
+ * the first value.
+ * @param c2
+ * the second value.
* @return a negative integer if c1 should come before
- * c2
a positive integer if c1
- * should come after c2
0 if they
- * are equal.
+ * c2
+ * a positive integer if c1 should come after
+ * c2
+ * 0 if they are equal.
*/
public static int compare(Comparable c1, Comparable c2) {
if (c1 == c2) {
@@ -236,7 +250,11 @@ public class Util {
}
/**
- * Compares two arrays of comparables.
+ * Compares two arrays of Comparable(s) in the same style as
+ * {@link #compare(Value[], Value[])}.
+ *
+ * The 2 methods *have* to work in the same way for the sort to be
+ * consistent
*/
public static int compare(Comparable>[] c1, Comparable>[] c2) {
if (c1 == null) {
@@ -255,76 +273,102 @@ public class Util {
}
/**
+ * Compares two arrays of Value(s) in the same style as
+ * {@link #compare(Comparable[], Comparable[])}.
+ *
+ * The 2 methods *have* to work in the same way for the sort to be
+ * consistent
+ */
+ public static int compare(Value[] a, Value[] b) throws RepositoryException {
+ if (a == null) {
+ return -1;
+ }
+ if (b == null) {
+ return 1;
+ }
+ for (int i = 0; i < a.length && i < b.length; i++) {
+ int d = compare(a[i], b[i]);
+ if (d != 0) {
+ return d;
+ }
+ }
+ return a.length - b.length;
+ }
+
+ /**
* Compares the two values. If the values have differing types, then an
* attempt is made to convert the second value into the type of the first
* value.
*
value cannot be
- * converted into a comparable (i.e.
- * unsupported type).
- * @throws RepositoryException if an error occurs while converting the
- * value.
+ * @throws ValueFormatException
+ * if the given value cannot be converted into a
+ * comparable (i.e. unsupported type).
+ * @throws RepositoryException
+ * if an error occurs while converting the value.
*/
- public static int compare(Value v1, Value v2)
- throws ValueFormatException, RepositoryException {
+ public static int compare(Value v1, Value v2) throws ValueFormatException,
+ RepositoryException {
Comparable c1 = getComparable(v1);
Comparable c2;
switch (v1.getType()) {
- case PropertyType.BOOLEAN:
- c2 = v2.getBoolean();
- break;
- case PropertyType.DATE:
- c2 = v2.getDate().getTimeInMillis();
- break;
- case PropertyType.DOUBLE:
- c2 = v2.getDouble();
- break;
- case PropertyType.LONG:
- c2 = v2.getLong();
- break;
- case PropertyType.DECIMAL:
- c2 = v2.getDecimal();
- break;
- case PropertyType.NAME:
- if (v2.getType() == PropertyType.URI) {
- String s = v2.getString();
- if (s.startsWith("./")) {
- s = s.substring(2);
- }
- // need to decode
- try {
- c2 = URLDecoder.decode(s, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RepositoryException(e);
- }
- } else {
- c2 = v2.getString();
+ case PropertyType.BOOLEAN:
+ c2 = v2.getBoolean();
+ break;
+ case PropertyType.DATE:
+ c2 = v2.getDate().getTimeInMillis();
+ break;
+ case PropertyType.DOUBLE:
+ c2 = v2.getDouble();
+ break;
+ case PropertyType.LONG:
+ c2 = v2.getLong();
+ break;
+ case PropertyType.DECIMAL:
+ c2 = v2.getDecimal();
+ break;
+ case PropertyType.NAME:
+ if (v2.getType() == PropertyType.URI) {
+ String s = v2.getString();
+ if (s.startsWith("./")) {
+ s = s.substring(2);
+ }
+ // need to decode
+ try {
+ c2 = URLDecoder.decode(s, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RepositoryException(e);
}
- break;
- case PropertyType.PATH:
- case PropertyType.REFERENCE:
- case PropertyType.WEAKREFERENCE:
- case PropertyType.URI:
- case PropertyType.STRING:
+ } else {
c2 = v2.getString();
- break;
- default:
- throw new RepositoryException("Unsupported type: "
- + PropertyType.nameFromValue(v2.getType()));
+ }
+ break;
+ case PropertyType.PATH:
+ case PropertyType.REFERENCE:
+ case PropertyType.WEAKREFERENCE:
+ case PropertyType.URI:
+ case PropertyType.STRING:
+ c2 = v2.getString();
+ break;
+ default:
+ throw new RepositoryException("Unsupported type: "
+ + PropertyType.nameFromValue(v2.getType()));
}
return compare(c1, c2);
}
/**
* Creates a regexp from likePattern.
- *
- * @param likePattern the pattern.
+ *
+ * @param likePattern
+ * the pattern.
* @return the regular expression Pattern.
*/
public static Pattern createRegexp(String likePattern) {
@@ -355,14 +399,14 @@ public class Util {
escaped = false;
} else {
switch (likePattern.charAt(i)) {
- case '_':
- regexp.append('.');
- break;
- case '%':
- regexp.append(".*");
- break;
- default:
- regexp.append('\\').append(likePattern.charAt(i));
+ case '_':
+ regexp.append('.');
+ break;
+ case '%':
+ regexp.append(".*");
+ break;
+ default:
+ regexp.append('\\').append(likePattern.charAt(i));
}
}
}
@@ -373,8 +417,9 @@ public class Util {
/**
* Returns length of the internal value.
- *
- * @param value a value.
+ *
+ * @param value
+ * a value.
* @return the length of the internal value or -1 if the length
* cannot be determined.
*/
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ValueComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ValueComparator.java?rev=1209402&r1=1209401&r2=1209402&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ValueComparator.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/join/ValueComparator.java Fri Dec 2 10:58:41 2011
@@ -16,10 +16,6 @@
*/
package org.apache.jackrabbit.core.query.lucene.join;
-import static javax.jcr.PropertyType.DATE;
-import static javax.jcr.PropertyType.DECIMAL;
-import static javax.jcr.PropertyType.DOUBLE;
-import static javax.jcr.PropertyType.LONG;
import static javax.jcr.query.qom.QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO;
import static javax.jcr.query.qom.QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN;
import static javax.jcr.query.qom.QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO;
@@ -28,6 +24,7 @@ import static javax.jcr.query.qom.QueryO
import static javax.jcr.query.qom.QueryObjectModelConstants.JCR_OPERATOR_LIKE;
import static javax.jcr.query.qom.QueryObjectModelConstants.JCR_OPERATOR_NOT_EQUAL_TO;
+import java.util.Arrays;
import java.util.Comparator;
import java.util.regex.Pattern;
@@ -46,20 +43,10 @@ public class ValueComparator implements
*/
public int compare(Value a, Value b) {
try {
- int ta = a.getType();
- int tb = b.getType();
-
- if ((ta == DECIMAL || ta == DOUBLE || ta == LONG)
- && (tb == DECIMAL || tb == DOUBLE || tb == LONG)) {
- return a.getDecimal().compareTo(b.getDecimal());
- } else if (ta == DATE && tb == DATE) {
- return a.getDate().compareTo(b.getDate());
- } else {
- return a.getString().compareTo(b.getString());
- }
+ return Util.compare(a, b);
} catch (RepositoryException e) {
- throw new RuntimeException(
- "Unable to compare values " + a + " and " + b, e);
+ throw new RuntimeException("Unable to compare values " + a
+ + " and " + b, e);
}
}
@@ -98,6 +85,15 @@ public class ValueComparator implements
}
}
+ public int compare(Value[] a, Value[] b) {
+ try {
+ return Util.compare(a, b);
+ } catch (RepositoryException e) {
+ throw new RuntimeException("Unable to compare values "
+ + Arrays.toString(a) + " and " + Arrays.toString(b), e);
+ }
+ }
+
/**
* Evaluates the given QOM comparison operation with the given value arrays.
*
@@ -108,15 +104,20 @@ public class ValueComparator implements
*/
public boolean evaluate(String operator, Value[] a, Value[] b) {
if (JCR_OPERATOR_EQUAL_TO.equals(operator)) {
- for (int i = 0; i < a.length; i++) {
- for (int j = 0; j < b.length; j++) {
- if (compare(a[i], b[j]) == 0) {
- return true;
- }
- }
- }
+ return compare(a, b) == 0;
+ } else if (JCR_OPERATOR_GREATER_THAN.equals(operator)) {
+ return compare(a, b) > 0;
+ } else if (JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO.equals(operator)) {
+ return compare(a, b) >= 0;
+ } else if (JCR_OPERATOR_LESS_THAN.equals(operator)) {
+ return compare(a, b) < 0;
+ } else if (JCR_OPERATOR_LESS_THAN_OR_EQUAL_TO.equals(operator)) {
+ return compare(a, b) <= 0;
+ } else if (JCR_OPERATOR_NOT_EQUAL_TO.equals(operator)) {
+ return compare(a, b) != 0;
}
- return false; // FIXME
+ // TODO JCR_OPERATOR_LIKE
+ throw new IllegalArgumentException("Unknown comparison operator: "
+ + operator);
}
-
-}
\ No newline at end of file
+}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/sort/RowComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/sort/RowComparator.java?rev=1209402&r1=1209401&r2=1209402&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/sort/RowComparator.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/sort/RowComparator.java Fri Dec 2 10:58:41 2011
@@ -34,7 +34,7 @@ import org.apache.jackrabbit.core.query.
*/
public class RowComparator implements Comparator