| /* |
| * 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.solr.handler.dataimport.config; |
| |
| import static org.apache.solr.handler.dataimport.DataImportHandlerException.SEVERE; |
| |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.solr.handler.dataimport.DataImportHandlerException; |
| import org.apache.solr.handler.dataimport.DataImporter; |
| import org.apache.solr.schema.SchemaField; |
| import org.w3c.dom.Element; |
| |
| public class Entity { |
| private final String name; |
| private final String pk; |
| private final String pkMappingFromSchema; |
| private final String dataSourceName; |
| private final String processorName; |
| private final Entity parentEntity; |
| private final boolean docRoot; |
| private final boolean child; |
| private final List<Entity> children; |
| private final List<EntityField> fields; |
| private final Map<String,Set<EntityField>> colNameVsField; |
| private final Map<String,String> allAttributes; |
| private final List<Map<String,String>> allFieldAttributes; |
| private final DIHConfiguration config; |
| |
| public Entity(boolean docRootFound, Element element, DataImporter di, DIHConfiguration config, Entity parent) { |
| this.parentEntity = parent; |
| this.config = config; |
| |
| String modName = ConfigParseUtil.getStringAttribute(element, ConfigNameConstants.NAME, null); |
| if (modName == null) { |
| throw new DataImportHandlerException(SEVERE, "Entity must have a name."); |
| } |
| if (modName.indexOf(".") != -1) { |
| throw new DataImportHandlerException(SEVERE, |
| "Entity name must not have period (.): '" + modName); |
| } |
| if (ConfigNameConstants.RESERVED_WORDS.contains(modName)) { |
| throw new DataImportHandlerException(SEVERE, "Entity name : '" + modName |
| + "' is a reserved keyword. Reserved words are: " + ConfigNameConstants.RESERVED_WORDS); |
| } |
| this.name = modName; |
| this.pk = ConfigParseUtil.getStringAttribute(element, "pk", null); |
| this.processorName = ConfigParseUtil.getStringAttribute(element, ConfigNameConstants.PROCESSOR,null); |
| this.dataSourceName = ConfigParseUtil.getStringAttribute(element, DataImporter.DATA_SRC, null); |
| |
| String rawDocRootValue = ConfigParseUtil.getStringAttribute(element, ConfigNameConstants.ROOT_ENTITY, null); |
| if (!docRootFound && !"false".equals(rawDocRootValue)) { |
| // if in this chain no document root is found() |
| docRoot = true; |
| } else { |
| docRoot = false; |
| } |
| |
| String childValue = ConfigParseUtil.getStringAttribute(element, ConfigNameConstants.CHILD, null); |
| child = "true".equals(childValue); |
| |
| Map<String,String> modAttributes = ConfigParseUtil |
| .getAllAttributes(element); |
| modAttributes.put(ConfigNameConstants.DATA_SRC, this.dataSourceName); |
| this.allAttributes = Collections.unmodifiableMap(modAttributes); |
| |
| List<Element> n = ConfigParseUtil.getChildNodes(element, "field"); |
| List<EntityField> modFields = new ArrayList<>(n.size()); |
| Map<String,Set<EntityField>> modColNameVsField = new HashMap<>(); |
| List<Map<String,String>> modAllFieldAttributes = new ArrayList<>(); |
| for (Element elem : n) { |
| EntityField.Builder fieldBuilder = new EntityField.Builder(elem); |
| if (config.getSchema() != null) { |
| if (fieldBuilder.getNameOrColumn() != null |
| && fieldBuilder.getNameOrColumn().contains("${")) { |
| fieldBuilder.dynamicName = true; |
| } else { |
| SchemaField schemaField = config.getSchemaField |
| (fieldBuilder.getNameOrColumn()); |
| if (schemaField != null) { |
| fieldBuilder.name = schemaField.getName(); |
| fieldBuilder.multiValued = schemaField.multiValued(); |
| fieldBuilder.allAttributes.put(DataImporter.MULTI_VALUED, Boolean |
| .toString(schemaField.multiValued())); |
| fieldBuilder.allAttributes.put(DataImporter.TYPE, schemaField |
| .getType().getTypeName()); |
| fieldBuilder.allAttributes.put("indexed", Boolean |
| .toString(schemaField.indexed())); |
| fieldBuilder.allAttributes.put("stored", Boolean |
| .toString(schemaField.stored())); |
| fieldBuilder.allAttributes.put("defaultValue", schemaField |
| .getDefaultValue()); |
| } else { |
| fieldBuilder.toWrite = false; |
| } |
| } |
| } |
| Set<EntityField> fieldSet = modColNameVsField.get(fieldBuilder.column); |
| if (fieldSet == null) { |
| fieldSet = new HashSet<>(); |
| modColNameVsField.put(fieldBuilder.column, fieldSet); |
| } |
| fieldBuilder.allAttributes.put("boost", Float |
| .toString(fieldBuilder.boost)); |
| fieldBuilder.allAttributes.put("toWrite", Boolean |
| .toString(fieldBuilder.toWrite)); |
| modAllFieldAttributes.add(fieldBuilder.allAttributes); |
| fieldBuilder.entity = this; |
| EntityField field = new EntityField(fieldBuilder); |
| fieldSet.add(field); |
| modFields.add(field); |
| } |
| Map<String,Set<EntityField>> modColNameVsField1 = new HashMap<>(); |
| for (Map.Entry<String,Set<EntityField>> entry : modColNameVsField |
| .entrySet()) { |
| if (entry.getValue().size() > 0) { |
| modColNameVsField1.put(entry.getKey(), Collections |
| .unmodifiableSet(entry.getValue())); |
| } |
| } |
| this.colNameVsField = Collections.unmodifiableMap(modColNameVsField1); |
| this.fields = Collections.unmodifiableList(modFields); |
| this.allFieldAttributes = Collections |
| .unmodifiableList(modAllFieldAttributes); |
| |
| String modPkMappingFromSchema = null; |
| if (config.getSchema() != null) { |
| SchemaField uniqueKey = config.getSchema().getUniqueKeyField(); |
| if (uniqueKey != null) { |
| modPkMappingFromSchema = uniqueKey.getName(); |
| // if no fields are mentioned . solr uniqueKey is same as dih 'pk' |
| for (EntityField field : fields) { |
| if (field.getName().equals(modPkMappingFromSchema)) { |
| modPkMappingFromSchema = field.getColumn(); |
| // get the corresponding column mapping for the solr uniqueKey |
| // But if there are multiple columns mapping to the solr uniqueKey, |
| // it will fail |
| // so , in one off cases we may need pk |
| break; |
| } |
| } |
| } |
| } |
| pkMappingFromSchema = modPkMappingFromSchema; |
| n = ConfigParseUtil.getChildNodes(element, "entity"); |
| List<Entity> modEntities = new ArrayList<>(); |
| for (Element elem : n) { |
| modEntities.add(new Entity((docRootFound || this.docRoot), elem, di, config, this)); |
| } |
| this.children = Collections.unmodifiableList(modEntities); |
| } |
| |
| public String getPk() { |
| return pk == null ? pkMappingFromSchema : pk; |
| } |
| |
| public String getSchemaPk() { |
| return pkMappingFromSchema != null ? pkMappingFromSchema : pk; |
| } |
| |
| public String getName() { |
| return name; |
| } |
| |
| public String getPkMappingFromSchema() { |
| return pkMappingFromSchema; |
| } |
| |
| public String getDataSourceName() { |
| return dataSourceName; |
| } |
| |
| public String getProcessorName() { |
| return processorName; |
| } |
| |
| public Entity getParentEntity() { |
| return parentEntity; |
| } |
| |
| public boolean isDocRoot() { |
| return docRoot; |
| } |
| |
| public List<Entity> getChildren() { |
| return children; |
| } |
| |
| public List<EntityField> getFields() { |
| return fields; |
| } |
| |
| public Map<String,Set<EntityField>> getColNameVsField() { |
| return colNameVsField; |
| } |
| |
| public Map<String,String> getAllAttributes() { |
| return allAttributes; |
| } |
| |
| public List<Map<String,String>> getAllFieldsList() { |
| return allFieldAttributes; |
| } |
| |
| public boolean isChild() { |
| return child; |
| } |
| } |