Merge "Use resolved augmentation schema instead of original schema."
authorRobert Varga <rovarga@cisco.com>
Mon, 1 Sep 2014 19:53:10 +0000 (19:53 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 1 Sep 2014 19:53:10 +0000 (19:53 +0000)
22 files changed:
code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java
common/parent/pom.xml
yang/yang-data-codec-gson/pom.xml
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/CodecFactory.java [new file with mode: 0644]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONNormalizedNodeStreamWriter.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStringIdentityrefCodec.java [new file with mode: 0644]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStringInstanceIdentifierCodec.java [new file with mode: 0644]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JsonParserStream.java
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/AbstractCodecImpl.java [deleted file]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/IdentityValuesDTO.java [deleted file]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/IdentityrefCodecImpl.java [deleted file]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/InstanceIdentifierCodecImpl.java [deleted file]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/LeafrefCodecImpl.java [deleted file]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/ObjectCodec.java [deleted file]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/RestCodecFactory.java [deleted file]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/RestUtil.java [deleted file]
yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/SchemaContextUtils.java [deleted file]
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractModuleStringIdentityrefCodec.java [new file with mode: 0644]
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractModuleStringInstanceIdentifierCodec.java [new file with mode: 0644]
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractNamespaceCodec.java [new file with mode: 0644]
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringIdentityrefCodec.java [new file with mode: 0644]
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java [new file with mode: 0644]

index f1864ab1b7e5af44810b1dd9a07d5d1e81e52d6a..d48046a48b23bc76cb174d92fe70b0e9d68f686d 100644 (file)
@@ -1299,9 +1299,10 @@ public final class TypeProviderImpl implements TypeProvider {
             }
             typeDefinitionsConcreteDepth.add(unsortedTypeDefinition);
         }
-        // keys are in ascending order
-        for (Map.Entry<Integer, List<TypeDefinition<?>>> entry : typeDefinitionsDepths.entrySet()) {
-            sortedTypeDefinition.addAll(entry.getValue());
+
+        // SortedMap guarantees order corresponding to keys in ascending order
+        for (List<TypeDefinition<?>> v : typeDefinitionsDepths.values()) {
+            sortedTypeDefinition.addAll(v);
         }
 
         return sortedTypeDefinition;
index a22fe9000669ffdb048dc51374e434efc9d1bc44..15e887eb44655c77b23cda83d934afe5e5c1bc10 100644 (file)
         <repository>
             <id>opendaylight-mirror</id>
             <name>opendaylight-mirror</name>
-            <url>http://nexus.opendaylight.org/content/groups/public/</url>
+            <url>${nexusproxy}/groups/public/</url>
             <snapshots>
                 <enabled>false</enabled>
             </snapshots>
         <repository>
             <id>opendaylight-snapshot</id>
             <name>opendaylight-snapshot</name>
-            <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+            <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
             <snapshots>
                 <enabled>true</enabled>
             </snapshots>
index c8e17199064fc3766dc5ad80428badb0f8e3e4aa..6947a8121147cd5d05de5f73d7b11fdc620d738b 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-data-impl</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-util</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-parser-impl</artifactId>
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/CodecFactory.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/CodecFactory.java
new file mode 100644 (file)
index 0000000..dba5ed7
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import com.google.common.annotations.Beta;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.IdentityrefType;
+import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class is implementation-internal and subject to change. Please do not use it.
+ */
+@Beta
+final class CodecFactory {
+    private static final Logger LOG = LoggerFactory.getLogger(CodecFactory.class);
+    private static final Codec<?, ?> LEAFREF_DEFAULT_CODEC = new LeafrefCodec<String>() {
+        @Override
+        public String serialize(final Object data) {
+            return String.valueOf(data);
+        }
+
+        @Override
+        public Object deserialize(final String data) {
+            return data;
+        }
+    };
+    private static final Codec<?, ?> NULL_CODEC = new Codec<Object, Object>() {
+        @Override
+        public Object deserialize(final Object input) {
+            return null;
+        }
+
+        @Override
+        public Object serialize(final Object input) {
+            return null;
+        }
+    };
+
+
+    private static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
+        TypeDefinition<?> superType = type;
+        while (superType.getBaseType() != null) {
+            superType = superType.getBaseType();
+        }
+        return superType;
+    }
+
+    private final LoadingCache<TypeDefinition<?>, Codec<?, ?>> codecs =
+            CacheBuilder.newBuilder().softValues().build(new CacheLoader<TypeDefinition<?>, Codec<?, ?>>() {
+        @Override
+        public Codec<?, ?> load(final TypeDefinition<?> key) throws Exception {
+            final TypeDefinition<?> type = resolveBaseTypeFrom(key);
+
+            if (type instanceof InstanceIdentifierType) {
+                return iidCodec;
+            }
+            if (type instanceof IdentityrefType) {
+                return idrefCodec;
+            }
+            if (type instanceof LeafrefTypeDefinition) {
+                return LEAFREF_DEFAULT_CODEC;
+            }
+
+            final TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> codec = TypeDefinitionAwareCodec.from(type);
+            if (codec == null) {
+                LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName());
+                return NULL_CODEC;
+            }
+
+            return codec;
+        }
+    });
+
+    private final Codec<?, ?> iidCodec;
+    private final Codec<?, ?> idrefCodec;
+
+    private CodecFactory(final SchemaContext context) {
+        iidCodec = new JSONStringInstanceIdentifierCodec(context);
+        idrefCodec = new JSONStringIdentityrefCodec(context);
+    }
+
+    public static CodecFactory create(final SchemaContext context) {
+        return new CodecFactory(context);
+    }
+
+    @SuppressWarnings("unchecked")
+    public final Codec<Object, Object> codecFor(final TypeDefinition<?> typeDefinition) {
+        return (Codec<Object, Object>) codecs.getUnchecked(typeDefinition);
+    }
+}
index aa4936a595f6b67525145d6396cfeda00a677363..b03771d4c49698c676e1feb2f332a6c4257a29fc 100644 (file)
@@ -22,8 +22,6 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.Augmentat
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.RestCodecFactory;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.SchemaContextUtils;
 import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
@@ -75,8 +73,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
 
     private final Deque<TypeInfo> stack = new ArrayDeque<>();
     private final SchemaContext schemaContext;
-    private final SchemaContextUtils utils;
-    private final RestCodecFactory codecs;
+    private final CodecFactory codecs;
     private final SchemaTracker tracker;
     private final Writer writer;
     private final String indent;
@@ -96,8 +93,7 @@ public class JSONNormalizedNodeStreamWriter implements NormalizedNodeStreamWrite
             indent = null;
         }
 
-        this.utils = SchemaContextUtils.create(schemaContext);
-        this.codecs = RestCodecFactory.create(utils);
+        this.codecs = CodecFactory.create(schemaContext);
         this.tracker = SchemaTracker.create(schemaContext);
     }
 
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStringIdentityrefCodec.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStringIdentityrefCodec.java
new file mode 100644 (file)
index 0000000..66d5523
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import com.google.common.base.Preconditions;
+
+import java.net.URI;
+
+import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringIdentityrefCodec;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+final class JSONStringIdentityrefCodec extends AbstractModuleStringIdentityrefCodec {
+    private final SchemaContext context;
+
+    JSONStringIdentityrefCodec(final SchemaContext context) {
+        this.context = Preconditions.checkNotNull(context);
+    }
+
+    @Override
+    protected Module moduleForPrefix(final String prefix) {
+        return context.findModuleByName(prefix, null);
+    }
+
+    @Override
+    protected String prefixForNamespace(final URI namespace) {
+        final Module module = context.findModuleByNamespaceAndRevision(namespace, null);
+        return module == null ? null : module.getName();
+    }
+
+}
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStringInstanceIdentifierCodec.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONStringInstanceIdentifierCodec.java
new file mode 100644 (file)
index 0000000..fc1322f
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import com.google.common.base.Preconditions;
+
+import java.net.URI;
+
+import org.opendaylight.yangtools.yang.data.util.AbstractModuleStringInstanceIdentifierCodec;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+final class JSONStringInstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec {
+    private final SchemaContext context;
+
+    JSONStringInstanceIdentifierCodec(final SchemaContext context) {
+        this.context = Preconditions.checkNotNull(context);
+    }
+
+    @Override
+    protected Module moduleForPrefix(final String prefix) {
+        return context.findModuleByName(prefix, null);
+    }
+
+    @Override
+    protected String prefixForNamespace(final URI namespace) {
+        final Module module = context.findModuleByNamespaceAndRevision(namespace, null);
+        return module == null ? null : module.getName();
+    }
+}
index f3cf17aee35420ab815d4dda9300469868db0e80..65c234aae4b87dfef3c87fd3662cf34fd2c660d2 100644 (file)
@@ -21,7 +21,6 @@ import java.io.EOFException;
 import java.io.Flushable;
 import java.io.IOException;
 import java.net.URI;
-import java.security.InvalidParameterException;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -32,11 +31,6 @@ import java.util.Set;
 
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.IdentityValuesDTO;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.RestCodecFactory;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.RestUtil;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.RestUtil.PrefixMapingFromJson;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.SchemaContextUtils;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
@@ -44,10 +38,9 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
 
 /**
  * This class parses JSON elements from a GSON JsonReader. It disallows multiple elements of the same name unlike the
@@ -57,15 +50,13 @@ import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefi
 public final class JsonParserStream implements Closeable, Flushable {
     private final Deque<URI> namespaces = new ArrayDeque<>();
     private final NormalizedNodeStreamWriter writer;
-    private final SchemaContextUtils utils;
-    private final RestCodecFactory codecs;
+    private final CodecFactory codecs;
     private final SchemaContext schema;
 
     private JsonParserStream(final NormalizedNodeStreamWriter writer, final SchemaContext schemaContext) {
         this.schema = Preconditions.checkNotNull(schemaContext);
-        this.utils = SchemaContextUtils.create(schemaContext);
         this.writer = Preconditions.checkNotNull(writer);
-        this.codecs = RestCodecFactory.create(utils);
+        this.codecs = CodecFactory.create(schemaContext);
     }
 
     public static JsonParserStream create(final NormalizedNodeStreamWriter writer, final SchemaContext schemaContext) {
@@ -187,16 +178,7 @@ public final class JsonParserStream implements Closeable, Flushable {
             return value;
         }
 
-        final Object inputValue;
-        if (typeDefinition instanceof IdentityrefTypeDefinition) {
-            inputValue = valueAsIdentityRef(value);
-        } else if (typeDefinition instanceof InstanceIdentifierTypeDefinition) {
-            inputValue = valueAsInstanceIdentifier(value);
-        } else {
-            inputValue = value;
-        }
-
-        return codecs.codecFor(typeDefinition).deserialize(inputValue);
+        return codecs.codecFor(typeDefinition).deserialize(value);
     }
 
     private static TypeDefinition<? extends Object> typeDefinition(final DataSchemaNode node) {
@@ -219,47 +201,6 @@ public final class JsonParserStream implements Closeable, Flushable {
         return baseType;
     }
 
-    private static Object valueAsInstanceIdentifier(final String value) {
-        // it could be instance-identifier Built-In Type
-        if (!value.isEmpty() && value.charAt(0) == '/') {
-            IdentityValuesDTO resolvedValue = RestUtil.asInstanceIdentifier(value, new PrefixMapingFromJson());
-            if (resolvedValue != null) {
-                return resolvedValue;
-            }
-        }
-        throw new InvalidParameterException("Value for instance-identifier doesn't have correct format");
-    }
-
-    private static IdentityValuesDTO valueAsIdentityRef(final String value) {
-        // it could be identityref Built-In Type
-        URI namespace = getNamespaceFor(value);
-        if (namespace != null) {
-            return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null, value);
-        }
-        throw new InvalidParameterException("Value for identityref has to be in format moduleName:localName.");
-    }
-
-    private static URI getNamespaceFor(final String jsonElementName) {
-        // The string needs to me in form "moduleName:localName"
-        final int idx = jsonElementName.indexOf(':');
-        if (idx == -1 || jsonElementName.indexOf(':', idx + 1) != -1) {
-            return null;
-        }
-
-        // FIXME: is this correct? This should be looking up module name instead
-        return URI.create(jsonElementName.substring(0, idx));
-    }
-
-    private static String getLocalNameFor(final String jsonElementName) {
-        // The string needs to me in form "moduleName:localName"
-        final int idx = jsonElementName.indexOf(':');
-        if (idx == -1 || jsonElementName.indexOf(':', idx + 1) != -1) {
-            return jsonElementName;
-        }
-
-        return jsonElementName.substring(idx + 1);
-    }
-
     private void removeNamespace() {
         namespaces.pop();
     }
@@ -284,7 +225,9 @@ public final class JsonParserStream implements Closeable, Flushable {
         if (lastIndexOfColon != -1) {
             moduleNamePart = childName.substring(0, lastIndexOfColon);
             nodeNamePart = childName.substring(lastIndexOfColon + 1);
-            namespace = utils.findNamespaceByModuleName(moduleNamePart);
+
+            final Module m = schema.findModuleByName(moduleNamePart, null);
+            namespace = m == null ? null : m.getNamespace();
         } else {
             nodeNamePart = childName;
         }
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/AbstractCodecImpl.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/AbstractCodecImpl.java
deleted file mode 100644 (file)
index 407d866..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-import com.google.common.base.Preconditions;
-
-import java.net.URI;
-
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-abstract class AbstractCodecImpl {
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractCodecImpl.class);
-    private final SchemaContextUtils schema;
-
-    protected AbstractCodecImpl(final SchemaContextUtils schema) {
-        this.schema = Preconditions.checkNotNull(schema);
-    }
-
-    protected final SchemaContextUtils getSchema() {
-        return schema;
-    }
-
-    protected final Module getModuleByNamespace(final String namespace) {
-        URI validNamespace = resolveValidNamespace(namespace);
-
-        Module module = schema.findModuleByNamespace(validNamespace);
-        if (module == null) {
-            LOG.info("Module for namespace " + validNamespace + " wasn't found.");
-            return null;
-        }
-        return module;
-    }
-
-    protected final URI resolveValidNamespace(final String namespace) {
-        URI validNamespace = schema.findNamespaceByModuleName(namespace);
-        if (validNamespace == null) {
-            validNamespace = URI.create(namespace);
-        }
-
-        return validNamespace;
-    }
-}
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/IdentityValuesDTO.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/IdentityValuesDTO.java
deleted file mode 100644 (file)
index 30ba2a0..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-import com.google.common.annotations.Beta;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * This class is implementation-internal and subject to change. Please do not use it.
- */
-@Beta
-public final class IdentityValuesDTO {
-
-    private final List<IdentityValue> elementData = new ArrayList<>();
-    private final String originValue;
-
-    public IdentityValuesDTO(final String namespace, final String value, final String prefix, final String originValue) {
-        elementData.add(new IdentityValue(namespace, value, prefix));
-        this.originValue = originValue;
-    }
-
-    public IdentityValuesDTO(final String originValue) {
-        this.originValue = originValue;
-    }
-
-    public IdentityValuesDTO() {
-        originValue = null;
-    }
-
-    public void add(final String namespace, final String value, final String prefix) {
-        elementData.add(new IdentityValue(namespace, value, prefix));
-    }
-
-    public void add(final IdentityValue identityValue) {
-        elementData.add(identityValue);
-    }
-
-    public List<IdentityValue> getValuesWithNamespaces() {
-        return Collections.unmodifiableList(elementData);
-    }
-
-    @Override
-    public String toString() {
-        return elementData.toString();
-    }
-
-    public String getOriginValue() {
-        return originValue;
-    }
-
-    public static final class IdentityValue {
-
-        private final String namespace;
-        private final String value;
-        private final String prefix;
-        private List<Predicate> predicates;
-
-        public IdentityValue(final String namespace, final String value, final String prefix) {
-            this.namespace = namespace;
-            this.value = value;
-            this.prefix = prefix;
-        }
-
-        public String getNamespace() {
-            return namespace;
-        }
-
-        public String getValue() {
-            return value;
-        }
-
-        public String getPrefix() {
-            return prefix;
-        }
-
-        public List<Predicate> getPredicates() {
-            if (predicates == null) {
-                return Collections.emptyList();
-            }
-            return Collections.unmodifiableList(predicates);
-        }
-
-        public void setPredicates(final List<Predicate> predicates) {
-            this.predicates = predicates;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            if (namespace != null) {
-                sb.append(namespace);
-            }
-            if (prefix != null) {
-                sb.append("(").append(prefix).append(")");
-            }
-            if (value != null) {
-                sb.append(" - ").append(value);
-            }
-            if (predicates != null && !predicates.isEmpty()) {
-                for (Predicate predicate : predicates) {
-                    sb.append("[");
-                    predicate.toString();
-                    sb.append("]");
-                }
-            }
-            return sb.toString();
-        }
-
-    }
-
-    public static final class Predicate {
-
-        private final IdentityValue name;
-        private final String value;
-
-        public Predicate(final IdentityValue name, final String value) {
-            super();
-            this.name = name;
-            this.value = value;
-        }
-
-        public IdentityValue getName() {
-            return name;
-        }
-
-        public String getValue() {
-            return value;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            if (name != null) {
-                sb.append(name.toString());
-            }
-            if (value != null) {
-                sb.append("=").append(value);
-            }
-            return sb.toString();
-        }
-
-        public boolean isLeafList() {
-            return name == null ? true : false;
-        }
-
-    }
-}
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/IdentityrefCodecImpl.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/IdentityrefCodecImpl.java
deleted file mode 100644 (file)
index a8c8b8d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class IdentityrefCodecImpl extends AbstractCodecImpl implements IdentityrefCodec<IdentityValuesDTO> {
-    private static final Logger LOG = LoggerFactory.getLogger(IdentityrefCodecImpl.class);
-
-    IdentityrefCodecImpl(final SchemaContextUtils schema) {
-        super(schema);
-    }
-
-    @Override
-    public IdentityValuesDTO serialize(final QName data) {
-        return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix(), null);
-    }
-
-    @Override
-    public QName deserialize(final IdentityValuesDTO data) {
-        IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
-        Module module = getModuleByNamespace(valueWithNamespace.getNamespace());
-        if (module == null) {
-            LOG.info("Module was not found for namespace {}", valueWithNamespace.getNamespace());
-            LOG.info("Idenetityref will be translated as NULL for data - {}", String.valueOf(valueWithNamespace));
-            return null;
-        }
-
-        return QName.create(module.getNamespace(), module.getRevision(), valueWithNamespace.getValue());
-    }
-
-}
\ No newline at end of file
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/InstanceIdentifierCodecImpl.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/InstanceIdentifierCodecImpl.java
deleted file mode 100644 (file)
index 455bdf4..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.IdentityValuesDTO.Predicate;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class InstanceIdentifierCodecImpl extends AbstractCodecImpl implements InstanceIdentifierCodec<IdentityValuesDTO> {
-    private static final Logger LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl.class);
-
-    InstanceIdentifierCodecImpl(final SchemaContextUtils schema) {
-        super(schema);
-    }
-
-    @Override
-    public IdentityValuesDTO serialize(final YangInstanceIdentifier data) {
-        IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO();
-        for (PathArgument pathArgument : data.getPathArguments()) {
-            IdentityValue identityValue = qNameToIdentityValue(pathArgument.getNodeType());
-            if (pathArgument instanceof NodeIdentifierWithPredicates && identityValue != null) {
-                List<Predicate> predicates = keyValuesToPredicateList(((NodeIdentifierWithPredicates) pathArgument)
-                        .getKeyValues());
-                identityValue.setPredicates(predicates);
-            } else if (pathArgument instanceof NodeWithValue && identityValue != null) {
-                List<Predicate> predicates = new ArrayList<>();
-                String value = String.valueOf(((NodeWithValue) pathArgument).getValue());
-                predicates.add(new Predicate(null, value));
-                identityValue.setPredicates(predicates);
-            }
-            identityValuesDTO.add(identityValue);
-        }
-        return identityValuesDTO;
-    }
-
-    @Override
-    public YangInstanceIdentifier deserialize(final IdentityValuesDTO data) {
-        List<PathArgument> result = new ArrayList<PathArgument>();
-        IdentityValue valueWithNamespace = data.getValuesWithNamespaces().get(0);
-        Module module = getModuleByNamespace(valueWithNamespace.getNamespace());
-        if (module == null) {
-            LOG.info("Module by namespace '{}' of first node in instance-identiefier was not found.",
-                    valueWithNamespace.getNamespace());
-            LOG.info("Instance-identifier will be translated as NULL for data - {}",
-                    String.valueOf(valueWithNamespace.getValue()));
-            return null;
-        }
-
-        DataNodeContainer parentContainer = module;
-        List<IdentityValue> identities = data.getValuesWithNamespaces();
-        for (int i = 0; i < identities.size(); i++) {
-            IdentityValue identityValue = identities.get(i);
-            URI validNamespace = resolveValidNamespace(identityValue.getNamespace());
-            DataSchemaNode node = getSchema().findInstanceDataChildByNameAndNamespace(
-                    parentContainer, identityValue.getValue(), validNamespace);
-            if (node == null) {
-                LOG.info("'{}' node was not found in {}", identityValue, parentContainer.getChildNodes());
-                LOG.info("Instance-identifier will be translated as NULL for data - {}",
-                        String.valueOf(identityValue.getValue()));
-                return null;
-            }
-            QName qName = node.getQName();
-            PathArgument pathArgument = null;
-            if (identityValue.getPredicates().isEmpty()) {
-                pathArgument = new NodeIdentifier(qName);
-            } else {
-                if (node instanceof LeafListSchemaNode) { // predicate is value of leaf-list entry
-                    Predicate leafListPredicate = identityValue.getPredicates().get(0);
-                    if (!leafListPredicate.isLeafList()) {
-                        LOG.info("Predicate's data is not type of leaf-list. It should be in format \".='value'\"");
-                        LOG.info("Instance-identifier will be translated as NULL for data - {}",
-                                String.valueOf(identityValue.getValue()));
-                        return null;
-                    }
-                    pathArgument = new NodeWithValue(qName, leafListPredicate.getValue());
-                } else if (node instanceof ListSchemaNode) { // predicates are keys of list
-                    DataNodeContainer listNode = (DataNodeContainer) node;
-                    Map<QName, Object> predicatesMap = new HashMap<>();
-                    for (Predicate predicate : identityValue.getPredicates()) {
-                        validNamespace = resolveValidNamespace(predicate.getName().getNamespace());
-                        DataSchemaNode listKey = getSchema()
-                                .findInstanceDataChildByNameAndNamespace(listNode, predicate.getName().getValue(),
-                                        validNamespace);
-                        predicatesMap.put(listKey.getQName(), predicate.getValue());
-                    }
-                    pathArgument = new NodeIdentifierWithPredicates(qName, predicatesMap);
-                } else {
-                    LOG.info("Node {} is not List or Leaf-list.", node);
-                    LOG.info("Instance-identifier will be translated as NULL for data - {}",
-                            String.valueOf(identityValue.getValue()));
-                    return null;
-                }
-            }
-            result.add(pathArgument);
-            if (i < identities.size() - 1) { // last element in instance-identifier can be other than
-                // DataNodeContainer
-                if (node instanceof DataNodeContainer) {
-                    parentContainer = (DataNodeContainer) node;
-                } else {
-                    LOG.info("Node {} isn't instance of DataNodeContainer", node);
-                    LOG.info("Instance-identifier will be translated as NULL for data - {}",
-                            String.valueOf(identityValue.getValue()));
-                    return null;
-                }
-            }
-        }
-
-        return result.isEmpty() ? null : YangInstanceIdentifier.create(result);
-    }
-
-    private static List<Predicate> keyValuesToPredicateList(final Map<QName, Object> keyValues) {
-        List<Predicate> result = new ArrayList<>(keyValues.size());
-        for (Map.Entry<QName, Object> e : keyValues.entrySet()) {
-            result.add(new Predicate(qNameToIdentityValue(e.getKey()), String.valueOf(e.getValue())));
-        }
-        return result;
-    }
-
-    private static IdentityValue qNameToIdentityValue(final QName qName) {
-        if (qName != null) {
-            // FIXME: the prefix here is completely arbitrary
-            return new IdentityValue(qName.getNamespace().toString(), qName.getLocalName(), qName.getPrefix());
-        }
-        return null;
-    }
-}
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/LeafrefCodecImpl.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/LeafrefCodecImpl.java
deleted file mode 100644 (file)
index c6d8baf..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-import org.opendaylight.yangtools.yang.data.api.codec.LeafrefCodec;
-
-class LeafrefCodecImpl implements LeafrefCodec<String> {
-
-    @Override
-    public String serialize(final Object data) {
-        return String.valueOf(data);
-    }
-
-    @Override
-    public Object deserialize(final String data) {
-        return data;
-    }
-
-}
\ No newline at end of file
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/ObjectCodec.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/ObjectCodec.java
deleted file mode 100644 (file)
index abe7cd2..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-import org.opendaylight.yangtools.concepts.Codec;
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("rawtypes")
-final class ObjectCodec extends AbstractCodecImpl implements Codec<Object, Object> {
-    public static final Codec LEAFREF_DEFAULT_CODEC = new LeafrefCodecImpl();
-    private static final Logger LOG = LoggerFactory.getLogger(RestCodecFactory.class);
-    private final Codec instanceIdentifier;
-    private final Codec identityrefCodec;
-    private final TypeDefinition<?> type;
-
-    ObjectCodec(final SchemaContextUtils schema, final TypeDefinition<?> typeDefinition) {
-        super(schema);
-        type = RestUtil.resolveBaseTypeFrom(typeDefinition);
-        if (type instanceof IdentityrefTypeDefinition) {
-            identityrefCodec = new IdentityrefCodecImpl(schema);
-        } else {
-            identityrefCodec = null;
-        }
-        if (type instanceof InstanceIdentifierTypeDefinition) {
-            instanceIdentifier = new InstanceIdentifierCodecImpl(schema);
-        } else {
-            instanceIdentifier = null;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Object deserialize(final Object input) {
-        try {
-            if (type instanceof IdentityrefTypeDefinition) {
-                if (input instanceof IdentityValuesDTO) {
-                    return identityrefCodec.deserialize(input);
-                }
-                LOG.debug("Value is not instance of IdentityrefTypeDefinition but is {}. Therefore NULL is used as translation of  - {}",
-                        input == null ? "null" : input.getClass(), String.valueOf(input));
-                return null;
-            } else if (type instanceof LeafrefTypeDefinition) {
-                if (input instanceof IdentityValuesDTO) {
-                    return LEAFREF_DEFAULT_CODEC.deserialize(((IdentityValuesDTO) input).getOriginValue());
-                }
-                return LEAFREF_DEFAULT_CODEC.deserialize(input);
-            } else if (type instanceof InstanceIdentifierTypeDefinition) {
-                if (input instanceof IdentityValuesDTO) {
-                    return instanceIdentifier.deserialize(input);
-                }
-                LOG.info(
-                        "Value is not instance of InstanceIdentifierTypeDefinition but is {}. Therefore NULL is used as translation of  - {}",
-                        input == null ? "null" : input.getClass(), String.valueOf(input));
-                return null;
-            } else {
-                TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
-                        .from(type);
-                if (typeAwarecodec != null) {
-                    if (input instanceof IdentityValuesDTO) {
-                        return typeAwarecodec.deserialize(((IdentityValuesDTO) input).getOriginValue());
-                    }
-                    return typeAwarecodec.deserialize(String.valueOf(input));
-                } else {
-                    LOG.debug("Codec for type \"" + type.getQName().getLocalName()
-                            + "\" is not implemented yet.");
-                    return null;
-                }
-            }
-        } catch (ClassCastException e) {
-            // TODO remove this catch when everyone use codecs
-            LOG.error("ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
-                    e);
-            return null;
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Object serialize(final Object input) {
-        try {
-            if (type instanceof IdentityrefTypeDefinition) {
-                return identityrefCodec.serialize(input);
-            } else if (type instanceof LeafrefTypeDefinition) {
-                return LEAFREF_DEFAULT_CODEC.serialize(input);
-            } else if (type instanceof InstanceIdentifierTypeDefinition) {
-                return instanceIdentifier.serialize(input);
-            } else {
-                TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>> typeAwarecodec = TypeDefinitionAwareCodec
-                        .from(type);
-                if (typeAwarecodec != null) {
-                    return typeAwarecodec.serialize(input);
-                } else {
-                    LOG.debug("Codec for type \"" + type.getQName().getLocalName()
-                            + "\" is not implemented yet.");
-                    return null;
-                }
-            }
-        } catch (ClassCastException e) { // TODO remove this catch when everyone use codecs
-            LOG.error(
-                    "ClassCastException was thrown when codec is invoked with parameter " + String.valueOf(input),
-                    e);
-            return input;
-        }
-    }
-
-}
\ No newline at end of file
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/RestCodecFactory.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/RestCodecFactory.java
deleted file mode 100644 (file)
index ba32831..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-
-import org.opendaylight.yangtools.concepts.Codec;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
-/**
- * This class is implementation-internal and subject to change. Please do not use it.
- */
-@Beta
-public final class RestCodecFactory {
-    private final LoadingCache<TypeDefinition<?>, Codec<Object, Object>> codecs =
-            CacheBuilder.newBuilder().softValues().build(new CacheLoader<TypeDefinition<?>, Codec<Object, Object>>() {
-        @Override
-        public Codec<Object, Object> load(final TypeDefinition<?> key) throws Exception {
-            return new ObjectCodec(utils, key);
-        }
-    });
-    private final SchemaContextUtils utils;
-
-    private RestCodecFactory(final SchemaContextUtils utils) {
-        this.utils = Preconditions.checkNotNull(utils);
-    }
-
-    public static RestCodecFactory create(final SchemaContextUtils utils) {
-        return new RestCodecFactory(utils);
-    }
-
-    public final Codec<Object, Object> codecFor(final TypeDefinition<?> typeDefinition) {
-        return codecs.getUnchecked(typeDefinition);
-    }
-}
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/RestUtil.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/RestUtil.java
deleted file mode 100644 (file)
index c3d002c..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-
-import com.google.common.annotations.Beta;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.stream.events.StartElement;
-
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.IdentityValuesDTO.IdentityValue;
-import org.opendaylight.yangtools.yang.data.codec.gson.helpers.IdentityValuesDTO.Predicate;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
-/**
- * This class is implementation-internal and subject to change. Please do not use it.
- */
-@Beta
-public final class RestUtil {
-
-    // FIXME: BUG-1275: this is code duplicates data.impl.codec
-
-    public static final String SQUOTE = "'";
-    public static final String DQUOTE = "\"";
-    private static final Pattern PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
-
-    public final static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
-        TypeDefinition<?> superType = type;
-        while (superType.getBaseType() != null) {
-            superType = superType.getBaseType();
-        }
-        return superType;
-    }
-
-    public static IdentityValuesDTO asInstanceIdentifier(final String value, final PrefixesMaping prefixMap) {
-        String valueTrimmed = value.trim();
-        if (!valueTrimmed.startsWith("/")) {
-            return null;
-        }
-        String[] xPathParts = valueTrimmed.split("/");
-        if (xPathParts.length < 2) { // must be at least "/pr:node"
-            return null;
-        }
-        IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(value);
-        for (int i = 1; i < xPathParts.length; i++) {
-            String xPathPartTrimmed = xPathParts[i].trim();
-
-            String xPathPartStr = getIdAndPrefixAsStr(xPathPartTrimmed);
-            IdentityValue identityValue = toIdentity(xPathPartStr, prefixMap);
-            if (identityValue == null) {
-                return null;
-            }
-
-            List<Predicate> predicates = toPredicates(xPathPartTrimmed, prefixMap);
-            if (predicates == null) {
-                return null;
-            }
-            identityValue.setPredicates(predicates);
-
-            identityValuesDTO.add(identityValue);
-        }
-        return identityValuesDTO.getValuesWithNamespaces().isEmpty() ? null : identityValuesDTO;
-    }
-
-    private static String getIdAndPrefixAsStr(final String pathPart) {
-        int predicateStartIndex = pathPart.indexOf("[");
-        return predicateStartIndex == -1 ? pathPart : pathPart.substring(0, predicateStartIndex);
-    }
-
-    private static IdentityValue toIdentity(final String xPathPart, final PrefixesMaping prefixMap) {
-        String xPathPartTrimmed = xPathPart.trim();
-        if (xPathPartTrimmed.isEmpty()) {
-            return null;
-        }
-        String[] prefixAndIdentifier = xPathPartTrimmed.split(":");
-        // it is not "prefix:value"
-        if (prefixAndIdentifier.length != 2) {
-            return null;
-        }
-        String prefix = prefixAndIdentifier[0].trim();
-        String identifier = prefixAndIdentifier[1].trim();
-        if (prefix.isEmpty() || identifier.isEmpty()) {
-            return null;
-        }
-        String namespace = prefixMap.getNamespace(prefix);
-        return new IdentityValue(namespace, identifier, namespace.equals(prefix) ? null : prefix);
-    }
-
-    private static List<Predicate> toPredicates(final String predicatesStr, final PrefixesMaping prefixMap) {
-        List<Predicate> result = new ArrayList<>();
-        List<String> predicates = new ArrayList<>();
-        Matcher matcher = PREDICATE_PATTERN.matcher(predicatesStr);
-        while (matcher.find()) {
-            predicates.add(matcher.group(1).trim());
-        }
-        for (String predicate : predicates) {
-            int indexOfEqualityMark = predicate.indexOf("=");
-            if (indexOfEqualityMark != -1) {
-                String predicateValue = toPredicateValue(predicate.substring(indexOfEqualityMark + 1));
-                if (predicate.startsWith(".")) { // it is leaf-list
-                    if (predicateValue == null) {
-                        return null;
-                    }
-                    result.add(new Predicate(null, predicateValue));
-                } else {
-                    IdentityValue identityValue = toIdentity(predicate.substring(0, indexOfEqualityMark), prefixMap);
-                    if (identityValue == null || predicateValue == null) {
-                        return null;
-                    }
-                    result.add(new Predicate(identityValue, predicateValue));
-                }
-            }
-        }
-        return result;
-    }
-
-    private static String toPredicateValue(final String predicatedValue) {
-        String predicatedValueTrimmed = predicatedValue.trim();
-        if ((predicatedValueTrimmed.startsWith(DQUOTE) || predicatedValueTrimmed.startsWith(SQUOTE))
-                && (predicatedValueTrimmed.endsWith(DQUOTE) || predicatedValueTrimmed.endsWith(SQUOTE))) {
-            return predicatedValueTrimmed.substring(1, predicatedValueTrimmed.length() - 1);
-        }
-        return null;
-    }
-
-    public interface PrefixesMaping {
-        public String getNamespace(String prefix);
-    }
-
-    public static class PrefixMapingFromXml implements PrefixesMaping {
-        StartElement startElement = null;
-
-        public PrefixMapingFromXml(final StartElement startElement) {
-            this.startElement = startElement;
-        }
-
-        @Override
-        public String getNamespace(final String prefix) {
-            return startElement.getNamespaceContext().getNamespaceURI(prefix);
-        }
-    }
-
-    public static class PrefixMapingFromJson implements PrefixesMaping {
-
-        @Override
-        public String getNamespace(final String prefix) {
-            return prefix;
-        }
-    }
-
-}
diff --git a/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/SchemaContextUtils.java b/yang/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/helpers/SchemaContextUtils.java
deleted file mode 100644 (file)
index 5e8f6f1..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.data.codec.gson.helpers;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * This class is implementation-internal and subject to change. Please do not use it.
- */
-@Beta
-public final class SchemaContextUtils {
-    private final SchemaContext schemaContext;
-
-    private SchemaContextUtils(final SchemaContext schemaContext) {
-        this.schemaContext = Preconditions.checkNotNull(schemaContext);
-    }
-
-    public static SchemaContextUtils create(final SchemaContext schemaContext) {
-        return new SchemaContextUtils(schemaContext);
-    }
-
-    public URI findNamespaceByModuleName(final String moduleName) {
-        final Module module = this.findModuleByName(moduleName);
-        return module == null ? null : module.getNamespace();
-    }
-
-
-    public Module findModuleByName(final String moduleName) {
-        checkPreconditions();
-        Preconditions.checkArgument(moduleName != null && !moduleName.isEmpty());
-        return schemaContext.findModuleByName(moduleName, null);
-    }
-
-    public Module findModuleByNamespace(final URI namespace) {
-        this.checkPreconditions();
-        Preconditions.checkArgument(namespace != null);
-        return schemaContext.findModuleByNamespaceAndRevision(namespace, null);
-    }
-
-    private void checkPreconditions() {
-        if (schemaContext == null) {
-            throw new IllegalStateException("Schema context isn't set.");
-        }
-    }
-
-    public DataSchemaNode findInstanceDataChildByNameAndNamespace(final DataNodeContainer container, final String name,
-            final URI namespace) {
-        Preconditions.<URI> checkNotNull(namespace);
-
-        final List<DataSchemaNode> potentialSchemaNodes = findInstanceDataChildrenByName(container, name);
-
-        Predicate<DataSchemaNode> filter = new Predicate<DataSchemaNode>() {
-            @Override
-            public boolean apply(final DataSchemaNode node) {
-                return Objects.equal(node.getQName().getNamespace(), namespace);
-            }
-        };
-
-        Iterable<DataSchemaNode> result = Iterables.filter(potentialSchemaNodes, filter);
-        return Iterables.getFirst(result, null);
-    }
-
-    public List<DataSchemaNode> findInstanceDataChildrenByName(final DataNodeContainer container, final String name) {
-        Preconditions.<DataNodeContainer> checkNotNull(container);
-        Preconditions.<String> checkNotNull(name);
-
-        List<DataSchemaNode> instantiatedDataNodeContainers = new ArrayList<DataSchemaNode>();
-        collectInstanceDataNodeContainers(instantiatedDataNodeContainers, container, name);
-        return instantiatedDataNodeContainers;
-    }
-
-    private void collectInstanceDataNodeContainers(final List<DataSchemaNode> potentialSchemaNodes,
-            final DataNodeContainer container, final String name) {
-
-        Predicate<DataSchemaNode> filter = new Predicate<DataSchemaNode>() {
-            @Override
-            public boolean apply(final DataSchemaNode node) {
-                return Objects.equal(node.getQName().getLocalName(), name);
-            }
-        };
-
-        Iterable<DataSchemaNode> nodes = Iterables.filter(container.getChildNodes(), filter);
-
-        // Can't combine this loop with the filter above because the filter is
-        // lazily-applied by Iterables.filter.
-        for (final DataSchemaNode potentialNode : nodes) {
-            if (isInstantiatedDataSchema(potentialNode)) {
-                potentialSchemaNodes.add(potentialNode);
-            }
-        }
-
-        Iterable<ChoiceNode> choiceNodes = Iterables.filter(container.getChildNodes(), ChoiceNode.class);
-        Iterable<Set<ChoiceCaseNode>> map = Iterables.transform(choiceNodes, CHOICE_FUNCTION);
-
-        final Iterable<ChoiceCaseNode> allCases = Iterables.<ChoiceCaseNode> concat(map);
-        for (final ChoiceCaseNode caze : allCases) {
-            collectInstanceDataNodeContainers(potentialSchemaNodes, caze, name);
-        }
-    }
-
-    public boolean isInstantiatedDataSchema(final DataSchemaNode node) {
-        return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode
-                || node instanceof ContainerSchemaNode || node instanceof ListSchemaNode
-                || node instanceof AnyXmlSchemaNode;
-    }
-
-    private final Function<ChoiceNode, Set<ChoiceCaseNode>> CHOICE_FUNCTION = new Function<ChoiceNode, Set<ChoiceCaseNode>>() {
-        @Override
-        public Set<ChoiceCaseNode> apply(final ChoiceNode node) {
-            return node.getCases();
-        }
-    };
-
-}
diff --git a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractModuleStringIdentityrefCodec.java b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractModuleStringIdentityrefCodec.java
new file mode 100644 (file)
index 0000000..dc04682
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.util;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+@Beta
+public abstract class AbstractModuleStringIdentityrefCodec extends AbstractStringIdentityrefCodec {
+    /**
+     * Resolve a string prefix into the corresponding module.
+     *
+     * @param prefix
+     * @return module mapped to prefix, or null if the module cannot be resolved
+     */
+    protected abstract Module moduleForPrefix(@Nonnull String prefix);
+
+    @Override
+    protected final QName createQName(final String prefix, final String localName) {
+        final Module module = moduleForPrefix(prefix);
+        Preconditions.checkArgument(module != null, "Failed to lookup prefix %s", prefix);
+        return QName.create(module.getQNameModule(), localName);
+    }
+}
diff --git a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractModuleStringInstanceIdentifierCodec.java b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractModuleStringInstanceIdentifierCodec.java
new file mode 100644 (file)
index 0000000..7e61841
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.util;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+/**
+ * Extension of {@link AbstractStringInstanceIdentifierCodec}, which instantiates
+ * QNames by first resolving the namespace and then looking the target namespace
+ * in the list of currently-subscribed modules.
+ */
+@Beta
+public abstract class AbstractModuleStringInstanceIdentifierCodec extends AbstractStringInstanceIdentifierCodec {
+    /**
+     * Resolve a string prefix into the corresponding module.
+     *
+     * @param prefix
+     * @return module mapped to prefix, or null if the module cannot be resolved
+     */
+    protected abstract Module moduleForPrefix(@Nonnull String prefix);
+
+    @Override
+    protected final QName createQName(final String prefix, final String localName) {
+        final Module module = moduleForPrefix(prefix);
+        Preconditions.checkArgument(module != null, "Failed to lookup prefix %s", prefix);
+        return QName.create(module.getQNameModule(), localName);
+    }
+}
diff --git a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractNamespaceCodec.java b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractNamespaceCodec.java
new file mode 100644 (file)
index 0000000..620f46e
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.util;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import java.net.URI;
+import java.util.Iterator;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+abstract class AbstractNamespaceCodec {
+    private static final Splitter COLON_SPLITTER = Splitter.on(':');
+
+    /**
+     * Return string prefix for a particular namespace, allocating a new one if necessary.
+     *
+     * @param namespace Namespace to map
+     * @return Allocated unique prefix, or null if the prefix cannot be mapped.
+     */
+    protected abstract @Nullable String prefixForNamespace(final @Nonnull URI namespace);
+
+    /**
+     * Create a QName for a prefix and local name.
+     *
+     * @param prefix Prefix for namespace
+     * @param localName local name
+     * @return QName
+     * @throws IllegalArgumentException if the prefix cannot be resolved
+     */
+    protected abstract @Nullable QName createQName(final @Nonnull String prefix, final @Nonnull String localName);
+
+    private static String getIdAndPrefixAsStr(final String pathPart) {
+        int predicateStartIndex = pathPart.indexOf('[');
+        return predicateStartIndex == -1 ? pathPart : pathPart.substring(0, predicateStartIndex);
+    }
+
+    protected final StringBuilder appendQName(final StringBuilder sb, final QName qname) {
+        final String prefix = prefixForNamespace(qname.getNamespace());
+        Preconditions.checkArgument(prefix != null, "Failed to map QName {}", qname);
+        sb.append(prefix);
+        sb.append(':');
+        sb.append(qname.getLocalName());
+        return sb;
+    }
+
+    protected final QName parseQName(final String str) {
+        final String xPathPartTrimmed = getIdAndPrefixAsStr(str).trim();
+        final Iterator<String> it = COLON_SPLITTER.split(xPathPartTrimmed).iterator();
+
+        // Empty string
+        if (!it.hasNext()) {
+            return null;
+        }
+
+        final String prefix = it.next().trim();
+        if (prefix.isEmpty()) {
+            return null;
+        }
+
+        // it is not "prefix:value"
+        if (!it.hasNext()) {
+            return null;
+        }
+
+        final String identifier = it.next().trim();
+        if (identifier.isEmpty()) {
+            return null;
+        }
+
+        return createQName(prefix, identifier);
+    }
+}
diff --git a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringIdentityrefCodec.java b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringIdentityrefCodec.java
new file mode 100644 (file)
index 0000000..6e15067
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.util;
+
+import com.google.common.annotations.Beta;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.codec.IdentityrefCodec;
+
+/**
+ * Abstract utility class for representations which encode Identityref as a
+ * prefix:name tuple. Typical uses are RESTCONF/JSON (module:name) and XML (prefix:name).
+ */
+@Beta
+public abstract class AbstractStringIdentityrefCodec extends AbstractNamespaceCodec implements IdentityrefCodec<String> {
+    @Override
+    public String serialize(final QName data) {
+        return appendQName(new StringBuilder(), data).toString();
+    }
+
+    @Override
+    public QName deserialize(final String data) {
+        return parseQName(data);
+    }
+}
diff --git a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java
new file mode 100644 (file)
index 0000000..5140f27
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.util;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec;
+
+/**
+ * Abstract utility class for representations which encode {@link YangInstanceIdentifier} as a
+ * prefix:name tuple. Typical uses are RESTCONF/JSON (module:name) and XML (prefix:name).
+ */
+@Beta
+public abstract class AbstractStringInstanceIdentifierCodec extends AbstractNamespaceCodec implements InstanceIdentifierCodec<String> {
+    private static final Pattern PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]");
+    private static final Splitter SLASH_SPLITTER = Splitter.on('/');
+
+    @Override
+    public final String serialize(final YangInstanceIdentifier data) {
+        StringBuilder sb = new StringBuilder();
+        for (PathArgument arg : data.getPathArguments()) {
+            sb.append('/');
+            appendQName(sb, arg.getNodeType());
+
+            if (arg instanceof NodeIdentifierWithPredicates) {
+                for (Map.Entry<QName, Object> entry : ((NodeIdentifierWithPredicates) arg).getKeyValues().entrySet()) {
+                    sb.append('[');
+                    appendQName(sb, entry.getKey());
+                    sb.append("='");
+                    sb.append(String.valueOf(entry.getValue()));
+                    sb.append("']");
+                }
+            } else if (arg instanceof NodeWithValue) {
+                sb.append("[.='");
+                sb.append(((NodeWithValue) arg).getValue());
+                sb.append("']");
+            }
+        }
+
+        return sb.toString();
+    }
+
+    @Override
+    public final YangInstanceIdentifier deserialize(final String data) {
+        Preconditions.checkNotNull(data, "Data may not be null");
+
+        final Iterator<String> xPathParts = SLASH_SPLITTER.split(data).iterator();
+
+        // must be at least "/pr:node"
+        if (!xPathParts.hasNext() || !xPathParts.next().isEmpty() || !xPathParts.hasNext()) {
+            return null;
+        }
+
+        List<PathArgument> result = new ArrayList<>();
+        while (xPathParts.hasNext()) {
+            String xPathPartTrimmed = xPathParts.next().trim();
+
+            PathArgument pathArgument = toPathArgument(xPathPartTrimmed);
+            if (pathArgument != null) {
+                result.add(pathArgument);
+            }
+        }
+        return YangInstanceIdentifier.create(result);
+    }
+
+    private PathArgument toPathArgument(final String xPathArgument) {
+        final QName mainQName = parseQName(xPathArgument);
+
+        // predicates
+        final Matcher matcher = PREDICATE_PATTERN.matcher(xPathArgument);
+        final Map<QName, Object> predicates = new HashMap<>();
+        QName currentQName = mainQName;
+
+        while (matcher.find()) {
+            final String predicateStr = matcher.group(1).trim();
+            final int indexOfEqualityMark = predicateStr.indexOf('=');
+            if (indexOfEqualityMark != -1) {
+                final String predicateValue = toPredicateValue(predicateStr.substring(indexOfEqualityMark + 1));
+                if (predicateValue == null) {
+                    return null;
+                }
+
+                if (predicateStr.charAt(0) != '.') {
+                    // target is not a leaf-list
+                    currentQName = parseQName(predicateStr.substring(0, indexOfEqualityMark));
+                    if (currentQName == null) {
+                        return null;
+                    }
+                }
+                predicates.put(currentQName, predicateValue);
+            }
+        }
+
+        if (predicates.isEmpty()) {
+            return new YangInstanceIdentifier.NodeIdentifier(mainQName);
+        } else {
+            return new YangInstanceIdentifier.NodeIdentifierWithPredicates(mainQName, predicates);
+        }
+    }
+
+    private static String toPredicateValue(final String predicatedValue) {
+        final String predicatedValueTrimmed = predicatedValue.trim();
+        if (predicatedValue.isEmpty()) {
+            return null;
+        }
+
+        switch (predicatedValueTrimmed.charAt(0)) {
+        case '"':
+            return trimIfEndIs(predicatedValueTrimmed, '"');
+        case '\'':
+            return trimIfEndIs(predicatedValueTrimmed, '\'');
+        default:
+            return null;
+        }
+    }
+
+    private static String trimIfEndIs(final String str, final char end) {
+        final int l = str.length() - 1;
+        if (str.charAt(l) != end) {
+            return null;
+        }
+
+        return str.substring(1, l);
+    }
+}