blob: 0d0ba4f592651dc61a7ece03f8463c7567fb93e9 [file] [log] [blame]
/*
* 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;
}
}