Iterate over XML namespaces deterministically.
package com.google.devtools.build.android.xml;
import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSortedMap;
import com.google.devtools.build.android.DataResourceXml;
import com.google.devtools.build.android.XmlResourceValue;
import com.google.devtools.build.android.XmlResourceValues;
@@ -41,7 +41,7 @@ import javax.xml.stream.events.StartElement;
public class Namespaces implements Iterable<Map.Entry<String, String>> {
private static final Logger logger = Logger.getLogger(Namespaces.class.getCanonicalName());
private static final Namespaces EMPTY_INSTANCE =
- new Namespaces(ImmutableMap.<String, String>of());
+ new Namespaces(ImmutableSortedMap.<String, String>of());
/** Collects prefix and uri pairs from elements. */
public static class Collector {
@@ -93,7 +93,7 @@ public class Namespaces implements Iterable<Map.Entry<String, String>> {
if (prefixToUri.isEmpty()) {
return empty();
}
- return new Namespaces(ImmutableMap.copyOf(prefixToUri));
+ return new Namespaces(ImmutableSortedMap.copyOf(prefixToUri));
}
/**
@@ -104,16 +104,18 @@ public class Namespaces implements Iterable<Map.Entry<String, String>> {
if (name.getPrefix().isEmpty()) {
return empty();
}
- return new Namespaces(ImmutableMap.of(name.getPrefix(), name.getNamespaceURI()));
+ return new Namespaces(ImmutableSortedMap.of(name.getPrefix(), name.getNamespaceURI()));
}
public static Namespaces empty() {
return EMPTY_INSTANCE;
}
- private ImmutableMap<String, String> prefixToUri;
+ // Keep the prefixes in a sorted map so that when this object is iterated over, the order is
+ // deterministic.
+ private final ImmutableSortedMap<String, String> prefixToUri;
- private Namespaces(ImmutableMap<String, String> prefixToUri) {
+ private Namespaces(ImmutableSortedMap<String, String> prefixToUri) {
this.prefixToUri = prefixToUri;
}
