/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.stanbol.entityhub.yard.solr.query; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import org.apache.stanbol.entityhub.yard.solr.model.IndexField; /** * Interface used to encode constraints for a logical {@link IndexField}. * <p> * Typically a single constraint in a query needs to converted to several constraints in the index. Do give * some examples let's assume, that we are interested in documents that contains "life" in there English * title. This constraint would be represented by the following constraints in the index * <ul> * <li>A {@link IndexConstraintTypeEnum#LANG} set to be English * <li>A {@link IndexConstraintTypeEnum#FIELD} set to "dc:title" (dublin core) * <li>A {@link IndexConstraintTypeEnum#WILDCARD} set to life* or alternatively * <li> {@link IndexConstraintTypeEnum#EQ} set to life. * </ul> * In addition it can be the case that for encoding one kind of constraint one needs also an other constraint * to be present. e.g. when encoding a range constraint one needs always to have both the upper and lower * bound to be present. Because of that implementations of this interface can define there * {@link #dependsOn()} other {@link IndexConstraintTypeEnum} to be present. Such types are than added with * the default constraint <code>null</code> if missing. Implementations can indicate with * {@link #supportsDefault()} if they are able to encode the constraint type when set to the default value * <code>null</code>. * <p> * Finally different constraints need different types of values to be parsed. Therefore this interface uses a * generic type and the {@link #acceptsValueType()} method can be used to check if the type of the parsed * value is compatible with the implementation registered for the current {@link IndexConstraintTypeEnum}. * <p> * Please note that implementations of this interface need to be thread save, because typically there will * only be one instance that is shared for all encoding taks. * <p> * TODO: Currently there is no generic implementation that implements the processing steps described here. * However the SolrQueryFactory provides a Solr specific implementation. * * @author Rupert Westenthaler * @param T * the type of supported values! */ public interface IndexConstraintTypeEncoder<T> { /** * Encodes the parsed value and adds it to the IndexQueryConstraint. * <p> * If the encoder supports default values (meaning that {@link #supportsDefault()} returns * <code>true</code>, than parsing <code>null</code> as value MUST result in returning the default value. * Otherwise the encode method might throw an {@link IllegalArgumentException} if <code>null</code> is * parsed. * <p> * Please note that <code>null</code> might also be a valid parameter even if an Encoder does not support * a default value! * @param constraint the encoded constraint parts * @param value * the value for the constraint * @throws IllegalArgumentException * if the parsed value is not supported. Especially if <code>null</code> is parsed and the * implementation does not {@link #supportsDefault()}! */ void encode(EncodedConstraintParts constraint, T value) throws IllegalArgumentException; /** * Returns <code>true</code> if this Encoder supports a default value. This would be e.g. an open ended * upper or lower bound for range constraints or any language for text constraints. * * @return if the encoder supports a default encoding if no constraint of that type is provided by the * query. */ boolean supportsDefault(); /** * A set of other Constraints that need to be present, that the encoding provided by this encoder results * in a valid query constraint. e.g. A range constraint always need a lower and an upper bound. So even if * the query only defines an upper bound, than there MUST BE also a open ended lower bound encoded to * result in a valid query constraint. * * @return set of other index constraint types that must be present. If none return * {@link Collections#emptySet()}. This Method should return an unmodifiable collection (e.g. * {@link Arrays#asList(Object...)} or using * {@link Collections#unmodifiableCollection(Collection)}) */ Collection<IndexConstraintTypeEnum> dependsOn(); /** * The type of the constraint this implementation encodes * * @return the type of the constraints encoded by this implementation */ IndexConstraintTypeEnum encodes(); /** * Getter for the type of values this encoder accepts. * * @return the generic type of the index constraint type encoder */ Class<T> acceptsValueType(); }