/* * ModeShape (http://www.modeshape.org) * * 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. */ package org.modeshape.jcr.index.elasticsearch; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.modeshape.jcr.ExecutionContext; import org.modeshape.jcr.api.index.IndexColumnDefinition; import org.modeshape.jcr.api.index.IndexDefinition; import org.modeshape.jcr.index.elasticsearch.client.EsRequest; import org.modeshape.jcr.value.PropertyType; import static org.modeshape.jcr.value.PropertyType.BINARY; import static org.modeshape.jcr.value.PropertyType.BOOLEAN; import static org.modeshape.jcr.value.PropertyType.DATE; import static org.modeshape.jcr.value.PropertyType.DECIMAL; import static org.modeshape.jcr.value.PropertyType.DOUBLE; import static org.modeshape.jcr.value.PropertyType.LONG; /** * Set of index columns where each column provides column's type * specific conversation. * * * @author kulikov */ public class EsIndexColumns { //list of columns private final Map<String, EsIndexColumn> columns = new HashMap<String, EsIndexColumn>(); /** * Creates new set. * * @param cols set of columns. */ public EsIndexColumns(EsIndexColumn... cols) { for (int i = 0; i < cols.length; i++) { columns.put(cols[i].getName(), cols[i]); } } /** * Creates new set of columns using index definition. * * @param context execution context * @param defn index definition. */ public EsIndexColumns(ExecutionContext context, IndexDefinition defn) { EsIndexColumn[] cols = new EsIndexColumn[defn.size()]; for (int i = 0; i < cols.length; i++) { IndexColumnDefinition idef = defn.getColumnDefinition(i); columns.put(idef.getPropertyName(), new EsIndexColumn(context, idef.getPropertyName(), idef.getColumnType())); } } /** * Gets column with given name. * * @param name the name of column in index or name of pseudo column like * lower case, upper case or length. * * @return real column definition related to the specified name */ public EsIndexColumn column(String name) { return columns.get(noprefix(name, EsIndexColumn.LENGTH_PREFIX, EsIndexColumn.LOWERCASE_PREFIX, EsIndexColumn.UPPERCASE_PREFIX)); } /** * Cuts name prefix for the pseudo column case. * * @param name the name of the column or pseudo column. * @param prefix the list of prefixes to cut. * @return the name without prefix. */ private String noprefix(String name, String... prefix) { for (int i = 0; i < prefix.length; i++) { if (name.startsWith(prefix[i])) { name = name.replaceAll(prefix[i], ""); } } return name; } /** * List of real columns. * * @return collection of the columns. */ public Collection<EsIndexColumn> columns() { return columns.values(); } /** * Provides Elasticsearch mapping definition for the given type and * this columns. * * @param type the type name for wich this mapping will be applied. * @return mappings definition in the JSON format. */ public EsRequest mappings( String type ) { EsRequest mappings = new EsRequest(); EsRequest mappingsValue = new EsRequest(); EsRequest mtype = new EsRequest(); EsRequest properties = new EsRequest(); for (EsIndexColumn col : columns()) { properties.put(col.getName(), fieldMapping(col.getType())); properties.put(col.getLowerCaseFieldName(), fieldMapping(PropertyType.STRING)); properties.put(col.getUpperCaseFieldName(), fieldMapping(PropertyType.STRING)); properties.put(col.getLengthFieldName(), fieldMapping(PropertyType.LONG)); } mtype.put("properties", properties); mappingsValue.put(type, mtype); mappings.put("mappings", mappingsValue); return mappings; } /** * Creates mapping definition for the specified column type. * * @param type * @return */ private EsRequest fieldMapping( PropertyType type ) { EsRequest mappings = new EsRequest(); switch (type) { case BINARY: mappings.put("type", "binary"); break; case BOOLEAN: mappings.put("type", "boolean"); break; case DATE: mappings.put("type", "long"); break; case LONG: case DECIMAL: mappings.put("type", "long"); break; case DOUBLE: mappings.put("type", "double"); break; default: mappings.put("type", "string"); mappings.put("analyzer", "whitespace"); } return mappings; } }