return getDataClass().cast(ret);
}
- throw new IllegalArgumentException("Input '" + input +"' did not match any codecs");
+ throw new IllegalArgumentException("Invalid value \"" + input + "\" for union type.");
}
@Override
package org.opendaylight.yangtools.yang.data.codec.xml;
import com.google.common.base.Preconditions;
-import org.opendaylight.yangtools.concepts.Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.BooleanCodec;
-import org.opendaylight.yangtools.yang.data.api.codec.DecimalCodec;
-import org.opendaylight.yangtools.yang.data.api.codec.Int16Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.Int32Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.Int64Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.Int8Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.Uint16Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.Uint32Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.Uint64Codec;
-import org.opendaylight.yangtools.yang.data.api.codec.Uint8Codec;
+import javax.xml.namespace.NamespaceContext;
+import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
/**
*/
abstract class AbstractXmlCodec<T> implements XmlCodec<T> {
- private final Codec<String, T> codec;
+ private final DataStringCodec<T> codec;
- protected AbstractXmlCodec(final Codec<String, T> codec) {
+ protected AbstractXmlCodec(final DataStringCodec<T> codec) {
this.codec = Preconditions.checkNotNull(codec);
}
- /**
- * Create a proper XmlCodec based on the underlying codec type
- * @param codec underlying codec
- * @return An XmlCodec instance
- */
- public static XmlCodec<?> create(final Codec<String, ?> codec) {
- if (codec instanceof BooleanCodec) {
- return new BooleanXmlCodec((BooleanCodec<String>) codec);
- } else if (codec instanceof DecimalCodec || codec instanceof Int8Codec
- || codec instanceof Int16Codec || codec instanceof Int32Codec
- || codec instanceof Int64Codec || codec instanceof Uint8Codec
- || codec instanceof Uint16Codec || codec instanceof Uint32Codec
- || codec instanceof Uint64Codec) {
- return new NumberXmlCodec(codec);
- } else {
- return new QuotedXmlCodec(codec);
- }
+ @Override
+ public final Class<T> getDataClass() {
+ return codec.getInputClass();
}
@Override
- public final T deserialize(final String input) {
- return codec.deserialize(input);
+ public final T deserializeFromString(final NamespaceContext namespaceContext, final String value) {
+ return codec.deserialize(value);
}
- @Override
- public final String serialize(final T input) {
+ final String serialize(final T input) {
return codec.serialize(input);
}
}
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
final class BooleanXmlCodec extends AbstractXmlCodec<Boolean> {
-
- BooleanXmlCodec(final Codec<String, Boolean> codec) {
+ BooleanXmlCodec(final DataStringCodec<Boolean> codec) {
super(codec);
}
- /**
- * Serialize specified value with specified XMLStreamWriter.
- *
- * @param writer XMLStreamWriter
- * @param value value which will be serialized to the writer
- */
@Override
- public void serializeToWriter(XMLStreamWriter writer, Boolean value) throws XMLStreamException {
+ public void serializeToWriter(final XMLStreamWriter writer, final Boolean value) throws XMLStreamException {
writer.writeCharacters(String.valueOf(value));
}
}
package org.opendaylight.yangtools.yang.data.codec.xml;
+import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
-final class XmlEmptyCodec implements XmlCodec<Object> {
+final class EmptyXmlCodec implements XmlCodec<Void> {
- static final XmlEmptyCodec INSTANCE = new XmlEmptyCodec();
+ static final EmptyXmlCodec INSTANCE = new EmptyXmlCodec();
- private XmlEmptyCodec() {
+ private EmptyXmlCodec() {
}
@Override
- public Object deserialize(final String input) {
- return null;
+ public Class<Void> getDataClass() {
+ return Void.class;
}
@Override
- public String serialize(final Object input) {
+ public Void deserializeFromString(final NamespaceContext namespaceContext, final String value) {
return null;
}
@Override
- public void serializeToWriter(final XMLStreamWriter writer, final Object value) throws XMLStreamException {
+ public void serializeToWriter(final XMLStreamWriter writer, final Void value) throws XMLStreamException {
writer.writeCharacters("");
}
}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.xml;
+
+import java.net.URI;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import javax.annotation.Nonnull;
+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.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<>();
+
+ 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);
+ }
+
+ @Override
+ public Class<QName> getDataClass() {
+ return QName.class;
+ }
+
+ /**
+ * Serialize QName with specified XMLStreamWriter.
+ *
+ * @param writer XMLStreamWriter
+ * @param value QName
+ */
+ @Override
+ public void serializeToWriter(final XMLStreamWriter writer, final QName value) throws XMLStreamException {
+ // FIXME: this does not work correctly, as we need to populate entries into the namespace context
+ writer.writeCharacters(serialize(value));
+ }
+
+ @Override
+ public QName deserializeFromString(final NamespaceContext namespaceContext, final String value) {
+ pushNamespaceContext(namespaceContext);
+ try {
+ return deserialize(value);
+ } finally {
+ popNamespaceContext();
+ }
+ }
+
+ 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);
+ }
+ }
+
+ private static void pushNamespaceContext(final NamespaceContext context) {
+ Deque<NamespaceContext> stack = TL_NSCONTEXT.get();
+ if (stack == null) {
+ stack = new ArrayDeque<>(1);
+ TL_NSCONTEXT.set(stack);
+ }
+ stack.push(context);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies, s.r.o. 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.xml;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class NullXmlCodec implements XmlCodec<Object> {
+ static final NullXmlCodec INSTANCE = new NullXmlCodec();
+ private static final Logger LOG = LoggerFactory.getLogger(NullXmlCodec.class);
+
+ private NullXmlCodec() {
+
+ }
+
+ @Override
+ public Class<Object> getDataClass() {
+ return Object.class;
+ }
+
+ @Override
+ public void serializeToWriter(final XMLStreamWriter writer, final Object value) throws XMLStreamException {
+ // NOOP since codec is unkwown.
+ LOG.warn("Call of the serializeToWriter method on null codec. No operation performed.");
+ }
+
+ @Override
+ public Object deserializeFromString(final NamespaceContext namespaceContext, final String value) {
+ LOG.warn("Call of the deserializeString method on null codec. No operation performed.");
+ return null;
+ }
+
+}
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
-final class NumberXmlCodec<T extends Number> extends AbstractXmlCodec<T>{
-
- NumberXmlCodec(final Codec<String, T> codec) {
+final class NumberXmlCodec<T extends Number> extends AbstractXmlCodec<T> {
+ NumberXmlCodec(final DataStringCodec<T> codec) {
super(codec);
}
- /**
- * Serialize specified value with specified XMLStreamWriter.
- *
- * @param writer XMLStreamWriter
- * @param value value which will be serialized to the writer
- */
@Override
- public void serializeToWriter(XMLStreamWriter writer, T value) throws XMLStreamException {
+ public void serializeToWriter(final XMLStreamWriter writer, final T value) throws XMLStreamException {
writer.writeCharacters(String.valueOf(value));
}
}
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.yangtools.concepts.Codec;
+import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
final class QuotedXmlCodec<T> extends AbstractXmlCodec<T> {
-
- QuotedXmlCodec(final Codec<String, T> codec) {
+ QuotedXmlCodec(final DataStringCodec<T> codec) {
super(codec);
}
* @param value value which will be serialized to the writer
*/
@Override
- public void serializeToWriter(XMLStreamWriter writer, T value) throws XMLStreamException {
+ public void serializeToWriter(final XMLStreamWriter writer, final T value) throws XMLStreamException {
writer.writeCharacters(serialize(value));
}
-
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Intel Corporation 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.xml;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
+import com.google.common.collect.ImmutableList;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+abstract class UnionXmlCodec<T> implements XmlCodec<T> {
+ private static final class Diverse extends UnionXmlCodec<Object> {
+ Diverse(final List<XmlCodec<?>> codecs) {
+ super(codecs);
+ }
+
+ @Override
+ public Class<Object> getDataClass() {
+ return Object.class;
+ }
+ }
+
+ private static final class SingleType<T> extends UnionXmlCodec<T> {
+ private final Class<T> dataClass;
+
+ SingleType(final Class<T> dataClass, final List<XmlCodec<?>> codecs) {
+ super(codecs);
+ this.dataClass = Preconditions.checkNotNull(dataClass);
+ }
+
+ @Override
+ public Class<T> getDataClass() {
+ return dataClass;
+ }
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(UnionXmlCodec.class);
+
+ private final List<XmlCodec<?>> codecs;
+
+ UnionXmlCodec(final List<XmlCodec<?>> codecs) {
+ this.codecs = ImmutableList.copyOf(codecs);
+ }
+
+ static UnionXmlCodec<?> create(final UnionTypeDefinition type, final List<XmlCodec<?>> codecs) {
+ final Iterator<XmlCodec<?>> it = codecs.iterator();
+ Verify.verify(it.hasNext(), "Union %s has no subtypes", type);
+
+ Class<?> dataClass = it.next().getDataClass();
+ while (it.hasNext()) {
+ final Class<?> next = it.next().getDataClass();
+ if (!dataClass.equals(next)) {
+ LOG.debug("Type {} has diverse data classes: {} and {}", type, dataClass, next);
+ return new Diverse(codecs);
+ }
+ }
+
+ LOG.debug("Type {} has single data class {}", type, dataClass);
+ return new SingleType<>(dataClass, codecs);
+ }
+
+ @Override
+ public final T deserializeFromString(final NamespaceContext namespaceContext, final String input) {
+ for (XmlCodec<?> codec : codecs) {
+ final Object ret;
+ try {
+ ret = codec.deserializeFromString(namespaceContext, input);
+ } catch (RuntimeException e) {
+ LOG.debug("Codec {} did not accept input '{}'", codec, input, e);
+ continue;
+ }
+
+ return getDataClass().cast(ret);
+ }
+
+ throw new IllegalArgumentException("Invalid value \"" + input + "\" for union type.");
+ }
+
+ @Override
+ public void serializeToWriter(final XMLStreamWriter writer, final Object value) throws XMLStreamException {
+ for (XmlCodec<?> codec : codecs) {
+ if (!codec.getDataClass().isInstance(value)) {
+ LOG.debug("Codec {} cannot accept input {}, skipping it", codec, value);
+ continue;
+ }
+
+ @SuppressWarnings("unchecked")
+ final XmlCodec<Object> objCodec = (XmlCodec<Object>) codec;
+ try {
+ objCodec.serializeToWriter(writer, value);
+ return;
+ } catch (RuntimeException e) {
+ LOG.debug("Codec {} failed to serialize {}", codec, value, e);
+ }
+ }
+
+ throw new IllegalArgumentException("No codecs could serialize" + value);
+ }
+}
package org.opendaylight.yangtools.yang.data.codec.xml;
+import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
-import org.opendaylight.yangtools.concepts.Codec;
-interface XmlCodec<T> extends Codec<String, T> {
+interface XmlCodec<T> {
+ Class<T> getDataClass();
+
+ T deserializeFromString(NamespaceContext namespaceContext, String value);
/**
* Serialize specified value with specified XMLStreamWriter.
package org.opendaylight.yangtools.yang.data.codec.xml;
import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Verify;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import java.util.AbstractMap.SimpleImmutableEntry;
-import java.util.Map.Entry;
-import javax.annotation.Nonnull;
+import java.util.List;
import javax.annotation.concurrent.ThreadSafe;
-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.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.impl.codec.AbstractIntegerStringCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.BinaryStringCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.BitsStringCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.BooleanStringCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.DecimalStringCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.EnumStringCodec;
+import org.opendaylight.yangtools.yang.data.impl.codec.StringStringCodec;
+import org.opendaylight.yangtools.yang.data.util.codec.AbstractCodecFactory;
+import org.opendaylight.yangtools.yang.data.util.codec.SharedCodecCache;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.TypedSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
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.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.opendaylight.yangtools.yang.model.api.type.UnknownTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
@Beta
@ThreadSafe
-public final class XmlCodecFactory {
-
- private static final Logger LOG = LoggerFactory.getLogger(XmlCodecFactory.class);
- private static final XmlCodec<Object> NULL_CODEC = new XmlCodec<Object>() {
- @Override
- public Object deserialize(final String input) {
- return null;
- }
-
- @Override
- public String serialize(final Object input) {
- return null;
- }
-
- @Override
- public void serializeToWriter(final XMLStreamWriter writer, final Object value) throws XMLStreamException {
- // NOOP since codec is unkwown.
- LOG.warn("Call of the serializeToWriter method on XmlCodecFactory.NULL_CODEC object. No operation " +
- "performed.");
- }
- };
-
- private final LoadingCache<Entry<TypedSchemaNode, NamespaceContext>, XmlCodec<?>> codecs = CacheBuilder.newBuilder()
- .softValues().build(new CacheLoader<Entry<TypedSchemaNode, NamespaceContext>, XmlCodec<?>>() {
- @Override
- public XmlCodec<?> load(@Nonnull final Entry<TypedSchemaNode, NamespaceContext> pair) {
- final TypedSchemaNode schemaNode = pair.getKey();
- final TypeDefinition<?> type = schemaNode.getType();
- return createCodec(schemaNode, type, pair.getValue());
- }
- });
-
- private final SchemaContext schemaContext;
+public final class XmlCodecFactory extends AbstractCodecFactory<XmlCodec<?>> {
private XmlCodecFactory(final SchemaContext context) {
- this.schemaContext = Preconditions.checkNotNull(context);
+ super(context, new SharedCodecCache<>());
}
/**
return new XmlCodecFactory(context);
}
- private XmlCodec<?> createCodec(final DataSchemaNode key, final TypeDefinition<?> type,
- final NamespaceContext namespaceContext) {
- if (type instanceof LeafrefTypeDefinition) {
- return createReferencedTypeCodec(key, (LeafrefTypeDefinition) type, namespaceContext);
- } else if (type instanceof IdentityrefTypeDefinition) {
- return createIdentityrefTypeCodec(key, namespaceContext);
- } else if (type instanceof UnionTypeDefinition) {
- return createUnionTypeCodec(key, (UnionTypeDefinition)type, namespaceContext);
- }
- return createFromSimpleType(key, type, namespaceContext);
+ @Override
+ protected XmlCodec<?> binaryCodec(final BinaryTypeDefinition type) {
+ return new QuotedXmlCodec<>(BinaryStringCodec.from(type));
}
- private XmlCodec<?> createReferencedTypeCodec(final DataSchemaNode schema, final LeafrefTypeDefinition type,
- final NamespaceContext namespaceContext) {
- // FIXME: Verify if this does indeed support leafref of leafref
- final TypeDefinition<?> referencedType =
- SchemaContextUtil.getBaseTypeForLeafRef(type, getSchemaContext(), schema);
- Verify.verifyNotNull(referencedType, "Unable to find base type for leafref node '%s'.", schema.getPath());
- return createCodec(schema, referencedType, namespaceContext);
+ @Override
+ protected XmlCodec<?> booleanCodec(final BooleanTypeDefinition type) {
+ return new BooleanXmlCodec(BooleanStringCodec.from(type));
}
- public XmlCodec<QName> createIdentityrefTypeCodec(final DataSchemaNode schema,
- final NamespaceContext namespaceContext) {
- final XmlCodec<QName> xmlStringIdentityrefCodec =
- new XmlStringIdentityrefCodec(getSchemaContext(), schema.getQName().getModule(), namespaceContext);
- return xmlStringIdentityrefCodec;
+ @Override
+ protected XmlCodec<?> bitsCodec(final BitsTypeDefinition type) {
+ return new QuotedXmlCodec<>(BitsStringCodec.from(type));
}
- private XmlCodec<Object> createUnionTypeCodec(final DataSchemaNode schema, final UnionTypeDefinition type,
- final NamespaceContext namespaceContext) {
- final XmlCodec<Object> xmlStringUnionCodec = new XmlStringUnionCodec(schema, type, this, namespaceContext);
- return xmlStringUnionCodec;
+ @Override
+ protected XmlCodec<?> emptyCodec(final EmptyTypeDefinition type) {
+ return EmptyXmlCodec.INSTANCE;
}
- private XmlCodec<?> createFromSimpleType(
- final DataSchemaNode schema, final TypeDefinition<?> type,
- final NamespaceContext namespaceContext) {
- if (type instanceof InstanceIdentifierTypeDefinition) {
- final XmlCodec<YangInstanceIdentifier> iidCodec = new XmlStringInstanceIdentifierCodec(schemaContext, this,
- namespaceContext);
- return iidCodec;
- }
- if (type instanceof EmptyTypeDefinition) {
- return XmlEmptyCodec.INSTANCE;
- }
-
- final TypeDefinitionAwareCodec<Object, ?> codec = TypeDefinitionAwareCodec.from(type);
- if (codec == null) {
- LOG.debug("Codec for type \"{}\" is not implemented yet.", type.getQName().getLocalName());
- return NULL_CODEC;
- }
- return AbstractXmlCodec.create(codec);
+ @Override
+ protected XmlCodec<?> enumCodec(final EnumTypeDefinition type) {
+ return new QuotedXmlCodec<>(EnumStringCodec.from(type));
}
- SchemaContext getSchemaContext() {
- return schemaContext;
+ @Override
+ protected XmlCodec<?> identityRefCodec(final IdentityrefTypeDefinition type, final QNameModule module) {
+ return new IdentityrefXmlCodec(getSchemaContext(), module);
}
- XmlCodec<?> codecFor(final DataSchemaNode schema, final NamespaceContext namespaceContext) {
- Preconditions.checkArgument(schema instanceof TypedSchemaNode, "Unsupported node type %s", schema.getClass());
- return codecs.getUnchecked(new SimpleImmutableEntry<>((TypedSchemaNode)schema, namespaceContext));
+ @Override
+ protected XmlCodec<?> instanceIdentifierCodec(final InstanceIdentifierTypeDefinition type) {
+ return new XmlStringInstanceIdentifierCodec(getSchemaContext(), this);
}
- XmlCodec<?> codecFor(final DataSchemaNode schema, final TypeDefinition<?> unionSubType,
- final NamespaceContext namespaceContext) {
- return createCodec(schema, unionSubType, namespaceContext);
+ @Override
+ protected XmlCodec<?> intCodec(final IntegerTypeDefinition type) {
+ return new NumberXmlCodec<>(AbstractIntegerStringCodec.from(type));
+ }
+
+ @Override
+ protected XmlCodec<?> decimalCodec(final DecimalTypeDefinition type) {
+ return new NumberXmlCodec<>(DecimalStringCodec.from(type));
+ }
+
+ @Override
+ protected XmlCodec<?> stringCodec(final StringTypeDefinition type) {
+ return new QuotedXmlCodec<>(StringStringCodec.from(type));
+ }
+
+ @Override
+ protected XmlCodec<?> uintCodec(final UnsignedIntegerTypeDefinition type) {
+ return new NumberXmlCodec<>(AbstractIntegerStringCodec.from(type));
+ }
+
+ @Override
+ protected XmlCodec<?> unionCodec(final UnionTypeDefinition type, final List<XmlCodec<?>> codecs) {
+ return UnionXmlCodec.create(type, codecs);
+ }
+
+ @Override
+ protected XmlCodec<?> unknownCodec(final UnknownTypeDefinition type) {
+ return NullXmlCodec.INSTANCE;
}
}
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypedSchemaNode;
import org.opendaylight.yangtools.yang.model.api.YangModeledAnyXmlSchemaNode;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
return new DOMSource(doc.getDocumentElement());
}
- return codecs.codecFor(node, namespaceCtx).deserialize(value);
+ Preconditions.checkArgument(node instanceof TypedSchemaNode);
+ return codecs.codecFor((TypedSchemaNode) node).deserializeFromString(namespaceCtx, value);
}
private static AbstractNodeDataWithSchema newEntryNode(final AbstractNodeDataWithSchema parent) {
+++ /dev/null
-/*
- * Copyright (c) 2016 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.xml;
-
-import com.google.common.base.Preconditions;
-import java.net.URI;
-import javax.annotation.Nonnull;
-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.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-final class XmlStringIdentityrefCodec extends ModuleStringIdentityrefCodec implements XmlCodec<QName> {
-
- private final NamespaceContext namespaceContext;
-
- XmlStringIdentityrefCodec(final SchemaContext context, final QNameModule parentModule,
- final NamespaceContext namespaceContext) {
- super(context, parentModule);
- this.namespaceContext = Preconditions.checkNotNull(namespaceContext);
- }
-
- @Override
- protected Module moduleForPrefix(@Nonnull final String prefix) {
- if (prefix.isEmpty()) {
- return context.findModuleByNamespaceAndRevision(parentModuleQname.getNamespace(),
- parentModuleQname.getRevision());
- } else {
- final String prefixedNS = namespaceContext.getNamespaceURI(prefix);
- return context.findModuleByNamespaceAndRevision(URI.create(prefixedNS), null);
- }
- }
-
- /**
- * Serialize QName with specified XMLStreamWriter.
- *
- * @param writer XMLStreamWriter
- * @param value QName
- */
- @Override
- public void serializeToWriter(final XMLStreamWriter writer, final QName value) throws XMLStreamException {
- writer.writeCharacters(serialize(value));
- }
-}
import com.google.common.base.Preconditions;
import java.net.URI;
+import java.util.ArrayDeque;
+import java.util.Deque;
import javax.annotation.Nonnull;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
final class XmlStringInstanceIdentifierCodec extends AbstractModuleStringInstanceIdentifierCodec
implements XmlCodec<YangInstanceIdentifier> {
+ private static final ThreadLocal<Deque<NamespaceContext>> TL_CONTEXT = new ThreadLocal<>();
+
private final DataSchemaContextTree dataContextTree;
private final XmlCodecFactory codecFactory;
private final SchemaContext context;
- private final NamespaceContext namespaceContext;
- XmlStringInstanceIdentifierCodec(final SchemaContext context, final XmlCodecFactory xmlCodecFactory,
- final NamespaceContext namespaceContext) {
+ XmlStringInstanceIdentifierCodec(final SchemaContext context, final XmlCodecFactory xmlCodecFactory) {
this.context = Preconditions.checkNotNull(context);
this.dataContextTree = DataSchemaContextTree.from(context);
this.codecFactory = Preconditions.checkNotNull(xmlCodecFactory);
- this.namespaceContext = Preconditions.checkNotNull(namespaceContext);
}
@Override
protected Module moduleForPrefix(@Nonnull final String prefix) {
- final String prefixedNS = namespaceContext.getNamespaceURI(prefix);
+ final String prefixedNS = getNamespaceContext().getNamespaceURI(prefix);
return context.findModuleByNamespaceAndRevision(URI.create(prefixedNS), null);
}
protected Object deserializeKeyValue(final DataSchemaNode schemaNode, final String value) {
Preconditions.checkNotNull(schemaNode, "schemaNode cannot be null");
Preconditions.checkArgument(schemaNode instanceof LeafSchemaNode, "schemaNode must be of type LeafSchemaNode");
- final XmlCodec<?> objectXmlCodec = codecFactory.codecFor(schemaNode, namespaceContext);
- return objectXmlCodec.deserialize(value);
+ final XmlCodec<?> objectXmlCodec = codecFactory.codecFor((LeafSchemaNode) schemaNode);
+ return objectXmlCodec.deserializeFromString(getNamespaceContext(), value);
+ }
+
+ @Override
+ public Class<YangInstanceIdentifier> getDataClass() {
+ return YangInstanceIdentifier.class;
+ }
+
+ @Override
+ public YangInstanceIdentifier deserializeFromString(final NamespaceContext namespaceContext, final String value) {
+ pushNamespaceContext(namespaceContext);
+ try {
+ return deserialize(value);
+ } finally {
+ popNamespaceContext();
+ }
}
- /**
- * Serialize YangInstanceIdentifier with specified XMLStreamWriter.
- *
- * @param writer XMLStreamWriter
- * @param value YangInstanceIdentifier
- */
@Override
public void serializeToWriter(final XMLStreamWriter writer, final YangInstanceIdentifier value)
throws XMLStreamException {
writer.writeCharacters(serialize(value));
}
+ private static NamespaceContext getNamespaceContext() {
+ return TL_CONTEXT.get().getFirst();
+ }
+
+ private static void popNamespaceContext() {
+ final Deque<NamespaceContext> stack = TL_CONTEXT.get();
+ stack.pop();
+ if (stack.isEmpty()) {
+ TL_CONTEXT.set(null);
+ }
+ }
+
+ private static void pushNamespaceContext(final NamespaceContext context) {
+ Deque<NamespaceContext> stack = TL_CONTEXT.get();
+ if (stack == null) {
+ stack = new ArrayDeque<>(1);
+ TL_CONTEXT.set(stack);
+ }
+ stack.push(context);
+ }
}
+++ /dev/null
-/*
- * Copyright (c) 2016 Intel Corporation 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.xml;
-
-import com.google.common.base.Preconditions;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-
-import org.opendaylight.yangtools.concepts.Codec;
-import org.opendaylight.yangtools.yang.data.util.AbstractStringUnionCodec;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class XmlStringUnionCodec extends AbstractStringUnionCodec implements XmlCodec<Object> {
- private static final Logger LOG = LoggerFactory.getLogger(XmlStringUnionCodec.class);
-
- private final XmlCodecFactory codecFactory;
- private final NamespaceContext namespaceContext;
-
- XmlStringUnionCodec(final DataSchemaNode schema, final UnionTypeDefinition typeDefinition,
- final XmlCodecFactory xmlCodecFactory, final NamespaceContext namespaceContext) {
- super(schema, typeDefinition);
- this.codecFactory = Preconditions.checkNotNull(xmlCodecFactory);
- this.namespaceContext = Preconditions.checkNotNull(namespaceContext);
- }
-
- @Override
- public void serializeToWriter(XMLStreamWriter writer, Object value) throws XMLStreamException {
- writer.writeCharacters(serialize(value));
- }
-
- @Override
- protected Codec<String, Object> codecFor(final TypeDefinition<?> type) {
- return (Codec<String, Object>) codecFactory.codecFor(schema, type, namespaceContext);
- }
-}