diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java b/modules/elasticsearch/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java index 7fec8bf353b..65d73122c18 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java @@ -281,7 +281,7 @@ public class IndexMetaData { for (Map.Entry entry : indexMetaData.mappings().entrySet()) { byte[] data = entry.getValue().source().uncompressed(); XContentParser parser = XContentFactory.xContent(data).createParser(data); - Map mapping = parser.map(); + Map mapping = parser.mapOrdered(); parser.close(); builder.map(mapping); } @@ -310,7 +310,7 @@ public class IndexMetaData { builder.settings(settingsBuilder.build()); } else if ("mappings".equals(currentFieldName)) { while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - Map mapping = parser.map(); + Map mapping = parser.mapOrdered(); if (mapping.size() == 1) { String mappingType = mapping.keySet().iterator().next(); builder.putMapping(new MappingMetaData(mappingType, mapping)); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentParser.java index ffe02be9206..ba31b2795d0 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentParser.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/XContentParser.java @@ -108,6 +108,8 @@ public interface XContentParser { Map map() throws IOException; + Map mapOrdered() throws IOException; + Map mapAndClose() throws IOException; String text() throws IOException; diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/support/AbstractXContentParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/support/AbstractXContentParser.java index d1dba465f81..43cdf040040 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/support/AbstractXContentParser.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/support/AbstractXContentParser.java @@ -103,6 +103,10 @@ public abstract class AbstractXContentParser implements XContentParser { return XContentMapConverter.readMap(this); } + @Override public Map mapOrdered() throws IOException { + return XContentMapConverter.readOrderedMap(this); + } + @Override public Map mapAndClose() throws IOException { try { return map(); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/support/XContentMapConverter.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/support/XContentMapConverter.java index 5024ec1e8a2..8017eac0021 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/support/XContentMapConverter.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/support/XContentMapConverter.java @@ -31,8 +31,32 @@ import java.util.*; */ public class XContentMapConverter { + public static interface MapFactory { + Map newMap(); + } + + public static final MapFactory SIMPLE_MAP_FACTORY = new MapFactory() { + @Override public Map newMap() { + return new HashMap(); + } + }; + + public static final MapFactory ORDERED_MAP_FACTORY = new MapFactory() { + @Override public Map newMap() { + return new LinkedHashMap(); + } + }; + public static Map readMap(XContentParser parser) throws IOException { - Map map = new HashMap(); + return readMap(parser, SIMPLE_MAP_FACTORY); + } + + public static Map readOrderedMap(XContentParser parser) throws IOException { + return readMap(parser, ORDERED_MAP_FACTORY); + } + + public static Map readMap(XContentParser parser, MapFactory mapFactory) throws IOException { + Map map = mapFactory.newMap(); XContentParser.Token t = parser.currentToken(); if (t == null) { t = parser.nextToken(); @@ -45,21 +69,21 @@ public class XContentMapConverter { String fieldName = parser.currentName(); // And then the value... t = parser.nextToken(); - Object value = readValue(parser, t); + Object value = readValue(parser, mapFactory, t); map.put(fieldName, value); } return map; } - private static List readList(XContentParser parser, XContentParser.Token t) throws IOException { + private static List readList(XContentParser parser, MapFactory mapFactory, XContentParser.Token t) throws IOException { ArrayList list = new ArrayList(); while ((t = parser.nextToken()) != XContentParser.Token.END_ARRAY) { - list.add(readValue(parser, t)); + list.add(readValue(parser, mapFactory, t)); } return list; } - private static Object readValue(XContentParser parser, XContentParser.Token t) throws IOException { + private static Object readValue(XContentParser parser, MapFactory mapFactory, XContentParser.Token t) throws IOException { if (t == XContentParser.Token.VALUE_NULL) { return null; } else if (t == XContentParser.Token.VALUE_STRING) { @@ -78,9 +102,9 @@ public class XContentMapConverter { } else if (t == XContentParser.Token.VALUE_BOOLEAN) { return parser.booleanValue(); } else if (t == XContentParser.Token.START_OBJECT) { - return readMap(parser); + return readMap(parser, mapFactory); } else if (t == XContentParser.Token.START_ARRAY) { - return readList(parser, t); + return readList(parser, mapFactory, t); } return null; }