*/
package org.opendaylight.yangtools.yang.data.api;\r
\r
-import java.io.Serializable;\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.opendaylight.yangtools.concepts.Builder;\r
-import org.opendaylight.yangtools.concepts.Immutable;\r
-import org.opendaylight.yangtools.concepts.Path;\r
-import org.opendaylight.yangtools.yang.common.QName;\r
-\r
-import com.google.common.collect.ImmutableList;\r
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.concepts.Path;
+import org.opendaylight.yangtools.yang.common.QName;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
\r
public class InstanceIdentifier implements Path<InstanceIdentifier>, Immutable, Serializable {\r
\r
private static final long serialVersionUID = 8467409862384206193L;\r
private final List<PathArgument> path;\r
\r
- private transient String to_string_cache = null;\r
+ private transient String toStringCache = null;
+ private transient Integer hashCodeCache = null;\r
\r
public List<PathArgument> getPath() {\r
return path;\r
}\r
\r
@Override\r
- public int hashCode() {\r
- final int prime = 31;\r
- int result = 1;\r
- result = prime * result + ((path == null) ? 0 : path.hashCode());\r
- return result;\r
+ public int hashCode() {
+ /*
+ * The hashCodeCache is safe, since the object contract requires immutability
+ * of the object and all objects referenced from this object.
+ *
+ * Used lists, maps are immutable. Path Arguments (elements) are also immutable,
+ * since the PathArgument contract requires immutability.
+ *
+ * The cache is thread-safe - if multiple computations occurs at the same time,
+ * cache will be overwritten with same result.
+ */
+ if(hashCodeCache == null) {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((path == null) ? 0 : path.hashCode());
+ hashCodeCache = result;
+ }
+ return hashCodeCache;\r
}\r
\r
@Override\r
public boolean equals(Object obj) {\r
- if (this == obj)\r
+ if (this == obj) {\r
return true;\r
- if (obj == null)\r
- return false;\r
- if (getClass() != obj.getClass())\r
- return false;\r
- InstanceIdentifier other = (InstanceIdentifier) obj;\r
+ }
+ if (obj == null) {\r
+ return false;
+ }\r
+ if (getClass() != obj.getClass()) {\r
+ return false;
+ }\r
+ InstanceIdentifier other = (InstanceIdentifier) obj;
+ if(this.hashCode() != obj.hashCode()) {
+ return false;
+ }\r
if (path == null) {\r
- if (other.path != null)\r
- return false;\r
- } else if (!path.equals(other.path))\r
- return false;\r
+ if (other.path != null) {\r
+ return false;
+ }\r
+ } else if (!path.equals(other.path)) {\r
+ return false;
+ }\r
return true;\r
}\r
\r
public static final class NodeIdentifier implements PathArgument {\r
\r
/**\r
- * \r
+ *\r
*/\r
private static final long serialVersionUID = -2255888212390871347L;\r
\r
this.nodeType = node;\r
}\r
\r
+ @Override
public QName getNodeType() {\r
return nodeType;\r
}\r
public static final class NodeIdentifierWithPredicates implements PathArgument {\r
\r
/**\r
- * \r
+ *\r
*/\r
private static final long serialVersionUID = -4787195606494761540L;\r
\r
\r
public NodeIdentifierWithPredicates(QName node, Map<QName, Object> keyValues) {\r
this.nodeType = node;\r
- this.keyValues = Collections.unmodifiableMap(new HashMap<QName, Object>(keyValues));\r
+ this.keyValues = ImmutableMap.copyOf(keyValues);\r
}\r
\r
public NodeIdentifierWithPredicates(QName node, QName key, Object value) {\r
this.nodeType = node;\r
- this.keyValues = Collections.singletonMap(key, value);\r
+ this.keyValues = ImmutableMap.of(key, value);\r
}\r
\r
@Override\r
public static final class NodeWithValue implements PathArgument {
/**
- *
+ *
*/
private static final long serialVersionUID = -3637456085341738431L;
\r
private static class BuilderImpl implements InstanceIdentifierBuilder {\r
\r
- private final ImmutableList.Builder<PathArgument> path; \r
+ private final ImmutableList.Builder<PathArgument> path;\r
\r
public BuilderImpl() {\r
path = ImmutableList.<PathArgument>builder();\r
}\r
\r
@Override\r
- public String toString() {\r
- if (to_string_cache != null) {\r
- return to_string_cache;\r
+ public String toString() {
+ /*
+ * The toStringCache is safe, since the object contract requires immutability
+ * of the object and all objects referenced from this object.
+ *
+ * Used lists, maps are immutable. Path Arguments (elements) are also immutable,
+ * since the PathArgument contract requires immutability.
+ *
+ * The cache is thread-safe - if multiple computations occurs at the same time,
+ * cache will be overwritten with same result.
+ */\r
+ if (toStringCache != null) {\r
+ return toStringCache;\r
}\r
StringBuilder builder = new StringBuilder();\r
for (PathArgument argument : path) {\r
builder.append("/");\r
builder.append(argument.toString());\r
}\r
- to_string_cache = builder.toString();\r
- return to_string_cache;\r
+ toStringCache = builder.toString();\r
+ return toStringCache;\r
}\r
\r
public static InstanceIdentifierBuilder builder(QName node) {\r