start abstaction of json

This commit is contained in:
kimchy 2010-04-28 11:20:41 +03:00
parent 348117c823
commit c48851f49c
17 changed files with 182 additions and 270 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/../../plugins/analysis/icu/build/classes/main" />
<output-test url="file://$MODULE_DIR$/../../plugins/analysis/icu/build/classes/test" />

View File

@ -21,13 +21,12 @@ package org.elasticsearch.index.mapper.json;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
@ -56,10 +55,9 @@ public class JsonBinaryFieldMapper extends JsonFieldMapper<byte[]> {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode binaryNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonBinaryFieldMapper.Builder builder = binaryField(name);
parseJsonField(builder, name, binaryNode, parserContext);
parseJsonField(builder, name, node, parserContext);
return builder;
}
}

View File

@ -21,9 +21,7 @@ package org.elasticsearch.index.mapper.json;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.util.Booleans;
import org.elasticsearch.util.Strings;
@ -31,7 +29,6 @@ import org.elasticsearch.util.json.JsonBuilder;
import org.elasticsearch.util.lucene.Lucene;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
@ -97,14 +94,12 @@ public class JsonBooleanFieldMapper extends JsonFieldMapper<Boolean> {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode booleanNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonBooleanFieldMapper.Builder builder = booleanField(name);
parseJsonField(builder, name, booleanNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = booleanNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
parseJsonField(builder, name, node, parserContext);
for (Map.Entry<String, Object> entry : node.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("null_value")) {
builder.nullValue(nodeBooleanValue(propNode));
}

View File

@ -23,9 +23,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.*;
import org.apache.lucene.util.NumericUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericDateAnalyzer;
import org.elasticsearch.index.mapper.MapperParsingException;
@ -36,7 +34,6 @@ import org.elasticsearch.util.joda.Joda;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
@ -85,16 +82,14 @@ public class JsonDateFieldMapper extends JsonNumberFieldMapper<Long> {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode dateNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonDateFieldMapper.Builder builder = dateField(name);
parseNumberField(builder, name, dateNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = dateNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
parseNumberField(builder, name, node, parserContext);
for (Map.Entry<String, Object> entry : node.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("null_value")) {
builder.nullValue(propNode.getValueAsText());
builder.nullValue(propNode.toString());
} else if (propName.equals("format")) {
builder.dateTimeFormatter(parseDateTimeFormatter(propName, propNode));
}

View File

@ -19,21 +19,18 @@
package org.elasticsearch.index.mapper.json;
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.DocumentMapperParser;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.util.MapBuilder;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
import org.elasticsearch.util.io.FastStringReader;
import org.elasticsearch.util.json.Jackson;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
@ -86,29 +83,29 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
}
@Override public DocumentMapper parse(String type, String source) throws MapperParsingException {
JsonNode root;
Map<String, Object> root;
try {
root = objectMapper.readValue(new FastStringReader(source), JsonNode.class);
root = objectMapper.readValue(new FastStringReader(source), Map.class);
} catch (IOException e) {
throw new MapperParsingException("Failed to parse json mapping definition", e);
}
String rootName = root.getFieldNames().next();
ObjectNode rootObj;
String rootName = root.keySet().iterator().next();
Map<String, Object> rootObj;
if (type == null) {
// we have no type, we assume the first node is the type
rootObj = (ObjectNode) root.get(rootName);
rootObj = (Map<String, Object>) root.get(rootName);
type = rootName;
} else {
// we have a type, check if the top level one is the type as well
// if it is, then the root is that node, if not then the root is the master node
if (type.equals(rootName)) {
JsonNode tmpNode = root.get(type);
if (!tmpNode.isObject()) {
throw new MapperParsingException("Expected root node name [" + rootName + "] to be of json object type, but its not");
Object tmpNode = root.get(type);
if (!(tmpNode instanceof Map)) {
throw new MapperParsingException("Expected root node name [" + rootName + "] to be of object type, but its not");
}
rootObj = (ObjectNode) tmpNode;
rootObj = (Map<String, Object>) tmpNode;
} else {
rootObj = (ObjectNode) root;
rootObj = root;
}
}
@ -116,30 +113,29 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
JsonDocumentMapper.Builder docBuilder = doc((JsonObjectMapper.Builder) rootObjectTypeParser.parse(type, rootObj, parserContext));
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = rootObj.getFields(); fieldsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = fieldsIt.next();
for (Map.Entry<String, Object> entry : rootObj.entrySet()) {
String fieldName = Strings.toUnderscoreCase(entry.getKey());
JsonNode fieldNode = entry.getValue();
Object fieldNode = entry.getValue();
if (JsonSourceFieldMapper.JSON_TYPE.equals(fieldName) || "sourceField".equals(fieldName)) {
docBuilder.sourceField(parseSourceField((ObjectNode) fieldNode, parserContext));
docBuilder.sourceField(parseSourceField((Map<String, Object>) fieldNode, parserContext));
} else if (JsonIdFieldMapper.JSON_TYPE.equals(fieldName) || "idField".equals(fieldName)) {
docBuilder.idField(parseIdField((ObjectNode) fieldNode, parserContext));
docBuilder.idField(parseIdField((Map<String, Object>) fieldNode, parserContext));
} else if (JsonTypeFieldMapper.JSON_TYPE.equals(fieldName) || "typeField".equals(fieldName)) {
docBuilder.typeField(parseTypeField((ObjectNode) fieldNode, parserContext));
docBuilder.typeField(parseTypeField((Map<String, Object>) fieldNode, parserContext));
} else if (JsonUidFieldMapper.JSON_TYPE.equals(fieldName) || "uidField".equals(fieldName)) {
docBuilder.uidField(parseUidField((ObjectNode) fieldNode, parserContext));
docBuilder.uidField(parseUidField((Map<String, Object>) fieldNode, parserContext));
} else if (JsonBoostFieldMapper.JSON_TYPE.equals(fieldName) || "boostField".equals(fieldName)) {
docBuilder.boostField(parseBoostField((ObjectNode) fieldNode, parserContext));
docBuilder.boostField(parseBoostField((Map<String, Object>) fieldNode, parserContext));
} else if (JsonAllFieldMapper.JSON_TYPE.equals(fieldName) || "allField".equals(fieldName)) {
docBuilder.allField(parseAllField((ObjectNode) fieldNode, parserContext));
docBuilder.allField(parseAllField((Map<String, Object>) fieldNode, parserContext));
} else if ("index_analyzer".equals(fieldName)) {
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.getTextValue()));
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.toString()));
} else if ("search_analyzer".equals(fieldName)) {
docBuilder.searchAnalyzer(analysisService.analyzer(fieldNode.getTextValue()));
docBuilder.searchAnalyzer(analysisService.analyzer(fieldNode.toString()));
} else if ("analyzer".equals(fieldName)) {
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.getTextValue()));
docBuilder.searchAnalyzer(analysisService.analyzer(fieldNode.getTextValue()));
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.toString()));
docBuilder.searchAnalyzer(analysisService.analyzer(fieldNode.toString()));
}
}
@ -158,29 +154,18 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
return documentMapper;
}
private JsonUidFieldMapper.Builder parseUidField(ObjectNode uidNode, JsonTypeParser.ParserContext parserContext) {
// String name = uidNode.get("name") == null ? JsonUidFieldMapper.Defaults.NAME : uidNode.get("name").getTextValue();
private JsonUidFieldMapper.Builder parseUidField(Map<String, Object> uidNode, JsonTypeParser.ParserContext parserContext) {
JsonUidFieldMapper.Builder builder = uid();
// for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = uidNode.getFields(); fieldsIt.hasNext();) {
// Map.Entry<String, JsonNode> entry = fieldsIt.next();
// String fieldName = entry.getKey();
// JsonNode fieldNode = entry.getValue();
//
// if ("indexName".equals(fieldName)) {
// builder.indexName(fieldNode.getTextValue());
// }
// }
return builder;
}
private JsonBoostFieldMapper.Builder parseBoostField(ObjectNode boostNode, JsonTypeParser.ParserContext parserContext) {
String name = boostNode.get("name") == null ? JsonBoostFieldMapper.Defaults.NAME : boostNode.get("name").getTextValue();
private JsonBoostFieldMapper.Builder parseBoostField(Map<String, Object> boostNode, JsonTypeParser.ParserContext parserContext) {
String name = boostNode.get("name") == null ? JsonBoostFieldMapper.Defaults.NAME : boostNode.get("name").toString();
JsonBoostFieldMapper.Builder builder = boost(name);
parseNumberField(builder, name, boostNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = boostNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
for (Map.Entry<String, Object> entry : boostNode.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("null_value")) {
builder.nullValue(nodeFloatValue(propNode));
}
@ -188,29 +173,25 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
return builder;
}
private JsonTypeFieldMapper.Builder parseTypeField(ObjectNode typeNode, JsonTypeParser.ParserContext parserContext) {
// String name = typeNode.get("name") == null ? JsonTypeFieldMapper.Defaults.NAME : typeNode.get("name").getTextValue();
private JsonTypeFieldMapper.Builder parseTypeField(Map<String, Object> typeNode, JsonTypeParser.ParserContext parserContext) {
JsonTypeFieldMapper.Builder builder = type();
parseJsonField(builder, builder.name, typeNode, parserContext);
return builder;
}
private JsonIdFieldMapper.Builder parseIdField(ObjectNode idNode, JsonTypeParser.ParserContext parserContext) {
// String name = idNode.get("name") == null ? JsonIdFieldMapper.Defaults.NAME : idNode.get("name").getTextValue();
private JsonIdFieldMapper.Builder parseIdField(Map<String, Object> idNode, JsonTypeParser.ParserContext parserContext) {
JsonIdFieldMapper.Builder builder = id();
parseJsonField(builder, builder.name, idNode, parserContext);
return builder;
}
private JsonAllFieldMapper.Builder parseAllField(ObjectNode allNode, JsonTypeParser.ParserContext parserContext) {
// String name = idNode.get("name") == null ? JsonIdFieldMapper.Defaults.NAME : idNode.get("name").getTextValue();
private JsonAllFieldMapper.Builder parseAllField(Map<String, Object> allNode, JsonTypeParser.ParserContext parserContext) {
JsonAllFieldMapper.Builder builder = all();
parseJsonField(builder, builder.name, allNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = allNode.getFields(); fieldsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = fieldsIt.next();
for (Map.Entry<String, Object> entry : allNode.entrySet()) {
String fieldName = Strings.toUnderscoreCase(entry.getKey());
JsonNode fieldNode = entry.getValue();
Object fieldNode = entry.getValue();
if (fieldName.equals("enabled")) {
builder.enabled(nodeBooleanValue(fieldNode));
}
@ -218,30 +199,15 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
return builder;
}
private JsonSourceFieldMapper.Builder parseSourceField(ObjectNode sourceNode, JsonTypeParser.ParserContext parserContext) {
// String name = sourceNode.get("name") == null ? JsonSourceFieldMapper.Defaults.NAME : sourceNode.get("name").getTextValue();
private JsonSourceFieldMapper.Builder parseSourceField(Map<String, Object> sourceNode, JsonTypeParser.ParserContext parserContext) {
JsonSourceFieldMapper.Builder builder = source();
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = sourceNode.getFields(); fieldsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = fieldsIt.next();
for (Map.Entry<String, Object> entry : sourceNode.entrySet()) {
String fieldName = Strings.toUnderscoreCase(entry.getKey());
JsonNode fieldNode = entry.getValue();
Object fieldNode = entry.getValue();
if (fieldName.equals("enabled")) {
builder.enabled(nodeBooleanValue(fieldNode));
}
// if (fieldName.equals("compressionThreshold")) {
// builder.compressionThreshold(nodeIn...);
// } else if (fieldName.equals("compressionType")) {
// String compressionType = fieldNode.getTextValue();
// if ("zip".equals(compressionType)) {
// builder.compressor(new ZipCompressor());
// } else if ("gzip".equals(compressionType)) {
// builder.compressor(new GZIPCompressor());
// } else if ("lzf".equals(compressionType)) {
// builder.compressor(new LzfCompressor());
// } else {
// throw new MapperParsingException("No compressor registed under [" + compressionType + "]");
// }
// }
}
return builder;
}

View File

@ -23,9 +23,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.*;
import org.apache.lucene.util.NumericUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericDoubleAnalyzer;
import org.elasticsearch.index.mapper.MapperParsingException;
@ -33,7 +31,6 @@ import org.elasticsearch.util.Numbers;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
@ -74,14 +71,12 @@ public class JsonDoubleFieldMapper extends JsonNumberFieldMapper<Double> {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode doubleNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonDoubleFieldMapper.Builder builder = doubleField(name);
parseNumberField(builder, name, doubleNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = doubleNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
parseNumberField(builder, name, node, parserContext);
for (Map.Entry<String, Object> entry : node.entrySet()) {
String propName = entry.getKey();
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("nullValue") || propName.equals("null_value")) {
builder.nullValue(nodeDoubleValue(propNode));
}

View File

@ -23,9 +23,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.*;
import org.apache.lucene.util.NumericUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericFloatAnalyzer;
import org.elasticsearch.index.mapper.MapperParsingException;
@ -34,7 +32,6 @@ import org.elasticsearch.util.Strings;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
@ -75,14 +72,12 @@ public class JsonFloatFieldMapper extends JsonNumberFieldMapper<Float> {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode floatNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonFloatFieldMapper.Builder builder = floatField(name);
parseNumberField(builder, name, floatNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = floatNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
parseNumberField(builder, name, node, parserContext);
for (Map.Entry<String, Object> entry : node.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("null_value")) {
builder.nullValue(nodeFloatValue(propNode));
}

View File

@ -75,14 +75,12 @@ public class JsonIntegerFieldMapper extends JsonNumberFieldMapper<Integer> {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode integerNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonIntegerFieldMapper.Builder builder = integerField(name);
parseNumberField(builder, name, integerNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = integerNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
parseNumberField(builder, name, node, parserContext);
for (Map.Entry<String, Object> entry : node.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("null_value")) {
builder.nullValue(nodeIntegerValue(propNode));
}

View File

@ -23,9 +23,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.*;
import org.apache.lucene.util.NumericUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericLongAnalyzer;
import org.elasticsearch.index.mapper.MapperParsingException;
@ -34,7 +32,6 @@ import org.elasticsearch.util.Strings;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
@ -75,14 +72,12 @@ public class JsonLongFieldMapper extends JsonNumberFieldMapper<Long> {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode longNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonLongFieldMapper.Builder builder = longField(name);
parseNumberField(builder, name, longNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = longNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
parseNumberField(builder, name, node, parserContext);
for (Map.Entry<String, Object> entry : node.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("null_value")) {
builder.nullValue(nodeLongValue(propNode));
}

View File

@ -19,26 +19,23 @@
package org.elasticsearch.index.mapper.json;
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.FieldMapperListener;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.util.gcommon.collect.Lists.*;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
import static org.elasticsearch.util.MapBuilder.*;
import static org.elasticsearch.util.gcommon.collect.Lists.*;
/**
* @author kimchy (shay.banon)
@ -102,26 +99,24 @@ public class JsonMultiFieldMapper implements JsonMapper, JsonIncludeInAllMapper
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode multiFieldNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonMultiFieldMapper.Builder builder = multiField(name);
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = multiFieldNode.getFields(); fieldsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = fieldsIt.next();
for (Map.Entry<String, Object> entry : node.entrySet()) {
String fieldName = Strings.toUnderscoreCase(entry.getKey());
JsonNode fieldNode = entry.getValue();
Object fieldNode = entry.getValue();
if (fieldName.equals("path")) {
builder.pathType(parsePathType(name, fieldNode.getValueAsText()));
builder.pathType(parsePathType(name, fieldNode.toString()));
} else if (fieldName.equals("fields")) {
ObjectNode fieldsNode = (ObjectNode) fieldNode;
for (Iterator<Map.Entry<String, JsonNode>> propsIt = fieldsNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry1 = propsIt.next();
Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode;
for (Map.Entry<String, Object> entry1 : fieldsNode.entrySet()) {
String propName = entry1.getKey();
JsonNode propNode = entry1.getValue();
Map<String, Object> propNode = (Map<String, Object>) entry1.getValue();
String type;
JsonNode typeNode = propNode.get("type");
Object typeNode = propNode.get("type");
if (typeNode != null) {
type = typeNode.getTextValue();
type = typeNode.toString();
} else {
throw new MapperParsingException("No type specified for property [" + propName + "]");
}

View File

@ -19,30 +19,26 @@
package org.elasticsearch.index.mapper.json;
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.ElasticSearchIllegalStateException;
import org.elasticsearch.index.mapper.*;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.concurrent.ThreadSafe;
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
import org.elasticsearch.util.joda.FormatDateTimeFormatter;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.util.gcommon.collect.ImmutableMap.*;
import static org.elasticsearch.util.gcommon.collect.Lists.*;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
import static org.elasticsearch.util.MapBuilder.*;
import static org.elasticsearch.util.gcommon.collect.ImmutableMap.*;
import static org.elasticsearch.util.gcommon.collect.Lists.*;
import static org.elasticsearch.util.json.JacksonNodes.*;
/**
@ -156,27 +152,28 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode objectNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
Map<String, Object> objectNode = node;
JsonObjectMapper.Builder builder = object(name);
for (Iterator<Entry<String, JsonNode>> fieldsIt = objectNode.getFields(); fieldsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = fieldsIt.next();
for (Map.Entry<String, Object> entry : objectNode.entrySet()) {
String fieldName = Strings.toUnderscoreCase(entry.getKey());
JsonNode fieldNode = entry.getValue();
Object fieldNode = entry.getValue();
if (fieldName.equals("dynamic")) {
builder.dynamic(nodeBooleanValue(fieldNode));
} else if (fieldName.equals("type")) {
String type = fieldNode.getTextValue();
String type = fieldNode.toString();
if (!type.equals("object")) {
throw new MapperParsingException("Trying to parse an object but has a different type [" + type + "] for [" + name + "]");
}
} else if (fieldName.equals("date_formats")) {
List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
if (fieldNode.isArray()) {
for (JsonNode node1 : (ArrayNode) fieldNode) {
if (fieldNode instanceof List) {
for (Object node1 : (List) fieldNode) {
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, node1));
}
} else if ("none".equals(fieldNode.getValueAsText())) {
} else if ("none".equals(fieldNode.toString())) {
dateTimeFormatters = null;
} else {
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, fieldNode));
@ -189,9 +186,9 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
} else if (fieldName.equals("enabled")) {
builder.enabled(nodeBooleanValue(fieldNode));
} else if (fieldName.equals("path")) {
builder.pathType(parsePathType(name, fieldNode.getValueAsText()));
builder.pathType(parsePathType(name, fieldNode.toString()));
} else if (fieldName.equals("properties")) {
parseProperties(builder, (ObjectNode) fieldNode, parserContext);
parseProperties(builder, (Map<String, Object>) fieldNode, parserContext);
} else if (fieldName.equals("include_in_all")) {
builder.includeInAll(nodeBooleanValue(fieldNode));
}
@ -199,21 +196,20 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
return builder;
}
private void parseProperties(JsonObjectMapper.Builder objBuilder, ObjectNode propsNode, JsonTypeParser.ParserContext parserContext) {
for (Iterator<Map.Entry<String, JsonNode>> propsIt = propsNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
private void parseProperties(JsonObjectMapper.Builder objBuilder, Map<String, Object> propsNode, JsonTypeParser.ParserContext parserContext) {
for (Map.Entry<String, Object> entry : propsNode.entrySet()) {
String propName = entry.getKey();
JsonNode propNode = entry.getValue();
Map<String, Object> propNode = (Map<String, Object>) entry.getValue();
String type;
JsonNode typeNode = propNode.get("type");
Object typeNode = propNode.get("type");
if (typeNode != null) {
type = typeNode.getTextValue();
type = typeNode.toString();
} else {
// lets see if we can derive this...
if (propNode.isObject() && propNode.get("properties") != null) {
if (propNode.get("properties") != null) {
type = JsonObjectMapper.JSON_TYPE;
} else if (propNode.isObject() && propNode.get("fields") != null) {
} else if (propNode.get("fields") != null) {
type = JsonMultiFieldMapper.JSON_TYPE;
} else {
throw new MapperParsingException("No type specified for property [" + propName + "]");

View File

@ -23,9 +23,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.*;
import org.apache.lucene.util.NumericUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
import org.elasticsearch.index.mapper.MapperParsingException;
@ -34,7 +32,6 @@ import org.elasticsearch.util.Strings;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
@ -75,14 +72,12 @@ public class JsonShortFieldMapper extends JsonNumberFieldMapper<Short> {
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode shortNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonShortFieldMapper.Builder builder = shortField(name);
parseNumberField(builder, name, shortNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = shortNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
parseNumberField(builder, name, node, parserContext);
for (Map.Entry<String, Object> entry : node.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("null_value")) {
builder.nullValue(nodeShortValue(propNode));
}

View File

@ -21,16 +21,13 @@ package org.elasticsearch.index.mapper.json;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.json.JsonBuilder;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
@ -77,16 +74,14 @@ public class JsonStringFieldMapper extends JsonFieldMapper<String> implements Js
}
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode stringNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonStringFieldMapper.Builder builder = stringField(name);
parseJsonField(builder, name, stringNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = stringNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
parseJsonField(builder, name, node, parserContext);
for (Map.Entry<String, Object> entry : node.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("null_value")) {
builder.nullValue(propNode.getValueAsText());
builder.nullValue(propNode.toString());
}
}
return builder;

View File

@ -26,6 +26,8 @@ import org.elasticsearch.index.analysis.AnalysisService;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.util.Strings;
import java.util.Map;
/**
* @author kimchy (shay.banon)
*/
@ -35,11 +37,11 @@ public interface JsonTypeParser {
private final AnalysisService analysisService;
private final ObjectNode rootNode;
private final Map<String, Object> rootNode;
private final ImmutableMap<String, JsonTypeParser> typeParsers;
public ParserContext(ObjectNode rootNode, AnalysisService analysisService, ImmutableMap<String, JsonTypeParser> typeParsers) {
public ParserContext(Map<String, Object> rootNode, AnalysisService analysisService, ImmutableMap<String, JsonTypeParser> typeParsers) {
this.analysisService = analysisService;
this.rootNode = rootNode;
this.typeParsers = typeParsers;
@ -49,7 +51,7 @@ public interface JsonTypeParser {
return analysisService;
}
public ObjectNode rootNode() {
public Map<String, Object> rootNode() {
return this.rootNode;
}
@ -58,5 +60,5 @@ public interface JsonTypeParser {
}
}
JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException;
JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException;
}

View File

@ -20,14 +20,11 @@
package org.elasticsearch.index.mapper.json;
import org.apache.lucene.document.Field;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ObjectNode;
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.joda.FormatDateTimeFormatter;
import org.elasticsearch.util.joda.Joda;
import java.util.Iterator;
import java.util.Map;
import static org.elasticsearch.util.json.JacksonNodes.*;
@ -37,31 +34,29 @@ import static org.elasticsearch.util.json.JacksonNodes.*;
*/
public class JsonTypeParsers {
public static void parseNumberField(JsonNumberFieldMapper.Builder builder, String name, ObjectNode numberNode, JsonTypeParser.ParserContext parserContext) {
public static void parseNumberField(JsonNumberFieldMapper.Builder builder, String name, Map<String, Object> numberNode, JsonTypeParser.ParserContext parserContext) {
parseJsonField(builder, name, numberNode, parserContext);
for (Iterator<Map.Entry<String, JsonNode>> propsIt = numberNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
for (Map.Entry<String, Object> entry : numberNode.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("precision_step")) {
builder.precisionStep(nodeIntegerValue(propNode));
}
}
}
public static void parseJsonField(JsonFieldMapper.Builder builder, String name, ObjectNode fieldNode, JsonTypeParser.ParserContext parserContext) {
for (Iterator<Map.Entry<String, JsonNode>> propsIt = fieldNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = propsIt.next();
public static void parseJsonField(JsonFieldMapper.Builder builder, String name, Map<String, Object> fieldNode, JsonTypeParser.ParserContext parserContext) {
for (Map.Entry<String, Object> entry : fieldNode.entrySet()) {
String propName = Strings.toUnderscoreCase(entry.getKey());
JsonNode propNode = entry.getValue();
Object propNode = entry.getValue();
if (propName.equals("index_name")) {
builder.indexName(propNode.getTextValue());
builder.indexName(propNode.toString());
} else if (propName.equals("store")) {
builder.store(parseStore(name, propNode.getTextValue()));
builder.store(parseStore(name, propNode.toString()));
} else if (propName.equals("index")) {
builder.index(parseIndex(name, propNode.getTextValue()));
builder.index(parseIndex(name, propNode.toString()));
} else if (propName.equals("term_vector")) {
builder.termVector(parseTermVector(name, propNode.getTextValue()));
builder.termVector(parseTermVector(name, propNode.toString()));
} else if (propName.equals("boost")) {
builder.boost(nodeFloatValue(propNode));
} else if (propName.equals("omit_norms")) {
@ -69,25 +64,20 @@ public class JsonTypeParsers {
} else if (propName.equals("omit_term_freq_and_positions")) {
builder.omitTermFreqAndPositions(nodeBooleanValue(propNode));
} else if (propName.equals("index_analyzer")) {
builder.indexAnalyzer(parserContext.analysisService().analyzer(propNode.getTextValue()));
builder.indexAnalyzer(parserContext.analysisService().analyzer(propNode.toString()));
} else if (propName.equals("search_analyzer")) {
builder.searchAnalyzer(parserContext.analysisService().analyzer(propNode.getTextValue()));
builder.searchAnalyzer(parserContext.analysisService().analyzer(propNode.toString()));
} else if (propName.equals("analyzer")) {
builder.indexAnalyzer(parserContext.analysisService().analyzer(propNode.getTextValue()));
builder.searchAnalyzer(parserContext.analysisService().analyzer(propNode.getTextValue()));
builder.indexAnalyzer(parserContext.analysisService().analyzer(propNode.toString()));
builder.searchAnalyzer(parserContext.analysisService().analyzer(propNode.toString()));
} else if (propName.equals("include_in_all")) {
builder.includeInAll(nodeBooleanValue(propNode));
}
}
}
public static FormatDateTimeFormatter parseDateTimeFormatter(String fieldName, JsonNode node) {
if (node.isTextual()) {
return Joda.forPattern(node.getTextValue());
} else {
// TODO support more complex configuration...
throw new MapperParsingException("Wrong node to use to parse date formatters [" + fieldName + "]");
}
public static FormatDateTimeFormatter parseDateTimeFormatter(String fieldName, Object node) {
return Joda.forPattern(node.toString());
}
public static Field.TermVector parseTermVector(String fieldName, String termVector) throws MapperParsingException {

View File

@ -21,59 +21,65 @@ package org.elasticsearch.util.json;
import org.codehaus.jackson.JsonNode;
import java.util.List;
import java.util.Map;
/**
* @author kimchy (shay.banon)
*/
public class JacksonNodes {
public static float nodeFloatValue(JsonNode node) {
if (node.isNumber()) {
return node.getNumberValue().floatValue();
}
String value = node.getTextValue();
return Float.parseFloat(value);
public static boolean isObject(Object node) {
return node instanceof Map;
}
public static double nodeDoubleValue(JsonNode node) {
if (node.isNumber()) {
return node.getNumberValue().doubleValue();
}
String value = node.getTextValue();
return Double.parseDouble(value);
public static boolean isArray(Object node) {
return node instanceof List;
}
public static int nodeIntegerValue(JsonNode node) {
if (node.isNumber()) {
return node.getNumberValue().intValue();
public static float nodeFloatValue(Object node) {
if (node instanceof Number) {
return ((Number) node).floatValue();
}
String value = node.getTextValue();
return Integer.parseInt(value);
return Float.parseFloat(node.toString());
}
public static short nodeShortValue(JsonNode node) {
if (node.isNumber()) {
return node.getNumberValue().shortValue();
public static double nodeDoubleValue(Object node) {
if (node instanceof Number) {
return ((Number) node).doubleValue();
}
String value = node.getTextValue();
return Short.parseShort(value);
return Double.parseDouble(node.toString());
}
public static long nodeLongValue(JsonNode node) {
if (node.isNumber()) {
return node.getNumberValue().longValue();
public static int nodeIntegerValue(Object node) {
if (node instanceof Number) {
return ((Number) node).intValue();
}
String value = node.getTextValue();
return Long.parseLong(value);
return Integer.parseInt(node.toString());
}
public static boolean nodeBooleanValue(JsonNode node) {
if (node.isBoolean()) {
return node.getBooleanValue();
public static short nodeShortValue(Object node) {
if (node instanceof Number) {
return ((Number) node).shortValue();
}
if (node.isNumber()) {
return node.getNumberValue().intValue() != 0;
return Short.parseShort(node.toString());
}
public static long nodeLongValue(Object node) {
if (node instanceof Number) {
return ((Number) node).longValue();
}
String value = node.getTextValue();
return Long.parseLong(node.toString());
}
public static boolean nodeBooleanValue(Object node) {
if (node instanceof Boolean) {
return (Boolean) node;
}
if (node instanceof Number) {
return ((Number) node).intValue() != 0;
}
String value = node.toString();
return !(value.equals("false") || value.equals("0") || value.equals("off"));
}
}

View File

@ -154,40 +154,36 @@ public class JsonAttachmentMapper implements JsonMapper {
*/
public static class TypeParser implements JsonTypeParser {
@Override public JsonMapper.Builder parse(String name, JsonNode node, ParserContext parserContext) throws MapperParsingException {
ObjectNode attachmentNode = (ObjectNode) node;
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
JsonAttachmentMapper.Builder builder = new JsonAttachmentMapper.Builder(name);
for (Iterator<Map.Entry<String, JsonNode>> fieldsIt = attachmentNode.getFields(); fieldsIt.hasNext();) {
Map.Entry<String, JsonNode> entry = fieldsIt.next();
for (Map.Entry<String, Object> entry : node.entrySet()) {
String fieldName = entry.getKey();
JsonNode fieldNode = entry.getValue();
Object fieldNode = entry.getValue();
if (fieldName.equals("path")) {
builder.pathType(parsePathType(name, fieldNode.getValueAsText()));
builder.pathType(parsePathType(name, fieldNode.toString()));
} else if (fieldName.equals("fields")) {
ObjectNode fieldsNode = (ObjectNode) fieldNode;
for (Iterator<Map.Entry<String, JsonNode>> propsIt = fieldsNode.getFields(); propsIt.hasNext();) {
Map.Entry<String, JsonNode> entry1 = propsIt.next();
Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode;
for (Map.Entry<String, Object> entry1 : fieldsNode.entrySet()) {
String propName = entry1.getKey();
JsonNode propNode = entry1.getValue();
Object propNode = entry1.getValue();
if (name.equals(propName)) {
// that is the content
builder.content((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse(name, propNode, parserContext));
builder.content((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse(name, (Map<String, Object>) propNode, parserContext));
} else if ("date".equals(propName)) {
builder.date((JsonDateFieldMapper.Builder) parserContext.typeParser("date").parse("date", propNode, parserContext));
builder.date((JsonDateFieldMapper.Builder) parserContext.typeParser("date").parse("date", (Map<String, Object>) propNode, parserContext));
} else if ("title".equals(propName)) {
builder.title((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("title", propNode, parserContext));
builder.title((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("title", (Map<String, Object>) propNode, parserContext));
} else if ("author".equals(propName)) {
builder.author((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("author", propNode, parserContext));
builder.author((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("author", (Map<String, Object>) propNode, parserContext));
} else if ("keywords".equals(propName)) {
builder.keywords((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("keywords", propNode, parserContext));
builder.keywords((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("keywords", (Map<String, Object>) propNode, parserContext));
}
}
}
}
return builder;
}
}