package org.xbib.elasticsearch.index.mapper.standardnumber;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexableField;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.Mapper;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.TextFieldMapper;
import org.xbib.elasticsearch.common.standardnumber.StandardnumberService;
import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
*
*/
public class StandardnumberMapper extends TextFieldMapper {
private static final Logger logger = LogManager.getLogger(StandardnumberMapper.class.getName());
public static final String MAPPER_TYPE = "standardnumber";
private final Settings settings;
private final StandardnumberService service;
public StandardnumberMapper(Settings settings,
String simpleName,
MappedFieldType fieldType,
MappedFieldType defaultFieldType,
Settings indexSettings,
MultiFields multiFields,
CopyTo copyTo,
StandardnumberService service) {
super(simpleName, fieldType, defaultFieldType,
-1, false, indexSettings, multiFields, copyTo);
this.settings = settings;
this.service = service;
}
@Override
protected void parseCreateField(ParseContext context, List<IndexableField> fields) throws IOException {
if (context.externalValueSet()) {
return;
}
XContentParser parser = context.parser();
if (parser.currentToken() == XContentParser.Token.VALUE_NULL) {
return;
}
String value = fieldType().nullValueAsString();
if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
XContentParser.Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if ("value".equals(currentFieldName) || "_value".equals(currentFieldName)) {
value = parser.textOrNull();
}
}
}
} else {
value = parser.textOrNull();
}
try {
Collection<CharSequence> stdnums = service.lookup(settings, value);
for (CharSequence stdnum : stdnums) {
Field field = new Field(fieldType().name(), stdnum.toString(), fieldType());
fields.add(field);
}
} catch (NumberFormatException e) {
logger.trace(e.getMessage(), e);
context.createExternalValueContext("unknown");
}
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(simpleName());
builder.field("type", MAPPER_TYPE);
builder.array("standardnumbers", settings.getAsArray("standardnumbers"));
builder.endObject();
return builder;
}
@Override
protected String contentType() {
return MAPPER_TYPE;
}
public static final class Defaults {
public static final TextFieldType FIELD_TYPE = new TextFieldType();
static {
FIELD_TYPE.setStored(true);
FIELD_TYPE.setOmitNorms(true);
FIELD_TYPE.setIndexAnalyzer(Lucene.KEYWORD_ANALYZER);
FIELD_TYPE.setSearchAnalyzer(Lucene.KEYWORD_ANALYZER);
FIELD_TYPE.setName(MAPPER_TYPE);
FIELD_TYPE.freeze();
FIELD_TYPE.freeze();
}
}
public static class Builder extends FieldMapper.Builder<Builder, StandardnumberMapper> {
private Settings.Builder settingsBuilder = Settings.builder();
private StandardnumberService service;
public Builder(String name, StandardnumberService service) {
super(name, Defaults.FIELD_TYPE, Defaults.FIELD_TYPE);
this.service = service;
this.builder = this;
}
public Builder standardNumbers(String[] standardnumbers) {
settingsBuilder.putArray("standardnumbers", standardnumbers);
return this;
}
@Override
public StandardnumberMapper build(BuilderContext context) {
if (fieldType.indexOptions() != IndexOptions.NONE && !fieldType.tokenized()) {
defaultFieldType.setOmitNorms(true);
defaultFieldType.setIndexOptions(IndexOptions.DOCS);
if (!omitNormsSet && Float.compare(fieldType.boost(), 1.0f) == 0) {
fieldType.setOmitNorms(true);
}
if (!indexOptionsSet) {
fieldType.setIndexOptions(IndexOptions.DOCS);
}
}
setupFieldType(context);
return new StandardnumberMapper(settingsBuilder.build(),
name,
fieldType,
defaultFieldType,
context.indexSettings(),
multiFieldsBuilder.build(this, context),
copyTo,
service);
}
}
public static class TypeParser implements Mapper.TypeParser {
private StandardnumberService service;
public void setService(StandardnumberService service) {
this.service = service;
}
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Mapper.Builder parse(String name, Map<String, Object> mapping, ParserContext parserContext) {
StandardnumberMapper.Builder builder = new Builder(name, service);
Iterator<Map.Entry<String, Object>> iterator = mapping.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Object> entry = iterator.next();
String fieldName = entry.getKey();
Object fieldNode = entry.getValue();
switch (fieldName) {
case "standardnumbers" :
builder.settingsBuilder.putArray("standardnumbers", XContentMapValues.nodeStringArrayValue(fieldNode));
iterator.remove();
break;
default:
break;
}
}
return builder;
}
}
}