/** Creates an update for intermediate object mappers that are not on the stack, but parents of newMapper. */ private static ObjectMapper createExistingMapperUpdate(List<ObjectMapper> parentMappers, String[] nameParts, int i, DocumentMapper docMapper, Mapper newMapper) { String updateParentName = nameParts[i]; final ObjectMapper lastParent = parentMappers.get(parentMappers.size() - 1); if (parentMappers.size() > 1) { // only prefix with parent mapper if the parent mapper isn't the root (which has a fake name) updateParentName = lastParent.name() + '.' + nameParts[i]; } ObjectMapper updateParent = docMapper.objectMappers().get(updateParentName); assert updateParent != null : updateParentName + " doesn't exist"; return createUpdate(updateParent, nameParts, i + 1, newMapper); }
@Override public ObjectMapper merge(Mapper mergeWith, boolean updateAllTypes) { if (!(mergeWith instanceof ObjectMapper)) { throw new IllegalArgumentException("Can't merge a non object mapping [" + mergeWith.name() + "] with an object mapping [" + name() + "]"); } ObjectMapper mergeWithObject = (ObjectMapper) mergeWith; ObjectMapper merged = clone(); merged.doMerge(mergeWithObject, updateAllTypes); return merged; }
/** Build an update for the parent which will contain the given mapper and any intermediate fields. */ private static ObjectMapper createUpdate(ObjectMapper parent, String[] nameParts, int i, Mapper mapper) { List<ObjectMapper> parentMappers = new ArrayList<>(); ObjectMapper previousIntermediate = parent; for (; i < nameParts.length - 1; ++i) { Mapper intermediate = previousIntermediate.getMapper(nameParts[i]); assert intermediate != null : "Field " + previousIntermediate.name() + " does not have a subfield " + nameParts[i]; assert intermediate instanceof ObjectMapper; parentMappers.add((ObjectMapper)intermediate); previousIntermediate = (ObjectMapper)intermediate; } if (parentMappers.isEmpty() == false) { // add the new mapper to the stack, and pop down to the original parent level addToLastMapper(parentMappers, mapper, false); popMappers(parentMappers, 1, false); mapper = parentMappers.get(0); } return parent.mappingUpdate(mapper); }
private static ObjectMapper.Dynamic dynamicOrDefault(ObjectMapper parentMapper, ParseContext context) { ObjectMapper.Dynamic dynamic = parentMapper.dynamic(); while (dynamic == null) { int lastDotNdx = parentMapper.name().lastIndexOf('.'); if (lastDotNdx == -1) { // no dot means we the parent is the root, so just delegate to the default outside the loop break; } String parentName = parentMapper.name().substring(0, lastDotNdx); parentMapper = context.docMapper().objectMappers().get(parentName); if (parentMapper == null) { // If parentMapper is ever null, it means the parent of the current mapper was dynamically created. // But in order to be created dynamically, the dynamic setting of that parent was necessarily true return ObjectMapper.Dynamic.TRUE; } dynamic = parentMapper.dynamic(); } if (dynamic == null) { return context.root().dynamic() == null ? ObjectMapper.Dynamic.TRUE : context.root().dynamic(); } return dynamic; }
protected void doMerge(final ObjectMapper mergeWith, boolean updateAllTypes) { if (nested().isNested()) { if (!mergeWith.nested().isNested()) { throw new IllegalArgumentException("object mapping [" + name() + "] can't be changed from nested to non-nested"); } } else { if (mergeWith.nested().isNested()) { throw new IllegalArgumentException("object mapping [" + name() + "] can't be changed from non-nested to nested"); } } this.includeInAll = mergeWith.includeInAll; if (mergeWith.dynamic != null) { this.dynamic = mergeWith.dynamic; } for (Mapper mergeWithMapper : mergeWith) { Mapper mergeIntoMapper = mappers.get(mergeWithMapper.simpleName()); checkEnabledFieldChange(mergeWith, mergeWithMapper, mergeIntoMapper); Mapper merged; if (mergeIntoMapper == null) { // no mapping, simply add it merged = mergeWithMapper; } else { // root mappers can only exist here for backcompat, and are merged in Mapping merged = mergeIntoMapper.merge(mergeWithMapper, updateAllTypes); } putMapper(merged); } }
private static void parseNonDynamicArray(ParseContext context, ObjectMapper mapper, String lastFieldName, String arrayFieldName) throws IOException { XContentParser parser = context.parser(); XContentParser.Token token; while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { if (token == XContentParser.Token.START_OBJECT) { parseObject(context, mapper, lastFieldName); } else if (token == XContentParser.Token.START_ARRAY) { parseArray(context, mapper, lastFieldName); } else if (token == XContentParser.Token.FIELD_NAME) { lastFieldName = parser.currentName(); } else if (token == XContentParser.Token.VALUE_NULL) { parseNullValue(context, mapper, lastFieldName); } else if (token == null) { throw new MapperParsingException("object mapping for [" + mapper.name() + "] with array for [" + arrayFieldName + "] tried to parse as array, but got EOF, is there a mismatch in types for the same field?"); } else { parseValue(context, mapper, lastFieldName, token); } } }
nestedObjectMapper.name() + "] are not nested. All parent fields need to be nested fields too");
ObjectMapper nestedParentObjectMapper; ObjectMapper current = nestedObjectMapper; String originalName = nestedObjectMapper.name(); SearchHit.NestedIdentity nestedIdentity = null; final IndexSettings indexSettings = context.getQueryShardContext().getIndexSettings(); int currentPrefix = current == null ? 0 : current.name().length() + 1; nestedIdentity = new SearchHit.NestedIdentity(originalName.substring(currentPrefix), offset, nestedIdentity); if (current != null) { originalName = current.name();
private static void parseValue(final ParseContext context, ObjectMapper parentMapper, String currentFieldName, XContentParser.Token token) throws IOException { if (currentFieldName == null) { throw new MapperParsingException("object mapping [" + parentMapper.name() + "] trying to serialize a value with" + " no field associated with it, current value [" + context.parser().textOrNull() + "]"); } final String[] paths = splitAndValidatePath(currentFieldName); Mapper mapper = getMapper(parentMapper, currentFieldName, paths); if (mapper != null) { parseObjectOrField(context, mapper); } else { currentFieldName = paths[paths.length - 1]; Tuple<Integer, ObjectMapper> parentMapperTuple = getDynamicParentMapper(context, paths, parentMapper); parentMapper = parentMapperTuple.v2(); parseDynamicValue(context, parentMapper, currentFieldName, token); for (int i = 0; i < parentMapperTuple.v1(); i++) { context.path().remove(); } } }
private static void innerParseObject(ParseContext context, ObjectMapper mapper, XContentParser parser, String currentFieldName, XContentParser.Token token) throws IOException { while (token != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.START_OBJECT) { parseObject(context, mapper, currentFieldName); } else if (token == XContentParser.Token.START_ARRAY) { parseArray(context, mapper, currentFieldName); } else if (token == XContentParser.Token.FIELD_NAME) { currentFieldName = parser.currentName(); if (MapperService.isMetadataField(context.path().pathAsText(currentFieldName))) { throw new MapperParsingException("Field [" + currentFieldName + "] is a metadata field and cannot be added inside" + " a document. Use the index API request parameters."); } } else if (token == XContentParser.Token.VALUE_NULL) { parseNullValue(context, mapper, currentFieldName); } else if (token == null) { throw new MapperParsingException("object mapping for [" + mapper.name() + "] tried to parse field [" + currentFieldName + "] as object, but got EOF, has a concrete value been provided to it?"); } else if (token.isValue()) { parseValue(context, mapper, currentFieldName, token); } token = parser.nextToken(); } }
/** Creates an update for intermediate object mappers that are not on the stack, but parents of newMapper. */ private static ObjectMapper createExistingMapperUpdate(List<ObjectMapper> parentMappers, String[] nameParts, int i, DocumentMapper docMapper, Mapper newMapper) { String updateParentName = nameParts[i]; final ObjectMapper lastParent = parentMappers.get(parentMappers.size() - 1); if (parentMappers.size() > 1) { // only prefix with parent mapper if the parent mapper isn't the root (which has a fake name) updateParentName = lastParent.name() + '.' + nameParts[i]; } ObjectMapper updateParent = docMapper.objectMappers().get(updateParentName); assert updateParent != null : updateParentName + " doesn't exist"; return createUpdate(updateParent, nameParts, i + 1, newMapper); }
/** Creates an update for intermediate object mappers that are not on the stack, but parents of newMapper. */ private static ObjectMapper createExistingMapperUpdate(List<ObjectMapper> parentMappers, String[] nameParts, int i, DocumentMapper docMapper, Mapper newMapper) { String updateParentName = nameParts[i]; final ObjectMapper lastParent = parentMappers.get(parentMappers.size() - 1); if (parentMappers.size() > 1) { // only prefix with parent mapper if the parent mapper isn't the root (which has a fake name) updateParentName = lastParent.name() + '.' + nameParts[i]; } ObjectMapper updateParent = docMapper.objectMappers().get(updateParentName); assert updateParent != null : updateParentName + " doesn't exist"; return createUpdate(updateParent, nameParts, i + 1, newMapper); }
/** Creates an update for intermediate object mappers that are not on the stack, but parents of newMapper. */ private static ObjectMapper createExistingMapperUpdate(List<ObjectMapper> parentMappers, String[] nameParts, int i, DocumentMapper docMapper, Mapper newMapper) { String updateParentName = nameParts[i]; final ObjectMapper lastParent = parentMappers.get(parentMappers.size() - 1); if (parentMappers.size() > 1) { // only prefix with parent mapper if the parent mapper isn't the root (which has a fake name) updateParentName = lastParent.name() + '.' + nameParts[i]; } ObjectMapper updateParent = docMapper.objectMappers().get(updateParentName); assert updateParent != null : updateParentName + " doesn't exist"; return createUpdate(updateParent, nameParts, i + 1, newMapper); }
throw new MapperParsingException("object mapping for [" + mapper.name() + "] tried to parse field [" + currentFieldName + "] as object, but found a concrete value");
@Override public ObjectMapper merge(Mapper mergeWith, boolean updateAllTypes) { if (!(mergeWith instanceof ObjectMapper)) { throw new IllegalArgumentException("Can't merge a non object mapping [" + mergeWith.name() + "] with an object mapping [" + name() + "]"); } ObjectMapper mergeWithObject = (ObjectMapper) mergeWith; ObjectMapper merged = clone(); merged.doMerge(mergeWithObject, updateAllTypes); return merged; }
@Override public ObjectMapper merge(Mapper mergeWith, boolean updateAllTypes) { if (!(mergeWith instanceof ObjectMapper)) { throw new IllegalArgumentException("Can't merge a non object mapping [" + mergeWith.name() + "] with an object mapping [" + name() + "]"); } ObjectMapper mergeWithObject = (ObjectMapper) mergeWith; ObjectMapper merged = clone(); merged.doMerge(mergeWithObject, updateAllTypes); return merged; }
@Override public ObjectMapper merge(Mapper mergeWith, boolean updateAllTypes) { if (!(mergeWith instanceof ObjectMapper)) { throw new IllegalArgumentException("Can't merge a non object mapping [" + mergeWith.name() + "] with an object mapping [" + name() + "]"); } ObjectMapper mergeWithObject = (ObjectMapper) mergeWith; ObjectMapper merged = clone(); merged.doMerge(mergeWithObject, updateAllTypes); return merged; }
private static void parseNonDynamicArray(ParseContext context, ObjectMapper mapper, String lastFieldName, String arrayFieldName) throws IOException { XContentParser parser = context.parser(); XContentParser.Token token; while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { if (token == XContentParser.Token.START_OBJECT) { parseObject(context, mapper, lastFieldName); } else if (token == XContentParser.Token.START_ARRAY) { parseArray(context, mapper, lastFieldName); } else if (token == XContentParser.Token.FIELD_NAME) { lastFieldName = parser.currentName(); } else if (token == XContentParser.Token.VALUE_NULL) { parseNullValue(context, mapper, lastFieldName); } else if (token == null) { throw new MapperParsingException("object mapping for [" + mapper.name() + "] with array for [" + arrayFieldName + "] tried to parse as array, but got EOF, is there a mismatch in types for the same field?"); } else { parseValue(context, mapper, lastFieldName, token); } } }
private static void parseValue(final ParseContext context, ObjectMapper parentMapper, String currentFieldName, XContentParser.Token token) throws IOException { if (currentFieldName == null) { throw new MapperParsingException("object mapping [" + parentMapper.name() + "] trying to serialize a value with no field associated with it, current value [" + context.parser().textOrNull() + "]"); } final String[] paths = splitAndValidatePath(currentFieldName); Mapper mapper = getMapper(parentMapper, currentFieldName, paths); if (mapper != null) { parseObjectOrField(context, mapper); } else { currentFieldName = paths[paths.length - 1]; Tuple<Integer, ObjectMapper> parentMapperTuple = getDynamicParentMapper(context, paths, parentMapper); parentMapper = parentMapperTuple.v2(); parseDynamicValue(context, parentMapper, currentFieldName, token); for (int i = 0; i < parentMapperTuple.v1(); i++) { context.path().remove(); } } }
private static void parseValue(final ParseContext context, ObjectMapper parentMapper, String currentFieldName, XContentParser.Token token) throws IOException { if (currentFieldName == null) { throw new MapperParsingException("object mapping [" + parentMapper.name() + "] trying to serialize a value with no field associated with it, current value [" + context.parser().textOrNull() + "]"); } Mapper mapper = getMapper(parentMapper, currentFieldName); if (mapper != null) { parseObjectOrField(context, mapper); } else { final String[] paths = splitAndValidatePath(currentFieldName); currentFieldName = paths[paths.length - 1]; Tuple<Integer, ObjectMapper> parentMapperTuple = getDynamicParentMapper(context, paths, parentMapper); parentMapper = parentMapperTuple.v2(); parseDynamicValue(context, parentMapper, currentFieldName, token); for (int i = 0; i < parentMapperTuple.v1(); i++) { context.path().remove(); } } }