public synchronized MergeResult merge(DocumentMapper mergeWith, MergeFlags mergeFlags) { MergeContext mergeContext = new MergeContext(this, mergeFlags); rootObjectMapper.merge(mergeWith.rootObjectMapper, mergeContext); for (Map.Entry<Class<? extends RootMapper>, RootMapper> entry : rootMappers.entrySet()) { // root mappers included in root object will get merge in the rootObjectMapper if (entry.getValue().includeInObject()) { continue; } RootMapper mergeWithRootMapper = mergeWith.rootMappers.get(entry.getKey()); if (mergeWithRootMapper != null) { entry.getValue().merge(mergeWithRootMapper, mergeContext); } } if (!mergeFlags.simulate()) { if (!mergeContext.newFieldMappers().mappers.isEmpty()) { addFieldMappers(mergeContext.newFieldMappers().mappers); } if (!mergeContext.newObjectMappers().mappers.isEmpty()) { addObjectMappers(mergeContext.newObjectMappers().mappers); } // let the merge with attributes to override the attributes meta = mergeWith.meta(); // update the source of the merged one refreshSource(); } return new MergeResult(mergeContext.buildConflicts()); }
@Override public void merge(final Mapper mergeWith, final MergeContext mergeContext) throws MergeMappingException { if (!(mergeWith instanceof ObjectMapper)) { mergeContext.addConflict( "Can't merge a non object mapping [" + mergeWith.name() + "] with an object mapping [" + name() + "]"); return; } ObjectMapper mergeWithObject = (ObjectMapper) mergeWith; if (nested().isNested()) { if (!mergeWithObject.nested().isNested()) { mergeContext.addConflict( "object mapping [" + name() + "] can't be changed from nested to non-nested"); return; } } else { if (mergeWithObject.nested().isNested()) { mergeContext.addConflict( "object mapping [" + name() + "] can't be changed from non-nested to nested"); return; } } doMerge(mergeWithObject, mergeContext); List<Mapper> mappersToTraverse = new ArrayList<Mapper>(); synchronized (mutex) { for (Mapper mergeWithMapper : mergeWithObject.mappers.values()) { Mapper mergeIntoMapper = mappers.get(mergeWithMapper.name()); if (mergeIntoMapper == null) { // no mapping, simply add it if not simulating if (!mergeContext.mergeFlags().simulate()) { putMapper(mergeWithMapper); mappersToTraverse.add(mergeWithMapper); } } else { if ((mergeWithMapper instanceof MultiFieldMapper) && !(mergeIntoMapper instanceof MultiFieldMapper)) { MultiFieldMapper mergeWithMultiField = (MultiFieldMapper) mergeWithMapper; mergeWithMultiField.merge(mergeIntoMapper, mergeContext); if (!mergeContext.mergeFlags().simulate()) { putMapper(mergeWithMultiField); // now, record mappers to traverse events for all mappers for (Mapper mapper : mergeWithMultiField.mappers().values()) { mappersToTraverse.add(mapper); } } } else { mergeIntoMapper.merge(mergeWithMapper, mergeContext); } } } } // call this outside of the mutex for (Mapper mapper : mappersToTraverse) { mapper.traverse(mergeContext.newFieldMappers()); mapper.traverse(mergeContext.newObjectMappers()); } }