package lux.index.field; import java.util.Iterator; import lux.exception.LuxException; import lux.index.XmlIndexer; import net.sf.saxon.s9api.SaxonApiException; import net.sf.saxon.s9api.XdmItem; import net.sf.saxon.s9api.XdmSequenceIterator; import net.sf.saxon.s9api.XdmValue; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Field.Store; import org.apache.solr.schema.SchemaField; /** * Indexes the values of the XPath expression evaluated with the document as the context item */ public class XPathField extends FieldDefinition { private final String xpath; private final SchemaField schemaField; /** * create a new indexed field whose values are given by evaluating an XPath expression * @param name the name of the field; although Lucene naming conventions are fairly loose, * it will go easier if you restrict yourself to [A-Za-z0-9_.-] * @param xpath the xpath to evaluate * @param analyzer String-valued fields may be subject to further textual analysis, or pass null * if the field is not to be analyzed. * @param isStored whether the field values are stored (and may be retrieved) * @param type the type of data indexed by the field */ public XPathField (String name, String xpath, Analyzer analyzer, Store isStored, Type type) { super (analyzer, isStored, type); this.xpath = xpath; schemaField= null; setName (name); } public XPathField (String name, String xpath, Analyzer analyzer, Store isStored, SchemaField schemaField) { super (analyzer, isStored, Type.SOLR_FIELD); this.xpath = xpath; this.schemaField = schemaField; setName (name); } public String getXPath () { return xpath; } @Override public Iterable<?> getValues(XmlIndexer indexer) { XdmValue value; try { value = indexer.evaluateXPath (xpath); } catch (SaxonApiException e) { throw new LuxException("error getting values for field: " + getName(), e); } return new XPathValueIterator(value.iterator()); } public SchemaField getSchemaField() { return schemaField; } class XPathValueIterator implements Iterator<Object>, Iterable<Object> { private final XdmSequenceIterator sequence; XPathValueIterator (XdmSequenceIterator sequence) { this.sequence = sequence; } @Override public boolean hasNext() { return sequence.hasNext(); } @Override public Object next() { XdmItem item = sequence.next(); String stringValue = item.getStringValue(); switch (getType()) { case STRING: case TEXT: return stringValue; case INT: return Integer.valueOf (stringValue); case LONG: return Long.valueOf (stringValue); case SOLR_FIELD: return getSchemaField().createField(stringValue, 1.0f); default: throw new IllegalStateException (getType() + " is not a valid type for an XPathField"); } } @Override public void remove() { throw new UnsupportedOperationException(); } @Override public Iterator<Object> iterator() { return this; } } } /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */