blob: 3832355a48c4f8145f36cfa2093df1c89502e37d [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 java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.solr.handler.dataimport.DataImporter;
import org.apache.solr.handler.dataimport.DocBuilder;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
/**
* <p>
* Mapping for data-config.xml
* </p>
* <p>
* Refer to <a
* href="http://wiki.apache.org/solr/DataImportHandler">http://wiki.apache.org/solr/DataImportHandler</a>
* for more details.
* </p>
* <p>
* <b>This API is experimental and subject to change</b>
*
* @since solr 1.3
*/
public class DIHConfiguration {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
// TODO - remove from here and add it to entity
private final String deleteQuery;
private final List<Entity> entities;
private final String onImportStart;
private final String onImportEnd;
private final String onError;
private final List<Map<String, String>> functions;
private final Script script;
private final Map<String, Map<String,String>> dataSources;
private final PropertyWriter propertyWriter;
private final IndexSchema schema;
private final Map<String,SchemaField> lowerNameVsSchemaField;
public DIHConfiguration(Element element, DataImporter di,
List<Map<String,String>> functions, Script script,
Map<String,Map<String,String>> dataSources, PropertyWriter pw) {
schema = di.getSchema();
lowerNameVsSchemaField = null == schema ? Collections.<String,SchemaField>emptyMap() : loadSchemaFieldMap();
this.deleteQuery = ConfigParseUtil.getStringAttribute(element, "deleteQuery", null);
this.onImportStart = ConfigParseUtil.getStringAttribute(element, "onImportStart", null);
this.onImportEnd = ConfigParseUtil.getStringAttribute(element, "onImportEnd", null);
this.onError = ConfigParseUtil.getStringAttribute(element, "onError", null);
List<Entity> modEntities = new ArrayList<>();
List<Element> l = ConfigParseUtil.getChildNodes(element, "entity");
boolean docRootFound = false;
for (Element e : l) {
Entity entity = new Entity(docRootFound, e, di, this, null);
Map<String, EntityField> fields = gatherAllFields(di, entity);
verifyWithSchema(fields);
modEntities.add(entity);
}
this.entities = Collections.unmodifiableList(modEntities);
if(functions==null) {
functions = Collections.emptyList();
}
List<Map<String, String>> modFunc = new ArrayList<>(functions.size());
for(Map<String, String> f : functions) {
modFunc.add(Collections.unmodifiableMap(f));
}
this.functions = Collections.unmodifiableList(modFunc);
this.script = script;
this.dataSources = Collections.unmodifiableMap(dataSources);
this.propertyWriter = pw;
}
private void verifyWithSchema(Map<String,EntityField> fields) {
Map<String,SchemaField> schemaFields = null;
if (schema == null) {
schemaFields = Collections.emptyMap();
} else {
schemaFields = schema.getFields();
}
for (Map.Entry<String,SchemaField> entry : schemaFields.entrySet()) {
SchemaField sf = entry.getValue();
if (!fields.containsKey(sf.getName())) {
if (sf.isRequired()) {
if (log.isInfoEnabled()) {
log.info("{} is a required field in SolrSchema . But not found in DataConfig", sf.getName());
}
}
}
}
for (Map.Entry<String,EntityField> entry : fields.entrySet()) {
EntityField fld = entry.getValue();
SchemaField field = getSchemaField(fld.getName());
if (field == null && !isSpecialCommand(fld.getName())) {
if (log.isInfoEnabled()) {
log.info("The field :{} present in DataConfig does not have a counterpart in Solr Schema", fld.getName());
}
}
}
}
private Map<String,EntityField> gatherAllFields(DataImporter di, Entity e) {
Map<String,EntityField> fields = new HashMap<>();
if (e.getFields() != null) {
for (EntityField f : e.getFields()) {
fields.put(f.getName(), f);
}
}
for (Entity e1 : e.getChildren()) {
fields.putAll(gatherAllFields(di, e1));
}
return fields;
}
private Map<String,SchemaField> loadSchemaFieldMap() {
Map<String, SchemaField> modLnvsf = new HashMap<>();
for (Map.Entry<String, SchemaField> entry : schema.getFields().entrySet()) {
modLnvsf.put(entry.getKey().toLowerCase(Locale.ROOT), entry.getValue());
}
return Collections.unmodifiableMap(modLnvsf);
}
public SchemaField getSchemaField(String caseInsensitiveName) {
SchemaField schemaField = null;
if(schema!=null) {
schemaField = schema.getFieldOrNull(caseInsensitiveName);
}
if (schemaField == null) {
schemaField = lowerNameVsSchemaField.get(caseInsensitiveName.toLowerCase(Locale.ROOT));
}
return schemaField;
}
public String getDeleteQuery() {
return deleteQuery;
}
public List<Entity> getEntities() {
return entities;
}
public String getOnImportStart() {
return onImportStart;
}
public String getOnImportEnd() {
return onImportEnd;
}
public String getOnError() {
return onError;
}
public List<Map<String,String>> getFunctions() {
return functions;
}
public Map<String,Map<String,String>> getDataSources() {
return dataSources;
}
public Script getScript() {
return script;
}
public PropertyWriter getPropertyWriter() {
return propertyWriter;
}
public IndexSchema getSchema() {
return schema;
}
public static boolean isSpecialCommand(String fld) {
return DocBuilder.DELETE_DOC_BY_ID.equals(fld) ||
DocBuilder.DELETE_DOC_BY_QUERY.equals(fld) ||
DocBuilder.DOC_BOOST.equals(fld) ||
DocBuilder.SKIP_DOC.equals(fld) ||
DocBuilder.SKIP_ROW.equals(fld);
}
}