protected static void parseNested( String name, Map<String, Object> node, ObjectMapper.Builder builder) { boolean nested = false; boolean nestedIncludeInParent = false; boolean nestedIncludeInRoot = false; Object fieldNode = node.get("type"); if (fieldNode != null) { String type = fieldNode.toString(); if (type.equals(CONTENT_TYPE)) { builder.nested = Nested.NO; } else if (type.equals(NESTED_CONTENT_TYPE)) { nested = true; } else { throw new MapperParsingException( "Trying to parse an object but has a different type [" + type + "] for [" + name + "]"); } } fieldNode = node.get("include_in_parent"); if (fieldNode != null) { nestedIncludeInParent = nodeBooleanValue(fieldNode); node.remove("include_in_parent"); } fieldNode = node.get("include_in_root"); if (fieldNode != null) { nestedIncludeInRoot = nodeBooleanValue(fieldNode); node.remove("include_in_root"); } if (nested) { builder.nested = Nested.newNested(nestedIncludeInParent, nestedIncludeInRoot); } }
protected static boolean parseObjectOrDocumentTypeProperties( String fieldName, Object fieldNode, ParserContext parserContext, ObjectMapper.Builder builder) { if (fieldName.equals("dynamic")) { String value = fieldNode.toString(); if (value.equalsIgnoreCase("strict")) { builder.dynamic(Dynamic.STRICT); } else { builder.dynamic(nodeBooleanValue(fieldNode) ? Dynamic.TRUE : Dynamic.FALSE); } return true; } else if (fieldName.equals("enabled")) { builder.enabled(nodeBooleanValue(fieldNode)); return true; } else if (fieldName.equals("properties")) { if (fieldNode instanceof Collection && ((Collection) fieldNode).isEmpty()) { // nothing to do here, empty (to support "properties: []" case) } else if (!(fieldNode instanceof Map)) { throw new ElasticsearchParseException("properties must be a map type"); } else { parseProperties(builder, (Map<String, Object>) fieldNode, parserContext); } return true; } else if (fieldName.equals("include_in_all")) { builder.includeInAll(nodeBooleanValue(fieldNode)); return true; } return false; }
private void parseProperties( ObjectMapper.Builder objBuilder, Map<String, Object> propsNode, ParserContext parserContext) { for (Map.Entry<String, Object> entry : propsNode.entrySet()) { String propName = entry.getKey(); Map<String, Object> propNode = (Map<String, Object>) entry.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { // lets see if we can derive this... if (propNode.get("properties") != null) { type = ObjectMapper.CONTENT_TYPE; } else if (propNode.get("fields") != null) { type = MultiFieldMapper.CONTENT_TYPE; } else { throw new MapperParsingException("No type specified for property [" + propName + "]"); } } Mapper.TypeParser typeParser = parserContext.typeParser(type); if (typeParser == null) { throw new MapperParsingException( "No handler for type [" + type + "] declared on field [" + propName + "]"); } objBuilder.add(typeParser.parse(propName, propNode, parserContext)); } }
@Override public Mapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException { Map<String, Object> objectNode = node; ObjectMapper.Builder builder = createBuilder(name); boolean nested = false; boolean nestedIncludeInParent = false; boolean nestedIncludeInRoot = false; for (Map.Entry<String, Object> entry : objectNode.entrySet()) { String fieldName = Strings.toUnderscoreCase(entry.getKey()); Object fieldNode = entry.getValue(); if (fieldName.equals("dynamic")) { String value = fieldNode.toString(); if (value.equalsIgnoreCase("strict")) { builder.dynamic(Dynamic.STRICT); } else { builder.dynamic(nodeBooleanValue(fieldNode) ? Dynamic.TRUE : Dynamic.FALSE); } } else if (fieldName.equals("type")) { String type = fieldNode.toString(); if (type.equals(CONTENT_TYPE)) { builder.nested = Nested.NO; } else if (type.equals(NESTED_CONTENT_TYPE)) { nested = true; } else { throw new MapperParsingException( "Trying to parse an object but has a different type [" + type + "] for [" + name + "]"); } } else if (fieldName.equals("include_in_parent")) { nestedIncludeInParent = nodeBooleanValue(fieldNode); } else if (fieldName.equals("include_in_root")) { nestedIncludeInRoot = nodeBooleanValue(fieldNode); } else if (fieldName.equals("enabled")) { builder.enabled(nodeBooleanValue(fieldNode)); } else if (fieldName.equals("path")) { builder.pathType(parsePathType(name, fieldNode.toString())); } else if (fieldName.equals("properties")) { parseProperties(builder, (Map<String, Object>) fieldNode, parserContext); } else if (fieldName.equals("include_in_all")) { builder.includeInAll(nodeBooleanValue(fieldNode)); } else { processField(builder, fieldName, fieldNode); } } if (nested) { builder.nested = Nested.newNested(nestedIncludeInParent, nestedIncludeInRoot); } return builder; }
private static ObjectMapper parseObject( final ParseContext context, ObjectMapper mapper, String currentFieldName) throws IOException { if (currentFieldName == null) { throw new MapperParsingException( "object mapping [" + mapper.name() + "] trying to serialize an object with no field associated with it, current value [" + context.parser().textOrNull() + "]"); } context.path().add(currentFieldName); ObjectMapper update = null; Mapper objectMapper = mapper.getMapper(currentFieldName); if (objectMapper != null) { final Mapper subUpdate = parseObjectOrField(context, objectMapper); if (subUpdate != null) { // propagate mapping update update = mapper.mappingUpdate(subUpdate); } } else { ObjectMapper.Dynamic dynamic = mapper.dynamic(); if (dynamic == null) { dynamic = dynamicOrDefault(context.root().dynamic()); } if (dynamic == ObjectMapper.Dynamic.STRICT) { throw new StrictDynamicMappingException(mapper.fullPath(), currentFieldName); } else if (dynamic == ObjectMapper.Dynamic.TRUE) { // remove the current field name from path, since template search and the object builder add // it as well... context.path().remove(); Mapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "object"); if (builder == null) { builder = MapperBuilders.object(currentFieldName).enabled(true); // if this is a non root object, then explicitly set the dynamic behavior if set if (!(mapper instanceof RootObjectMapper) && mapper.dynamic() != ObjectMapper.Defaults.DYNAMIC) { ((ObjectMapper.Builder) builder).dynamic(mapper.dynamic()); } } Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path()); objectMapper = builder.build(builderContext); context.path().add(currentFieldName); update = mapper.mappingUpdate(parseAndMergeUpdate(objectMapper, context)); } else { // not dynamic, read everything up to end object context.parser().skipChildren(); } } context.path().remove(); return update; }
protected static boolean parseObjectProperties( String name, String fieldName, Object fieldNode, ParserContext parserContext, ObjectMapper.Builder builder) { if (fieldName.equals("path") && parserContext.indexVersionCreated().before(Version.V_2_0_0)) { builder.pathType(parsePathType(name, fieldNode.toString())); return true; } return false; }
protected static void parseProperties( ObjectMapper.Builder objBuilder, Map<String, Object> propsNode, ParserContext parserContext) { for (Map.Entry<String, Object> entry : propsNode.entrySet()) { String propName = entry.getKey(); // Should accept empty arrays, as a work around for when the user can't provide an empty // Map. (PHP for example) boolean isEmptyList = entry.getValue() instanceof List && ((List<?>) entry.getValue()).isEmpty(); if (entry.getValue() instanceof Map) { @SuppressWarnings("unchecked") Map<String, Object> propNode = (Map<String, Object>) entry.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { // lets see if we can derive this... if (propNode.get("properties") != null) { type = ObjectMapper.CONTENT_TYPE; } else if (propNode.size() == 1 && propNode.get("enabled") != null) { // if there is a single property with the enabled flag on it, make it an object // (usually, setting enabled to false to not index any type, including core values, // which // non enabled object type supports). type = ObjectMapper.CONTENT_TYPE; } else { throw new MapperParsingException("No type specified for property [" + propName + "]"); } } Mapper.TypeParser typeParser = parserContext.typeParser(type); if (typeParser == null) { throw new MapperParsingException( "No handler for type [" + type + "] declared on field [" + propName + "]"); } objBuilder.add(typeParser.parse(propName, propNode, parserContext)); } else if (!isEmptyList) { throw new MapperParsingException( "Expected map for property [fields] on field [" + propName + "] but got a " + propName.getClass()); } } }
private void parseProperties( ObjectMapper.Builder objBuilder, Map<String, Object> propsNode, ParserContext parserContext) { for (Map.Entry<String, Object> entry : propsNode.entrySet()) { String propName = entry.getKey(); Map<String, Object> propNode = (Map<String, Object>) entry.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { // lets see if we can derive this... if (propNode.get("properties") != null) { type = ObjectMapper.CONTENT_TYPE; } else if (propNode.get("fields") != null) { type = MultiFieldMapper.CONTENT_TYPE; } else if (propNode.size() == 1 && propNode.get("enabled") != null) { // if there is a single property with the enabled flag on it, make it an object // (usually, setting enabled to false to not index any type, including core values, // which // non enabled object type supports). type = ObjectMapper.CONTENT_TYPE; } else { throw new MapperParsingException("No type specified for property [" + propName + "]"); } } Mapper.TypeParser typeParser = parserContext.typeParser(type); if (typeParser == null) { throw new MapperParsingException( "No handler for type [" + type + "] declared on field [" + propName + "]"); } objBuilder.add(typeParser.parse(propName, propNode, parserContext)); } }
protected static void parseProperties( ObjectMapper.Builder objBuilder, Map<String, Object> propsNode, ParserContext parserContext) { Iterator<Map.Entry<String, Object>> iterator = propsNode.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Object> entry = iterator.next(); String propName = entry.getKey(); // Should accept empty arrays, as a work around for when the // user can't provide an empty Map. (PHP for example) boolean isEmptyList = entry.getValue() instanceof List && ((List<?>) entry.getValue()).isEmpty(); if (entry.getValue() instanceof Map) { @SuppressWarnings("unchecked") Map<String, Object> propNode = (Map<String, Object>) entry.getValue(); String type; Object typeNode = propNode.get("type"); if (typeNode != null) { type = typeNode.toString(); } else { // lets see if we can derive this... if (propNode.get("properties") != null) { type = ObjectMapper.CONTENT_TYPE; } else if (propNode.size() == 1 && propNode.get("enabled") != null) { // if there is a single property with the enabled // flag on it, make it an object // (usually, setting enabled to false to not index // any type, including core values, which type = ObjectMapper.CONTENT_TYPE; } else { throw new MapperParsingException("No type specified for property [" + propName + "]"); } } Mapper.TypeParser typeParser = parserContext.typeParser(type); if (typeParser == null) { throw new MapperParsingException( "No handler for type [" + type + "] declared on field [" + propName + "]"); } objBuilder.add(typeParser.parse(propName, propNode, parserContext)); propNode.remove("type"); DocumentMapperParser.checkNoRemainingFields( propName, propNode, parserContext.indexVersionCreated()); iterator.remove(); } else if (isEmptyList) { iterator.remove(); } else { throw new MapperParsingException( "Expected map for property [fields] on field [" + propName + "] but got a " + propName.getClass()); } } DocumentMapperParser.checkNoRemainingFields( propsNode, parserContext.indexVersionCreated(), "DocType mapping definition has unsupported parameters: "); }
/** Creates an copy of the current field with given field name and boost */ private static void parseCopy(String field, ParseContext context) throws IOException { FieldMapper fieldMapper = context.docMapper().mappers().getMapper(field); if (fieldMapper != null) { fieldMapper.parse(context); } else { // The path of the dest field might be completely different from the current one so we need to // reset it context = context.overridePath(new ContentPath(0)); String[] paths = Strings.splitStringToArray(field, '.'); String fieldName = paths[paths.length - 1]; ObjectMapper mapper = context.root(); ObjectMapper[] mappers = new ObjectMapper[paths.length - 1]; if (paths.length > 1) { ObjectMapper parent = context.root(); for (int i = 0; i < paths.length - 1; i++) { mapper = context.docMapper().objectMappers().get(context.path().pathAsText(paths[i])); if (mapper == null) { // One mapping is missing, check if we are allowed to create a dynamic one. ObjectMapper.Dynamic dynamic = parent.dynamic(); if (dynamic == null) { dynamic = dynamicOrDefault(context.root().dynamic()); } switch (dynamic) { case STRICT: throw new StrictDynamicMappingException(parent.fullPath(), paths[i]); case TRUE: Mapper.Builder builder = context.root().findTemplateBuilder(context, paths[i], "object"); if (builder == null) { // if this is a non root object, then explicitly set the dynamic behavior if set if (!(parent instanceof RootObjectMapper) && parent.dynamic() != ObjectMapper.Defaults.DYNAMIC) { ((ObjectMapper.Builder) builder).dynamic(parent.dynamic()); } builder = MapperBuilders.object(paths[i]).enabled(true); } Mapper.BuilderContext builderContext = new Mapper.BuilderContext(context.indexSettings(), context.path()); mapper = (ObjectMapper) builder.build(builderContext); if (mapper.nested() != ObjectMapper.Nested.NO) { throw new MapperParsingException( "It is forbidden to create dynamic nested objects ([" + context.path().pathAsText(paths[i]) + "]) through `copy_to`"); } break; case FALSE: // Maybe we should log something to tell the user that the copy_to is ignored in // this case. break; default: throw new AssertionError("Unexpected dynamic type " + dynamic); } } context.path().add(paths[i]); mappers[i] = mapper; parent = mapper; } } ObjectMapper update = parseDynamicValue(context, mapper, fieldName, context.parser().currentToken()); assert update != null; // we are parsing a dynamic value so we necessarily created a new mapping if (paths.length > 1) { for (int i = paths.length - 2; i >= 0; i--) { ObjectMapper parent = context.root(); if (i > 0) { parent = mappers[i - 1]; } assert parent != null; update = parent.mappingUpdate(update); } } context.addDynamicMappingsUpdate(update); } }
protected static void parseObjectProperties( String name, String fieldName, Object fieldNode, ObjectMapper.Builder builder) { if (fieldName.equals("path")) { builder.pathType(parsePathType(name, fieldNode.toString())); } }