package org.apache.lucene.search;
/**
* Copyright 2004 The Apache Software Foundation
*
* 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.
*/
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
import java.io.IOException;
import java.io.Serializable;
/**
* An example Comparable for use with the custom sort tests.
* It implements a comparable for "id" sort of values which
* consist of an alphanumeric part and a numeric part, such as:
* <p/>
* <P>ABC-123, A-1, A-7, A-100, B-99999
* <p/>
* <p>Such values cannot be sorted as strings, since A-100 needs
* to come after A-7.
* <p/>
* <p>It could be argued that the "ids" should be rewritten as
* A-0001, A-0100, etc. so they will sort as strings. That is
* a valid alternate way to solve it - but
* this is only supposed to be a simple test case.
* <p/>
* <p>Created: Apr 21, 2004 5:34:47 PM
*
* @author Tim Jones
* @version $Id: SampleComparable.java 150348 2004-05-19 23:05:27Z tjones $
* @since 1.4
*/
public class SampleComparable
implements Comparable, Serializable {
String string_part;
Integer int_part;
public SampleComparable (String s) {
int i = s.indexOf ("-");
string_part = s.substring (0, i);
int_part = new Integer (s.substring (i + 1));
}
public int compareTo (Object o) {
SampleComparable otherid = (SampleComparable) o;
int i = string_part.compareTo (otherid.string_part);
if (i == 0) return int_part.compareTo (otherid.int_part);
return i;
}
public static SortComparatorSource getComparatorSource () {
return new SortComparatorSource () {
public ScoreDocComparator newComparator (final IndexReader reader, String fieldname)
throws IOException {
final String field = fieldname.intern ();
final TermEnum enumerator = reader.terms (new Term (fieldname, ""));
try {
return new ScoreDocComparator () {
protected Comparable[] cachedValues = fillCache (reader, enumerator, field);
public int compare (ScoreDoc i, ScoreDoc j) {
return cachedValues[i.doc].compareTo (cachedValues[j.doc]);
}
public Comparable sortValue (ScoreDoc i) {
return cachedValues[i.doc];
}
public int sortType () {
return SortField.CUSTOM;
}
};
} finally {
enumerator.close ();
}
}
/**
* Returns an array of objects which represent that natural order
* of the term values in the given field.
*
* @param reader Terms are in this index.
* @param enumerator Use this to get the term values and TermDocs.
* @param fieldname Comparables should be for this field.
* @return Array of objects representing natural order of terms in field.
* @throws IOException If an error occurs reading the index.
*/
protected Comparable[] fillCache (IndexReader reader, TermEnum enumerator, String fieldname)
throws IOException {
final String field = fieldname.intern ();
Comparable[] retArray = new Comparable[reader.maxDoc ()];
if (retArray.length > 0) {
TermDocs termDocs = reader.termDocs ();
try {
if (enumerator.term () == null) {
throw new RuntimeException ("no terms in field " + field);
}
do {
Term term = enumerator.term ();
if (term.field () != field) break;
Comparable termval = getComparable (term.text ());
termDocs.seek (enumerator);
while (termDocs.next ()) {
retArray[termDocs.doc ()] = termval;
}
} while (enumerator.next ());
} finally {
termDocs.close ();
}
}
return retArray;
}
Comparable getComparable (String termtext) {
return new SampleComparable (termtext);
}
};
}
public static SortComparator getComparator() {
return new SortComparator() {
protected Comparable getComparable (String termtext) {
return new SampleComparable (termtext);
}
};
}
} |