Deprecate XMLStreamNormalizedNodeStreamWriter.toString(Element)
[yangtools.git] / yang / yang-data-codec-xml / src / main / java / org / opendaylight / yangtools / yang / data / codec / xml / IdentityrefXmlCodec.java
index fbd99587cdef94a1452d29c85a73e2fac0f613e5..87623bc9967ff4bfb2b6cf620309910bb7dc96e2 100644 (file)
@@ -5,38 +5,31 @@
  * 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.xml;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
 import java.net.URI;
-import java.util.ArrayDeque;
-import java.util.Deque;
-import javax.annotation.Nonnull;
+import java.util.Iterator;
+import java.util.Map.Entry;
 import javax.xml.namespace.NamespaceContext;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.data.util.ModuleStringIdentityrefCodec;
+import org.opendaylight.yangtools.yang.data.util.codec.IdentityCodecUtil;
+import org.opendaylight.yangtools.yang.data.util.codec.QNameCodecUtil;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-final class IdentityrefXmlCodec extends ModuleStringIdentityrefCodec implements XmlCodec<QName> {
-    private static final ThreadLocal<Deque<NamespaceContext>> TL_NSCONTEXT = new ThreadLocal<>();
+final class IdentityrefXmlCodec implements XmlCodec<QName> {
+    private final SchemaContext schemaContext;
+    private final QNameModule parentModule;
 
     IdentityrefXmlCodec(final SchemaContext context, final QNameModule parentModule) {
-        super(context, parentModule);
-    }
-
-    @Override
-    protected Module moduleForPrefix(@Nonnull final String prefix) {
-        if (prefix.isEmpty()) {
-            return context.findModuleByNamespaceAndRevision(parentModuleQname.getNamespace(),
-                    parentModuleQname.getRevision());
-        }
-
-        final String prefixedNS = getNamespaceContext().getNamespaceURI(prefix);
-        return context.findModuleByNamespaceAndRevision(URI.create(prefixedNS), null);
+        this.schemaContext = requireNonNull(context);
+        this.parentModule = requireNonNull(parentModule);
     }
 
     @Override
@@ -46,38 +39,26 @@ final class IdentityrefXmlCodec extends ModuleStringIdentityrefCodec implements
 
     @Override
     public QName parseValue(final NamespaceContext ctx, final String str) {
-        pushNamespaceContext(ctx);
-        try {
-            return deserialize(str);
-        } finally {
-            popNamespaceContext();
-        }
+        return IdentityCodecUtil.parseIdentity(str, schemaContext, prefix -> {
+            if (prefix.isEmpty()) {
+                return parentModule;
+            }
+
+            final String prefixedNS = ctx.getNamespaceURI(prefix);
+            final Iterator<Module> modules = schemaContext.findModules(URI.create(prefixedNS)).iterator();
+            checkArgument(modules.hasNext(), "Could not find module for namespace %s", prefixedNS);
+            return modules.next().getQNameModule();
+        }).getQName();
     }
 
     @Override
     public void writeValue(final XMLStreamWriter ctx, final QName value) throws XMLStreamException {
-        // FIXME: this does not work correctly, as we need to populate entries into the namespace context
-        ctx.writeCharacters(serialize(value));
-    }
-
-    private static NamespaceContext getNamespaceContext() {
-        return TL_NSCONTEXT.get().getFirst();
-    }
-
-    private static void popNamespaceContext() {
-        final Deque<NamespaceContext> stack = TL_NSCONTEXT.get();
-        stack.pop();
-        if (stack.isEmpty()) {
-            TL_NSCONTEXT.set(null);
-        }
-    }
+        final RandomPrefix prefixes = new RandomPrefix(ctx.getNamespaceContext());
+        final String str = QNameCodecUtil.encodeQName(value, uri -> prefixes.encodePrefix(uri.getNamespace()));
 
-    private static void pushNamespaceContext(final NamespaceContext context) {
-        Deque<NamespaceContext> stack = TL_NSCONTEXT.get();
-        if (stack == null) {
-            stack = new ArrayDeque<>(1);
-            TL_NSCONTEXT.set(stack);
+        for (Entry<URI, String> e : prefixes.getPrefixes()) {
+            ctx.writeNamespace(e.getValue(), e.getKey().toString());
         }
-        stack.push(context);
+        ctx.writeCharacters(str);
     }
 }