Java tutorial
/* * Hibernate Search, full-text search for your domain model * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.search.backend.spi; import java.io.IOException; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.hibernate.search.analyzer.impl.AnalyzerReference; import org.hibernate.search.analyzer.impl.LuceneAnalyzerReference; import org.hibernate.search.analyzer.impl.RemoteAnalyzerReference; import org.hibernate.search.bridge.FieldBridge; import org.hibernate.search.bridge.util.impl.ContextualExceptionBridgeHelper; import org.hibernate.search.bridge.util.impl.NumericFieldUtils; import org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity; import org.hibernate.search.exception.AssertionFailure; import org.hibernate.search.util.impl.ScopedLuceneAnalyzer; /** * DeleteByQuery equivalent to {@link org.apache.lucene.search.TermQuery} * * @hsearch.experimental * * @author Martin Braun * @author Guillaume Smet */ public final class SingularTermDeletionQuery implements DeletionQuery { public static final int QUERY_KEY = 0; private final String fieldName; private final Object value; private final Type type; public SingularTermDeletionQuery(String fieldName, String value) { this(fieldName, value, Type.STRING); } public SingularTermDeletionQuery(String fieldName, int value) { this(fieldName, value, Type.INT); } public SingularTermDeletionQuery(String fieldName, long value) { this(fieldName, value, Type.LONG); } public SingularTermDeletionQuery(String fieldName, float value) { this(fieldName, value, Type.FLOAT); } public SingularTermDeletionQuery(String fieldName, double value) { this(fieldName, value, Type.DOUBLE); } public SingularTermDeletionQuery(String fieldName, Object value, Type type) { this.fieldName = fieldName; this.value = value; this.type = type; } public String getFieldName() { return fieldName; } public Object getValue() { return value; } public Type getType() { return this.type; } @Override public int getQueryKey() { return QUERY_KEY; } @Override public String toString() { return "SingularTermQuery: +" + fieldName + ":" + value; } @Override public Query toLuceneQuery(DocumentBuilderIndexedEntity documentBuilder) { AnalyzerReference analyzerReferenceForEntity = documentBuilder.getAnalyzerReference(); String stringValue = documentBuilder.objectToString(fieldName, this.getValue(), new ContextualExceptionBridgeHelper()); if (this.getType() == Type.STRING) { try { if (analyzerReferenceForEntity.is(RemoteAnalyzerReference.class)) { // no need to take into account the analyzer here as it will be dealt with remotely return new TermQuery(new Term(this.getFieldName(), stringValue)); } ScopedLuceneAnalyzer analyzerForEntity = (ScopedLuceneAnalyzer) analyzerReferenceForEntity .unwrap(LuceneAnalyzerReference.class).getAnalyzer(); TokenStream tokenStream = analyzerForEntity.tokenStream(this.getFieldName(), stringValue); tokenStream.reset(); try { BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder(); while (tokenStream.incrementToken()) { String term = tokenStream.getAttribute(CharTermAttribute.class).toString(); booleanQueryBuilder.add(new TermQuery(new Term(this.getFieldName(), term)), Occur.FILTER); } return booleanQueryBuilder.build(); } finally { tokenStream.close(); } } catch (IOException e) { throw new AssertionFailure( "No IOException can occur while using a TokenStream that is generated via String"); } } else { FieldBridge fieldBridge = documentBuilder.getBridge(fieldName); if (NumericFieldUtils.isNumericFieldBridge(fieldBridge)) { return NumericFieldUtils.createExactMatchQuery(fieldName, this.getValue()); } else { return new TermQuery(new Term(this.getFieldName(), stringValue)); } } } @Override public String[] serialize() { return new String[] { this.getType().toString(), this.getFieldName(), String.valueOf(this.getValue()) }; } public static SingularTermDeletionQuery fromString(String[] string) { if (string.length != 3) { throw new IllegalArgumentException( "To instantiate a SingularTermDeletionQuery, an array of size 3 is required" + " (type, fieldName, value). Got an array of size " + string.length); } Type type = Type.valueOf(string[0]); switch (type) { case STRING: return new SingularTermDeletionQuery(string[1], string[2]); case INT: return new SingularTermDeletionQuery(string[1], Integer.parseInt(string[2])); case FLOAT: return new SingularTermDeletionQuery(string[1], Float.parseFloat(string[2])); case LONG: return new SingularTermDeletionQuery(string[1], Long.parseLong(string[2])); case DOUBLE: return new SingularTermDeletionQuery(string[1], Double.parseDouble(string[2])); default: throw new AssertionFailure("Unsupported value type: " + type); } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((fieldName == null) ? 0 : fieldName.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); result = prime * result + ((value == null) ? 0 : value.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } SingularTermDeletionQuery other = (SingularTermDeletionQuery) obj; if (fieldName == null) { if (other.fieldName != null) { return false; } } else if (!fieldName.equals(other.fieldName)) { return false; } if (type != other.type) { return false; } if (value == null) { if (other.value != null) { return false; } } else if (!value.equals(other.value)) { return false; } return true; } public enum Type { STRING, INT, LONG, FLOAT, DOUBLE } }