+++ /dev/null
-/*
- * 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.sal.binding.generator.impl;
-
-import com.google.common.base.Preconditions;
-
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javassist.ClassPool;
-
-import org.eclipse.xtext.xbase.lib.Extension;
-import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
-import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
-import org.opendaylight.yangtools.util.ClassLoaderUtils;
-import org.opendaylight.yangtools.yang.binding.BindingCodec;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-/**
- * Abstract base class which defines the baseline for the real {@link TransformerGenerator}.
- * This class exists to expose the basic interface and common interactions with the rest
- * of the package.
- */
-abstract class AbstractTransformerGenerator {
- private static final Map<SchemaPath, InstanceIdentifier<?>> PATH_TO_BINDING_IDENTIFIER = new ConcurrentHashMap<>();
-
- /*
- * The generator has to always use this strategy, otherwise we may end up
- * will VerificationErrors.
- */
- @Extension
- protected static final ClassLoadingStrategy CLASS_LOADING_STRATEGY = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
- @Extension
- protected final TypeResolver typeResolver;
- @Extension
- protected final JavassistUtils javAssist;
-
- /*
- * This is effectively final, but we have an implementation circle, where this
- * class notifies LazyGeneratedCodecRegistry and it calls our methods. The
- * listener is initialized to non-null before it is exposed.
- */
- private GeneratorListener listener;
-
- protected AbstractTransformerGenerator(final TypeResolver typeResolver, final ClassPool pool) {
- this.typeResolver = Preconditions.checkNotNull(typeResolver);
- this.javAssist = JavassistUtils.forClassPool(pool);
- }
-
- protected final GeneratorListener getListener() {
- if (listener == null) {
- synchronized (this) {
- Preconditions.checkState(listener != null, "Implementation not fully initialized");
- }
- }
-
- return listener;
- }
-
- synchronized final void setListener(final GeneratorListener listener) {
- Preconditions.checkState(this.listener == null, "Implementation already initialized");
- this.listener = Preconditions.checkNotNull(listener);
- }
-
- protected final <V> V runOnClassLoader(final ClassLoader cls, final Callable<V> function) throws Exception {
- synchronized (javAssist) {
- javAssist.appendClassLoaderIfMissing(cls);
- return ClassLoaderUtils.withClassLoader(cls, function);
- }
- }
-
- protected final InstanceIdentifier<?> getBindingIdentifierByPath(final SchemaPath path) {
- return PATH_TO_BINDING_IDENTIFIER.get(path);
- }
-
- protected final void putPathToBindingIdentifier(final SchemaPath path, final InstanceIdentifier<?> bindingIdentifier) {
- PATH_TO_BINDING_IDENTIFIER.put(path, bindingIdentifier);
- }
-
- protected final InstanceIdentifier<?> putPathToBindingIdentifier(final SchemaPath path,
- final InstanceIdentifier<?> bindingIdentifier, final Class<?> childClass) {
- @SuppressWarnings({ "unchecked", "rawtypes" })
- InstanceIdentifier<?> newId = bindingIdentifier.builder().child((Class) childClass).build();
- PATH_TO_BINDING_IDENTIFIER.put(path, newId);
- return newId;
- }
-
- protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerForImpl(Class<?> inputType);
- protected abstract Class<? extends BindingCodec<Object, Object>> caseCodecForImpl(Class<?> inputType, ChoiceCaseNode node);
- protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiableImpl(Class<?> parentType);
- protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifierImpl(Class<?> inputType);
- protected abstract Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerForImpl(Class<?> inputType);
-
- // Called from LazyGeneratedCodecRegistry
- final Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentationTransformerFor(final Class<?> inputType) throws TransformerGeneratorException {
- try {
- return augmentationTransformerForImpl(inputType);
- } catch (Exception e) {
- throw TransformerGeneratorException.wrap(inputType, e);
- }
- }
-
- final Class<? extends BindingCodec<Object, Object>> caseCodecFor(final Class<?> inputType, final ChoiceCaseNode node) throws TransformerGeneratorException {
- try {
- return caseCodecForImpl(inputType, node);
- } catch (Exception e) {
- throw TransformerGeneratorException.wrap(inputType, e);
- }
- }
-
- final Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifiable(final Class<?> parentType) throws TransformerGeneratorException {
- try {
- return keyTransformerForIdentifiableImpl(parentType);
- } catch (Exception e) {
- throw TransformerGeneratorException.wrap(parentType, e);
- }
- }
-
- final Class<? extends BindingCodec<Map<QName, Object>, Object>> keyTransformerForIdentifier(final Class<?> inputType) throws TransformerGeneratorException {
- try {
- return keyTransformerForIdentifierImpl(inputType);
- } catch (Exception e) {
- throw TransformerGeneratorException.wrap(inputType, e);
- }
- }
-
- final Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(final Class<?> inputType) throws TransformerGeneratorException {
- try {
- return transformerForImpl(inputType);
- } catch (Exception e) {
- throw TransformerGeneratorException.wrap(inputType, e);
- }
- }
-}
+++ /dev/null
-/*
- * 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.sal.binding.generator.impl;
-
-public interface BindingClassListener {
-
- void onBindingClassCaptured(Class<?> cls);
-
- void onBindingClassProcessed(Class<?> cls);
-}
+++ /dev/null
-/*
- * 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.sal.binding.generator.impl;
-
-import java.lang.reflect.Field;
-import java.util.Map;
-import org.opendaylight.yangtools.yang.binding.BindingCodec;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.InstanceIdentifierCodec;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class CodecMapping {
-
- private static final Logger LOG = LoggerFactory.getLogger(CodecMapping.class);
-
- public static final String INSTANCE_IDENTIFIER_CODEC = "INSTANCE_IDENTIFIER_CODEC";
- public static final String IDENTITYREF_CODEC = "IDENTITYREF_CODEC";
-
- public static final String CLASS_TO_CASE_MAP = "CLASS_TO_CASE";
- public static final String COMPOSITE_TO_CASE = "COMPOSITE_TO_CASE";
- public static final String AUGMENTATION_CODEC = "AUGMENTATION_CODEC";
- public static final String DISPATCH_CODEC = "DISPATCH_CODEC";
-
- private CodecMapping() {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
- }
-
- public static void setIdentifierCodec(Class<?> obj,InstanceIdentifierCodec codec) {
- Field instanceIdField;
- try {
- instanceIdField = obj.getField(INSTANCE_IDENTIFIER_CODEC);
- if (instanceIdField != null) {
- instanceIdField.set(null, codec);
- }
- } catch (NoSuchFieldException e) {
- LOG.trace("Instance identifier codec is not needed for {}",obj.getName(),e);
- } catch (SecurityException | IllegalAccessException e) {
- LOG.error("Instance identifier could not be set for {}",obj.getName(),e);
- }
- }
-
- public static void setIdentityRefCodec(Class<?> obj,IdentityCodec<?> codec) {
- Field instanceIdField;
- try {
- instanceIdField = obj.getField(IDENTITYREF_CODEC);
- if (instanceIdField != null) {
- instanceIdField.set(null, codec);
- }
- } catch (NoSuchFieldException e) {
- LOG.trace("Instance identifier codec is not needed for {}",obj.getName(),e);
- } catch (SecurityException | IllegalAccessException e) {
- LOG.error("Instance identifier could not be set for {}",obj.getName(),e);
- }
- }
-
- public static void setClassToCaseMap(Class<? extends BindingCodec<?,?>> codec,
- Map<Class<?>,BindingCodec<?,?>> classToCaseRawCodec) {
- Field instanceIdField;
- try {
- instanceIdField = codec.getField(CLASS_TO_CASE_MAP);
- instanceIdField.set(null, classToCaseRawCodec);
- } catch (NoSuchFieldException e) {
- LOG.debug("BUG: Class to case mappping is not needed for {}",codec.getName(),e);
- } catch (SecurityException | IllegalAccessException e) {
- LOG.error("Class to case mappping could not be set for {}",codec.getName(),e);
- }
- }
-
- public static void setCompositeNodeToCaseMap(Class<? extends BindingCodec<?,?>> codec,
- Map<CompositeNode,BindingCodec<?,?>> compositeToCase) {
- Field instanceIdField;
- try {
- instanceIdField = codec.getField(COMPOSITE_TO_CASE);
- instanceIdField.set(null, compositeToCase);
- } catch (NoSuchFieldException e) {
- LOG.debug("BUG: Class to case mappping is not needed for {}",codec.getName(),e);
- } catch (SecurityException | IllegalAccessException e) {
- LOG.error("Composite node to case mappping could not be set for {}",codec.getName(),e);
- }
- }
-
- public static void setDispatchCodec(Class<? extends BindingCodec<?,?>> codec,
- BindingCodec<?, ?> dispatchCodec) {
- Field instanceIdField;
- try {
- instanceIdField = codec.getField(DISPATCH_CODEC);
- instanceIdField.set(null, dispatchCodec);
- } catch (NoSuchFieldException e) {
- LOG.debug("BUG: dispatch codec is not needed for {}",codec.getName(),e);
- } catch (SecurityException | IllegalAccessException e) {
- LOG.error("Dispatch codec could not be set for {}",codec.getName(),e);
- }
- }
-
- public static void setAugmentationCodec(Class<? extends BindingCodec<?,?>> dataCodec,
- BindingCodec<?,?> augmentableCodec) {
- Field instanceIdField;
- try {
- instanceIdField = dataCodec.getField(AUGMENTATION_CODEC);
- instanceIdField.set(null, augmentableCodec);
- } catch (NoSuchFieldException e) {
- LOG.debug("BUG: Augmentation codec is not needed for {}",dataCodec.getName(),e);
- } catch (SecurityException | IllegalAccessException e) {
- LOG.error("Augmentation codec could not be set for {}",dataCodec.getName(),e);
- }
- }
-
-
- public static BindingCodec<?,?> getAugmentationCodec(Class<? extends BindingCodec<?,?>> dataCodec) {
- Field instanceIdField;
- try {
- instanceIdField = dataCodec.getField(AUGMENTATION_CODEC);
- return (BindingCodec<?,?>) instanceIdField.get(null);
- } catch (NoSuchFieldException e) {
- LOG.debug("BUG: Augmentation codec is not needed for {}",dataCodec.getName(),e);
- } catch (SecurityException | IllegalAccessException e) {
- LOG.error("Augmentation codec could not be set for {}",dataCodec.getName(),e);
- }
- return null;
- }
-}
+++ /dev/null
-/*
- * 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.sal.binding.generator.impl;
-
-import java.util.Map;
-import org.opendaylight.yangtools.yang.binding.BindingCodec;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-
-public interface GeneratorListener {
- void onClassProcessed(Class<?> cl);
-
- void onCodecCreated(Class<?> codec);
- void onValueCodecCreated(Class<?> valueClass, Class<?> valueCodec);
- void onCaseCodecCreated(Class<?> choiceClass, Class<? extends BindingCodec<Map<QName, Object>, Object>> choiceCodec);
- void onDataContainerCodecCreated(Class<?> dataClass, Class<? extends BindingCodec<?, ?>> dataCodec);
-
- void onChoiceCodecCreated(Class<?> choiceClass,
- Class<? extends BindingCodec<Map<QName, Object>, Object>> choiceCodec, ChoiceSchemaNode schema);
-}
+++ /dev/null
-/**
- * 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.sal.binding.generator.impl;
-
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-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.PathArgument;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentifierCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.InstanceIdentifierCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
- private static final Logger LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl.class);
-
- private final CodecRegistry codecRegistry;
-
- private final Map<Class<?>,Set<List<QName>>> augmentationAdapted = new WeakHashMap<>();
-
- private final Map<Class<?>, Map<List<QName>, Class<?>>> classToPreviousAugment = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, Map<List<QName>, Class<?>>>());
-
- public InstanceIdentifierCodecImpl(final CodecRegistry registry) {
- this.codecRegistry = registry;
- }
-
- @Override
- public InstanceIdentifier<? extends Object> deserialize(
- final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier input) {
- Class<?> baType = null;
- Iterable<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument> biArgs = input.getPathArguments();
- List<QName> scannedPath = new ArrayList<>();
- List<InstanceIdentifier.PathArgument> baArgs = new ArrayList<InstanceIdentifier.PathArgument>();
- for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument biArg : biArgs) {
-
- scannedPath.add(biArg.getNodeType());
- org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument baArg = deserializePathArgument(
- biArg, scannedPath);
- if (baArg != null) {
- baType = baArg.getType();
- }
- Map<List<QName>, Class<?>> injectAugment = classToPreviousAugment.get(baType);
- if (injectAugment != null) {
- @SuppressWarnings("unchecked")
- Class<? extends DataObject> augment = (Class<? extends DataObject>) injectAugment.get(scannedPath);
- if (augment != null) {
- baArgs.add(new Item(augment));
- }
- }
- baArgs.add(baArg);
- }
- InstanceIdentifier<?> ret = InstanceIdentifier.create(baArgs);
- LOG.debug("DOM Instance Identifier {} deserialized to {}", input, ret);
- return ret;
- }
-
- @Override
- public InstanceIdentifier<? extends Object> deserialize(
- final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier input,
- final InstanceIdentifier<?> bindingIdentifier) {
- return deserialize(input);
- }
-
- private InstanceIdentifier.PathArgument deserializeNodeIdentifier(
- final NodeIdentifier argument, final List<QName> processedPath) {
- @SuppressWarnings("rawtypes")
- final Class cls = codecRegistry.getClassForPath(processedPath);
- @SuppressWarnings("unchecked")
- Item<DataObject> item = new Item<>(cls);
- return item;
- }
-
- private InstanceIdentifier.PathArgument deserializeNodeIdentifierWithPrecicates(
- final NodeIdentifierWithPredicates argument, final List<QName> processedPath) {
- @SuppressWarnings("rawtypes")
- final Class type = codecRegistry.getClassForPath(processedPath);
- @SuppressWarnings({ "unchecked", "rawtypes" })
- final IdentifierCodec codec = codecRegistry
- .<Identifiable<? extends Object>> getIdentifierCodecForIdentifiable(type);
- CompositeNode _compositeNode = this.toCompositeNode(argument);
- @SuppressWarnings("unchecked")
- ValueWithQName<CompositeNode> deserialize = codec.deserialize(_compositeNode);
- Object value = null;
- if (deserialize != null) {
- value = deserialize.getValue();
- }
- return CodecTypeUtils.newIdentifiableItem(type, value);
- }
-
- public CompositeNode toCompositeNode(final NodeIdentifierWithPredicates predicates) {
- Set<Map.Entry<QName, Object>> keyValues = predicates.getKeyValues().entrySet();
- List<Node<?>> values = new ArrayList<>(keyValues.size());
- for (Map.Entry<QName, Object> keyValue : keyValues) {
- values.add(new SimpleNodeTOImpl<Object>(keyValue.getKey(), null, keyValue.getValue()));
- }
- return new CompositeNodeTOImpl(predicates.getNodeType(), null, values);
- }
-
- @Override
- public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier serialize(final InstanceIdentifier<?> input) {
- Class<?> previousAugmentation = null;
- Iterable<InstanceIdentifier.PathArgument> pathArgs = input.getPathArguments();
- QName previousQName = null;
- List<PathArgument> components = new ArrayList<>();
- List<QName> qnamePath = new ArrayList<>();
- for (InstanceIdentifier.PathArgument baArg : pathArgs) {
- if (!Augmentation.class.isAssignableFrom(baArg.getType())) {
- PathArgument biArg = serializePathArgumentAndUpdateMapping(qnamePath, baArg, previousQName,previousAugmentation);
- components.add(biArg);
- qnamePath.add(biArg.getNodeType());
- previousQName = biArg.getNodeType();
- previousAugmentation = null;
- } else {
- previousQName = codecRegistry.getQNameForAugmentation(baArg.getType());
- previousAugmentation = baArg.getType();
- ensureAugmentation(qnamePath,previousQName,baArg.getType());
- }
- }
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier ret =
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.create(components);
- LOG.debug("Binding Instance Identifier {} serialized to DOM InstanceIdentifier {}", input, ret);
- return ret;
- }
-
- private synchronized void ensureAugmentation(final List<QName> augPath, final QName augQName, final Class<? extends DataObject> type) {
- Set<List<QName>> augPotential = augmentationAdapted.get(type);
- if(augPotential == null) {
- augPotential = new HashSet<>();
- augmentationAdapted.put(type, augPotential);
- }
- ImmutableList<QName> augTargetPath = ImmutableList.copyOf(augPath);
- if(augPotential.contains(augPath)) {
- return;
- }
-
- for(Class<? extends DataObject> child : BindingReflections.getChildrenClasses(type)) {
- Item<? extends DataObject> baArg = new Item<>(child);
- PathArgument biArg = serializePathArgumentAndUpdateMapping(augPath, baArg, augQName,type);
- }
- augPotential.add(augTargetPath);
- }
-
-
- public Class<? extends Object> updateAugmentationInjection(final Class<? extends DataObject> class1,
- final List<QName> list, final Class<?> augmentation) {
- if (classToPreviousAugment.get(class1) == null) {
- classToPreviousAugment.put(class1, new ConcurrentHashMap<List<QName>, Class<?>>());
- }
- return classToPreviousAugment.get(class1).put(list, augmentation);
- }
-
- private PathArgument serializeItem(final Item<?> argument, final QName previousQname) {
- Class<?> type = argument.getType();
- QName qname = BindingReflections.findQName(type);
- if (previousQname == null || (BindingReflections.isAugmentationChild(argument.getType()))) {
- return new NodeIdentifier(qname);
- }
- return new NodeIdentifier(QName.create(previousQname, qname.getLocalName()));
- }
-
- private PathArgument serializeIdentifiableItem(final IdentifiableItem<?,?> argument, final QName previousQname) {
- @SuppressWarnings("rawtypes")
- Class type = argument.getType();
- @SuppressWarnings("unchecked")
- IdentifierCodec<? extends Object> keyCodec = codecRegistry.getIdentifierCodecForIdentifiable(type);
- QName qname = BindingReflections.findQName(type);
- if (previousQname != null && !(BindingReflections.isAugmentationChild(argument.getType()))) {
- qname = QName.create(previousQname, qname.getLocalName());
- }
- @SuppressWarnings({ "rawtypes", "unchecked" })
- ValueWithQName combinedInput = new ValueWithQName(previousQname, argument.getKey());
- @SuppressWarnings("unchecked")
- CompositeNode compositeOutput = keyCodec.serialize(combinedInput);
-
- final Map<QName, Object> predicates = new LinkedHashMap<>();
- for (Node<?> outputValue : compositeOutput.getValue()) {
- predicates.put(outputValue.getNodeType(), outputValue.getValue());
- }
- if (previousQname == null) {
- return new NodeIdentifierWithPredicates(qname, predicates);
- }
- return new NodeIdentifierWithPredicates(qname, predicates);
- }
-
- private org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument deserializePathArgument(
- final PathArgument argument, final List<QName> processedPath) {
- if (argument instanceof NodeIdentifier) {
- return deserializeNodeIdentifier((NodeIdentifier) argument, processedPath);
- } else if (argument instanceof NodeIdentifierWithPredicates) {
- return deserializeNodeIdentifierWithPrecicates((NodeIdentifierWithPredicates) argument, processedPath);
- } else {
- throw new IllegalArgumentException("Unhandled parameter types: "
- + Arrays.<Object> asList(argument, processedPath).toString());
- }
- }
-
- private PathArgument serializePathArgumentAndUpdateMapping(final List<QName> parentPath, final InstanceIdentifier.PathArgument baArg, final QName previousQName, final Class<?> previousAugmentation) {
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument biArg = serializePathArgument(baArg, previousQName);
- List<QName> qnamePath = new ArrayList<>(parentPath);
- qnamePath.add(biArg.getNodeType());
- ImmutableList<QName> currentPath = ImmutableList.copyOf(qnamePath);
- codecRegistry.putPathToClass(currentPath, baArg.getType());
- if (previousAugmentation != null) {
- updateAugmentationInjection(baArg.getType(), currentPath, previousAugmentation);
- }
- return biArg;
- }
-
- private PathArgument serializePathArgument(
- final InstanceIdentifier.PathArgument argument,
- final QName previousQname) {
- if (argument instanceof IdentifiableItem) {
- return serializeIdentifiableItem((IdentifiableItem<?,?>) argument, previousQname);
- } else if (argument instanceof Item) {
- return serializeItem((Item<?>) argument, previousQname);
- } else {
- throw new IllegalArgumentException("Unhandled parameter types: "
- + Arrays.<Object> asList(argument, previousQname).toString());
- }
- }
-
-
-
-}
+++ /dev/null
-/**
- * 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.sal.binding.generator.impl;
-
-import com.google.common.base.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
-
-/**
- * @deprecated Use {@link NormalizedNode} and their stream writer codec suite.
- */
-@Deprecated
-public class IntermediateMapping {
- private IntermediateMapping() {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
- }
-
- public static Node<? extends Object> toNode(final Map<? extends Object, ? extends Object> map) {
- if ((map instanceof Node<?>)) {
- return ((Node<?>) map);
- }
- @SuppressWarnings("unchecked")
- final Map<QName, Object> nodeMap = ((Map<QName, Object>) map);
- Preconditions.checkArgument(map.size() == 1);
- final Entry<QName, Object> elem = nodeMap.entrySet().iterator().next();
- final QName qname = elem.getKey();
- final Object value = elem.getValue();
- return toNodeImpl(qname, value);
- }
-
- protected static Node<? extends Object> _toNodeImpl(final QName name, final List<? extends Object> objects) {
- List<Node<? extends Object>> values = new ArrayList<>(objects.size());
- for (Object obj : objects) {
- if ((obj instanceof Node<?>)) {
- values.add(((Node<?>) obj));
- } else {
- if ((obj instanceof Map<?, ?>)) {
- Node<? extends Object> _node = IntermediateMapping.toNode(((Map<?, ?>) obj));
- values.add(_node);
- }
- }
- }
- return new CompositeNodeTOImpl(name, null, values);
- }
-
- protected static Node<? extends Object> _toNodeImpl(final QName name, final Map<QName, Object> object) {
- throw new UnsupportedOperationException("Unsupported node hierarchy.");
- }
-
- protected static Node<? extends Object> _toNodeImpl(final QName name, final Object object) {
- return new SimpleNodeTOImpl<Object>(name, null, object);
- }
-
- @SuppressWarnings("unchecked")
- public static Node<? extends Object> toNodeImpl(final QName name, final Object objects) {
- if (objects instanceof List) {
- return _toNodeImpl(name, (List<?>) objects);
- } else if (objects instanceof Map) {
- return _toNodeImpl(name, (Map<QName, Object>) objects);
- } else if (objects != null) {
- return _toNodeImpl(name, objects);
- } else {
- throw new IllegalArgumentException("Unhandled parameter types: "
- + Arrays.<Object> asList(name, objects).toString());
- }
- }
-
-}
+++ /dev/null
-/*
- * 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.sal.binding.generator.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
-import org.opendaylight.yangtools.binding.generator.util.Types;
-import org.opendaylight.yangtools.concepts.Delegator;
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
-import org.opendaylight.yangtools.sal.binding.generator.util.CodeGenerationException;
-import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType;
-import org.opendaylight.yangtools.sal.binding.model.api.Type;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;
-import org.opendaylight.yangtools.util.ClassLoaderUtils;
-import org.opendaylight.yangtools.yang.binding.Augmentable;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.BaseIdentity;
-import org.opendaylight.yangtools.yang.binding.BindingCodec;
-import org.opendaylight.yangtools.yang.binding.BindingMapping;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.codec.AugmentationCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.ChoiceCaseCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.ChoiceCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.opendaylight.yangtools.yang.data.impl.codec.DataContainerCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.DomCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentifierCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.InstanceIdentifierCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-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.SchemaContextListener;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class LazyGeneratedCodecRegistry implements CodecRegistry, SchemaContextListener, GeneratorListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(LazyGeneratedCodecRegistry.class);
-
- // Concrete class to codecs
- private static final Map<Class<?>, DataContainerCodec<?>> containerCodecs = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, DataContainerCodec<?>>());
- private static final Map<Class<?>, IdentifierCodec<?>> identifierCodecs = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, IdentifierCodec<?>>());
- private static final Map<Class<?>, PublicChoiceCodecImpl<?>> choiceCodecs = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, PublicChoiceCodecImpl<?>>());
- private static final Map<Class<?>, ChoiceCaseCodecImpl<?>> caseCodecs = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, ChoiceCaseCodecImpl<?>>());
- private static final Map<Class<?>, AugmentableDispatchCodec> augmentableCodecs = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, AugmentableDispatchCodec>());
- private static final Map<Class<?>, AugmentationCodecWrapper<?>> augmentationCodecs = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, AugmentationCodecWrapper<?>>());
-
- private static final Map<Class<?>, LocationAwareDispatchCodec<?>> dispatchCodecs = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, LocationAwareDispatchCodec<?>>());
-
- private static final Map<Class<?>, QName> identityQNames = Collections
- .synchronizedMap(new WeakHashMap<Class<?>, QName>());
- private static final Map<QName, Type> qnamesToIdentityMap = new ConcurrentHashMap<>();
-
- private static final ConcurrentMap<Type, ChoiceCaseNode> caseTypeToCaseSchema = new ConcurrentHashMap<>();
-
- private static final Map<SchemaPath, Type> pathToType = new ConcurrentHashMap<>();
- private static final Map<List<QName>, Type> pathToInstantiatedType = new ConcurrentHashMap<>();
- private static final Map<Type, QName> typeToQname = new ConcurrentHashMap<>();
- private static final BiMap<Type, AugmentationSchema> typeToAugment = HashBiMap
- .create(new ConcurrentHashMap<Type, AugmentationSchema>());
-
- private static final Multimap<Type, Type> augmentableToAugmentations = Multimaps.synchronizedMultimap(HashMultimap
- .<Type, Type> create());
- private static final Multimap<Type, Type> choiceToCases = Multimaps.synchronizedMultimap(HashMultimap
- .<Type, Type> create());
-
- private final InstanceIdentifierCodec instanceIdentifierCodec = new InstanceIdentifierCodecImpl(this);
- private final IdentityCompositeCodec identityRefCodec = new IdentityCompositeCodec();
- private final ClassLoadingStrategy classLoadingStrategy;
- private final AbstractTransformerGenerator generator;
- private final SchemaLock lock;
-
- // FIXME: how is this protected?
- private SchemaContext currentSchema;
-
- LazyGeneratedCodecRegistry(final SchemaLock lock, final AbstractTransformerGenerator generator,
- final ClassLoadingStrategy classLoadingStrategy) {
- this.lock = Preconditions.checkNotNull(lock);
- this.classLoadingStrategy = Preconditions.checkNotNull(classLoadingStrategy);
- this.generator = Preconditions.checkNotNull(generator);
- }
-
- public SchemaLock getLock() {
- return lock;
- }
-
- @Override
- public InstanceIdentifierCodec getInstanceIdentifierCodec() {
- return instanceIdentifierCodec;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T extends Augmentation<?>> AugmentationCodecWrapper<T> getCodecForAugmentation(final Class<T> augClass) {
- AugmentationCodecWrapper<T> codec = null;
- @SuppressWarnings("rawtypes")
- AugmentationCodecWrapper potentialCodec = augmentationCodecs.get(augClass);
- if (potentialCodec != null) {
- codec = potentialCodec;
- } else {
- lock.waitForSchema(augClass);
- Class<? extends BindingCodec<Map<QName, Object>, Object>> augmentRawCodec = generator
- .augmentationTransformerFor(augClass);
-
- BindingCodec<Map<QName, Object>, Object> rawCodec = newInstanceOf(augmentRawCodec);
- codec = new AugmentationCodecWrapper<T>(rawCodec, augClass);
- augmentationCodecs.put(augClass, codec);
- }
-
- final Class<? extends Augmentable<?>> objectSupertype;
- try {
- objectSupertype = BindingReflections.findAugmentationTarget(augClass);
- } catch (Exception e) {
- LOG.warn("Failed to find target for augmentation {}, ignoring it", augClass, e);
- return codec;
- }
-
- if (objectSupertype == null) {
- LOG.warn("Augmentation target for {} not found, ignoring it", augClass);
- return codec;
- }
-
- getAugmentableCodec(objectSupertype).addImplementation(codec);
- return codec;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public QName getQNameForAugmentation(final Class<?> cls) {
- Preconditions.checkArgument(Augmentation.class.isAssignableFrom(cls));
- return getCodecForAugmentation((Class<? extends Augmentation<?>>) cls).getAugmentationQName();
- }
-
- @Override
- public Class<?> getClassForPath(final List<QName> names) {
- DataSchemaNode node = getSchemaNode(names);
- Preconditions.checkArgument(node != null, "Path %s points to invalid schema location", names);
- SchemaNode originalDefinition = SchemaNodeUtils.getRootOriginalIfPossible(node);
- if (originalDefinition instanceof DataSchemaNode) {
- node = (DataSchemaNode) originalDefinition;
- }
- final SchemaPath path = node.getPath();
- final Type t = pathToType.get(path);
-
- final Type type;
- if (t != null) {
- type = new ReferencedTypeImpl(t.getPackageName(), t.getName());
- } else {
- type = pathToInstantiatedType.get(names);
- Preconditions.checkState(type != null, "Failed to lookup instantiated type for path %s", path);
- }
-
- try {
- return classLoadingStrategy.loadClass(type);
- } catch (ClassNotFoundException e) {
- throw new IllegalStateException(String.format("Could not find loaded class for path: %s and type: %s",
- path, type.getFullyQualifiedName()));
- }
- }
-
- @Override
- public void putPathToClass(final List<QName> names, final Class<?> cls) {
- final Type reference = Types.typeForClass(cls);
- pathToInstantiatedType.put(names, reference);
- LOG.trace("Path {} attached to class {} reference {}", names, cls, reference);
- bindingClassEncountered(cls);
- }
-
- @Override
- public IdentifierCodec<?> getKeyCodecForPath(final List<QName> names) {
- @SuppressWarnings("unchecked")
- Class<? extends Identifiable<?>> cls = (Class<? extends Identifiable<?>>) getClassForPath(names);
- return getIdentifierCodecForIdentifiable(cls);
- }
-
- @Override
- public <T extends DataContainer> DataContainerCodec<T> getCodecForDataObject(final Class<T> type) {
- @SuppressWarnings("unchecked")
- DataContainerCodec<T> ret = (DataContainerCodec<T>) containerCodecs.get(type);
- if (ret != null) {
- return ret;
- }
- Class<? extends BindingCodec<Map<QName, Object>, Object>> newType = generator.transformerFor(type);
- BindingCodec<Map<QName, Object>, Object> rawCodec = newInstanceOf(newType);
- DataContainerCodecImpl<T> newWrapper = new DataContainerCodecImpl<>(rawCodec);
- containerCodecs.put(type, newWrapper);
- return newWrapper;
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- public void bindingClassEncountered(final Class cls) {
- if (Augmentation.class.isAssignableFrom(cls)) {
- // Intentionally NOOP
- } else if (DataObject.class.isAssignableFrom(cls)) {
- getCodecForDataObject((Class<? extends DataObject>) cls);
- }
- }
-
- @Override
- public void onClassProcessed(final Class<?> cls) {
-
- }
-
- private DataSchemaNode getSchemaNode(final List<QName> path) {
- QName firstNode = path.get(0);
- DataNodeContainer previous = currentSchema.findModuleByNamespaceAndRevision(firstNode.getNamespace(),
- firstNode.getRevision());
- Preconditions.checkArgument(previous != null, "Failed to find module %s for path %s", firstNode, path);
-
- Iterator<QName> iterator = path.iterator();
- while (iterator.hasNext()) {
- QName arg = iterator.next();
- DataSchemaNode currentNode = previous.getDataChildByName(arg);
- if (currentNode == null) {
- currentNode = searchInChoices(previous, arg);
- }
- if (currentNode instanceof DataNodeContainer) {
- previous = (DataNodeContainer) currentNode;
- } else if (currentNode instanceof LeafSchemaNode || currentNode instanceof LeafListSchemaNode) {
- Preconditions.checkState(!iterator.hasNext(), "Path tries to nest inside leaf node.");
- return currentNode;
- }
- }
- return (DataSchemaNode) previous;
- }
-
- private DataSchemaNode searchInChoices(final DataNodeContainer node, final QName arg) {
- for (DataSchemaNode child : node.getChildNodes()) {
- if (child instanceof ChoiceSchemaNode) {
- ChoiceSchemaNode choiceNode = (ChoiceSchemaNode) child;
- DataSchemaNode potential = searchInCases(choiceNode, arg);
- if (potential != null) {
- return potential;
- }
- }
- }
- return null;
- }
-
- private DataSchemaNode searchInCases(final ChoiceSchemaNode choiceNode, final QName arg) {
- Set<ChoiceCaseNode> cases = choiceNode.getCases();
- for (ChoiceCaseNode caseNode : cases) {
- DataSchemaNode node = caseNode.getDataChildByName(arg);
- if (node != null) {
- return node;
- }
- }
- return null;
- }
-
- private static <T> T newInstanceOf(final Class<?> cls) {
- try {
- @SuppressWarnings("unchecked")
- T ret = (T) cls.newInstance();
- return ret;
- } catch (InstantiationException e) {
- LOG.error("Failed to instantiate codec {}", cls.getSimpleName(), e);
- throw new IllegalStateException(String.format("Failed to instantiate codec %s", cls), e);
- } catch (IllegalAccessException e) {
- LOG.debug(
- "Run-time consistency issue: constructor for {} is not available. This indicates either a code generation bug or a misconfiguration of JVM.",
- cls.getSimpleName(), e);
- throw new IllegalStateException(String.format("Cannot access contructor of %s", cls), e);
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public IdentifierCodec<?> getIdentifierCodecForIdentifiable(final Class identifiable) {
-
- Class identifier = ClassLoaderUtils.findFirstGenericArgument(identifiable,
- org.opendaylight.yangtools.yang.binding.Identifiable.class);
- IdentifierCodec<?> obj = identifierCodecs.get(identifier);
- if (obj != null) {
- return obj;
- }
- return createIdentifierCodec(identifier, identifiable);
- }
-
- @Override
- public <T extends Identifier<?>> IdentifierCodec<T> getCodecForIdentifier(final Class<T> identifier) {
- @SuppressWarnings("unchecked")
- IdentifierCodec<T> obj = (IdentifierCodec<T>) identifierCodecs.get(identifier);
- if (obj != null) {
- return obj;
- }
- Class<? extends Identifiable<T>> identifiable = ClassLoaderUtils.findFirstGenericArgument(identifier,
- Identifier.class);
- return createIdentifierCodec(identifier, identifiable);
- }
-
- private <T extends Identifier<?>> IdentifierCodec<T> createIdentifierCodec(final Class<T> identifier,
- final Class<? extends Identifiable<T>> identifiable) {
- Class<? extends BindingCodec<Map<QName, Object>, Object>> newCodec = generator
- .keyTransformerForIdentifiable(identifiable);
- BindingCodec<Map<QName, Object>, Object> newInstance;
- newInstance = newInstanceOf(newCodec);
- IdentifierCodecImpl<T> newWrapper = new IdentifierCodecImpl<>(newInstance);
- identifierCodecs.put(identifier, newWrapper);
- return newWrapper;
- }
-
- @Override
- public IdentityCodec<?> getIdentityCodec() {
- return identityRefCodec;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public <T extends BaseIdentity> IdentityCodec<T> getCodecForIdentity(final Class<T> codec) {
- bindingClassEncountered(codec);
- return identityRefCodec;
- }
-
- @Override
- public void onCodecCreated(final Class<?> cls) {
- CodecMapping.setIdentifierCodec(cls, instanceIdentifierCodec);
- CodecMapping.setIdentityRefCodec(cls, identityRefCodec);
- }
-
- @SuppressWarnings("rawtypes")
- public ChoiceCaseCodecImpl getCaseCodecFor(final Class caseClass) {
- ChoiceCaseCodecImpl<?> potential = caseCodecs.get(caseClass);
- if (potential != null) {
- return potential;
- }
- ConcreteType typeref = Types.typeForClass(caseClass);
- ChoiceCaseNode caseSchema = caseTypeToCaseSchema.get(typeref);
-
- Preconditions.checkState(caseSchema != null, "Case schema is not available for %s", caseClass.getName());
- Class<? extends BindingCodec> newCodec = generator.caseCodecFor(caseClass, caseSchema);
- BindingCodec newInstance = newInstanceOf(newCodec);
- @SuppressWarnings("unchecked")
- ChoiceCaseCodecImpl caseCodec = new ChoiceCaseCodecImpl(caseClass, caseSchema, newInstance);
- caseCodecs.put(caseClass, caseCodec);
- return caseCodec;
- }
-
- public void onModuleContextAdded(final SchemaContext schemaContext, final Module module, final ModuleContext context) {
- pathToType.putAll(context.getChildNodes());
-
- BiMap<Type, AugmentationSchema> bimap = context.getTypeToAugmentation();
- for (Map.Entry<Type, AugmentationSchema> entry : bimap.entrySet()) {
- Type key = entry.getKey();
- AugmentationSchema value = entry.getValue();
- Collection<DataSchemaNode> augmentedNodes = value.getChildNodes();
- if (augmentedNodes != null && !augmentedNodes.isEmpty()) {
- typeToAugment.put(key, value);
- }
- }
-
- qnamesToIdentityMap.putAll(context.getIdentities());
- for (Entry<QName, GeneratedTOBuilder> identity : context.getIdentities().entrySet()) {
- typeToQname.put(
- new ReferencedTypeImpl(identity.getValue().getPackageName(), identity.getValue().getName()),
- identity.getKey());
- }
-
- synchronized (augmentableToAugmentations) {
- augmentableToAugmentations.putAll(context.getAugmentableToAugmentations());
- }
- synchronized (choiceToCases) {
- choiceToCases.putAll(context.getChoiceToCases());
- }
- synchronized (caseTypeToCaseSchema) {
- caseTypeToCaseSchema.putAll(context.getCaseTypeToSchemas());
- }
- }
-
- @Override
- public void onGlobalContextUpdated(final SchemaContext context) {
- currentSchema = context;
- resetDispatchCodecsAdaptation();
-
- }
-
- /**
- * Resets / clears adaptation for all schema context sensitive codecs in
- * order for them to adapt to new schema context and maybe newly discovered
- * augmentations This ensure correct behaviour for augmentations and
- * augmented cases for preexisting codecs, which augmentations were
- * introduced at later point in time.
- *
- * This also makes removed augmentations unavailable.
- */
- private void resetDispatchCodecsAdaptation() {
- synchronized (dispatchCodecs) {
- for (LocationAwareDispatchCodec<?> codec : dispatchCodecs.values()) {
- codec.resetCodec(this);
- }
- }
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- public void onChoiceCodecCreated(final Class<?> choiceClass,
- final Class<? extends BindingCodec<Map<QName, Object>, Object>> choiceCodec, final ChoiceSchemaNode schema) {
- ChoiceCodec<?> oldCodec = choiceCodecs.get(choiceClass);
- Preconditions.checkState(oldCodec == null);
- BindingCodec<Map<QName, Object>, Object> delegate = newInstanceOf(choiceCodec);
- PublicChoiceCodecImpl<?> newCodec = new PublicChoiceCodecImpl(delegate);
- DispatchChoiceCodecImpl dispatchCodec = new DispatchChoiceCodecImpl(choiceClass, this);
- choiceCodecs.put(choiceClass, newCodec);
- synchronized (dispatchCodecs) {
- dispatchCodecs.put(choiceClass, dispatchCodec);
- }
- CodecMapping.setDispatchCodec(choiceCodec, dispatchCodec);
- }
-
- @Override
- public void onValueCodecCreated(final Class<?> valueClass, final Class<?> valueCodec) {
- }
-
- @Override
- public void onCaseCodecCreated(final Class<?> choiceClass,
- final Class<? extends BindingCodec<Map<QName, Object>, Object>> choiceCodec) {
- }
-
- @Override
- public void onDataContainerCodecCreated(final Class<?> dataClass,
- final Class<? extends BindingCodec<?, ?>> dataCodec) {
- if (Augmentable.class.isAssignableFrom(dataClass)) {
- AugmentableDispatchCodec augmentableCodec = getAugmentableCodec(dataClass);
- CodecMapping.setAugmentationCodec(dataCodec, augmentableCodec);
- }
- }
-
- public synchronized AugmentableDispatchCodec getAugmentableCodec(final Class<?> dataClass) {
- AugmentableDispatchCodec ret = augmentableCodecs.get(dataClass);
- if (ret != null) {
- return ret;
- }
- ret = new AugmentableDispatchCodec(dataClass, this);
- augmentableCodecs.put(dataClass, ret);
- synchronized (dispatchCodecs) {
- dispatchCodecs.put(dataClass, ret);
- }
- ret.tryToLoadImplementations();
- return ret;
- }
-
- private static abstract class IntermediateCodec<T> implements DomCodec<T>,
- Delegator<BindingCodec<Map<QName, Object>, Object>> {
-
- private final BindingCodec<Map<QName, Object>, Object> delegate;
-
- @Override
- public BindingCodec<Map<QName, Object>, Object> getDelegate() {
- return delegate;
- }
-
- public IntermediateCodec(final BindingCodec<Map<QName, Object>, Object> delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public Node<?> serialize(final ValueWithQName<T> input) {
- Map<QName, Object> intermediateOutput = delegate.serialize(input);
- return IntermediateMapping.toNode(intermediateOutput);
- }
-
- }
-
- private static class IdentifierCodecImpl<T extends Identifier<?>> extends IntermediateCodec<T> implements
- IdentifierCodec<T> {
-
- public IdentifierCodecImpl(final BindingCodec<Map<QName, Object>, Object> delegate) {
- super(delegate);
- }
-
- @Override
- public ValueWithQName<T> deserialize(final Node<?> input) {
- QName qname = input.getNodeType();
- @SuppressWarnings("unchecked")
- T value = (T) getDelegate().deserialize((Map<QName, Object>) input);
- return new ValueWithQName<T>(qname, value);
- }
-
- @Override
- public ValueWithQName<T> deserialize(final Node<?> input, final InstanceIdentifier<?> bindingIdentifier) {
- QName qname = input.getNodeType();
- @SuppressWarnings("unchecked")
- T value = (T) getDelegate().deserialize((Map<QName, Object>) input, bindingIdentifier);
- return new ValueWithQName<T>(qname, value);
- }
-
- @Override
- public CompositeNode serialize(final ValueWithQName<T> input) {
- return (CompositeNode) super.serialize(input);
- }
- }
-
- private static class DataContainerCodecImpl<T extends DataContainer> extends IntermediateCodec<T> implements
- DataContainerCodec<T> {
-
- public DataContainerCodecImpl(final BindingCodec<Map<QName, Object>, Object> delegate) {
- super(delegate);
- }
-
- @Override
- public ValueWithQName<T> deserialize(final Node<?> input) {
- if (input == null) {
- return null;
- }
- QName qname = input.getNodeType();
- @SuppressWarnings("unchecked")
- T value = (T) getDelegate().deserialize((Map<QName, Object>) input);
- return new ValueWithQName<T>(qname, value);
- }
-
- @Override
- public ValueWithQName<T> deserialize(final Node<?> input, final InstanceIdentifier<?> bindingIdentifier) {
- if (input == null) {
- return null;
- }
- QName qname = input.getNodeType();
- @SuppressWarnings("unchecked")
- T value = (T) getDelegate().deserialize((Map<QName, Object>) input, bindingIdentifier);
- return new ValueWithQName<T>(qname, value);
- }
-
- @Override
- public CompositeNode serialize(final ValueWithQName<T> input) {
- return (CompositeNode) super.serialize(input);
- }
- }
-
- private interface LocationAwareBindingCodec<P, I> extends BindingCodec<P, I> {
-
- boolean isApplicable(InstanceIdentifier<?> parentPath, CompositeNode data);
-
- public Class<?> getDataType();
-
- }
-
- @SuppressWarnings("rawtypes")
- private static abstract class LocationAwareDispatchCodec<T extends LocationAwareBindingCodec> implements
- BindingCodec {
-
- private final Map<Class, T> implementations = Collections.synchronizedMap(new WeakHashMap<Class, T>());
- private final Set<InstanceIdentifier<?>> adaptedForPaths = new HashSet<>();
- private LazyGeneratedCodecRegistry registry;
-
- protected LocationAwareDispatchCodec(final LazyGeneratedCodecRegistry registry) {
- this.registry = registry;
- }
-
- protected Map<Class, T> getImplementations() {
- return implementations;
- }
-
- /**
- * Resets codec adaptation based on location and schema context.
- *
- * This is required if new cases / augmentations were introduced or
- * removed and first use of codec is triggered by invocation from DOM to
- * Java, so the implementations may change and this may require loading
- * of new codecs and/or removal of existing ones.
- *
- */
- public synchronized void resetCodec(final LazyGeneratedCodecRegistry currentRegistry) {
- registry = currentRegistry;
- adaptedForPaths.clear();
- resetAdaptationImpl();
- }
-
- protected void resetAdaptationImpl() {
- // Intentionally NOOP, subclasses may specify their custom
- // behaviour.
- }
-
- protected final LazyGeneratedCodecRegistry getRegistry() {
- return registry;
- }
-
- protected void addImplementation(final T implementation) {
- implementations.put(implementation.getDataType(), implementation);
- }
-
- @Override
- public final Object deserialize(final Object input) {
- throw new UnsupportedOperationException("Invocation of deserialize without Tree location is unsupported");
- }
-
- @Override
- public final Object deserialize(final Object parent, final InstanceIdentifier parentPath) {
- adaptForPath(parentPath);
- Preconditions.checkArgument(parent instanceof CompositeNode, "node must be of CompositeNode type.");
- CompositeNode parentData = (CompositeNode) parent;
- ArrayList<T> applicable = new ArrayList<>(implementations.size());
-
- /*
- * Codecs are filtered to only ones, which are applicable in
- * supplied parent context.
- */
- for (T impl : getImplementations().values()) {
- @SuppressWarnings("unchecked")
- boolean codecApplicable = impl.isApplicable(parentPath, parentData);
- if (codecApplicable) {
- applicable.add(impl);
- }
- }
- LOG.trace("{}: Deserializing mixins from {}, Schema Location {}, Applicable Codecs: {}, All Codecs: {}",
- this, parent, parentPath, applicable, getImplementations().values());
-
- /*
- * In case of none is applicable, we return null. Since there is no
- * mixin which is applicable in this location.
- */
- if (applicable.isEmpty()) {
- return null;
- }
- return deserializeImpl(parentData, parentPath, applicable);
- }
-
- protected abstract Object deserializeImpl(final CompositeNode input, final InstanceIdentifier<?> parentPath,
- Iterable<T> applicableCodecs);
-
- @Override
- public Object serialize(final Object input) {
- Preconditions.checkArgument(input instanceof DataContainer);
- Class<? extends DataContainer> inputType = ((DataContainer) input).getImplementedInterface();
- T implementation = implementations.get(inputType);
- if (implementation == null) {
- implementation = tryToLoadImplementationImpl(inputType);
- }
- return implementation;
- }
-
- private T tryToLoadImplementationImpl(final Class<? extends DataContainer> inputType) {
- T implementation = tryToLoadImplementation(inputType);
- Preconditions.checkArgument(implementation != null, "Data type %s is not supported.", inputType);
- addImplementation(implementation);
- return implementation;
- }
-
- protected final synchronized void adaptForPath(final InstanceIdentifier<?> path) {
- if (adaptedForPaths.contains(path)) {
- return;
- }
- LOG.debug("Adapting mixin codec {} for path {}", this, path);
- /**
- * We search in schema context if the use of this location aware
- * codec (augmentable codec, case codec) makes sense on provided
- * location (path)
- *
- */
- Optional<DataNodeContainer> contextNode = BindingSchemaContextUtils.findDataNodeContainer(
- getRegistry().currentSchema, path);
- /**
- * If context node is present, this codec makes sense on provided
- * location.
- *
- */
- if (contextNode.isPresent()) {
- synchronized (this) {
- /**
- *
- * We adapt (turn on / off) possible implementations of
- * child codecs (augmentations, cases) based on this
- * location.
- *
- *
- */
-
- adaptForPathImpl(path, contextNode.get());
- try {
- /**
- * We trigger serialization of instance identifier, to
- * make sure instance identifier codec is aware of
- * combination of this path / augmentation / case
- */
- getRegistry().getInstanceIdentifierCodec().serialize(path);
- } catch (Exception e) {
- LOG.warn("Exception during preparation of instance identifier codec for path {}.", path, e);
- }
- adaptedForPaths.add(path);
- }
- } else {
- LOG.debug("Context node (parent node) not found for {}", path);
- }
- }
-
- protected abstract T tryToLoadImplementation(Class<? extends DataContainer> inputType);
-
- protected abstract void tryToLoadImplementations();
-
- protected abstract void adaptForPathImpl(InstanceIdentifier<?> path, DataNodeContainer ctx);
- }
-
- @SuppressWarnings("rawtypes")
- private static class ChoiceCaseCodecImpl<T extends DataContainer> implements ChoiceCaseCodec<T>, //
- Delegator<BindingCodec>, LocationAwareBindingCodec<Node<?>, ValueWithQName<T>> {
- private final BindingCodec delegate;
- private final ChoiceCaseNode schema;
- private final Map<InstanceIdentifier<?>, ChoiceCaseNode> instantiatedLocations;
- private final Class<?> dataType;
-
- public ChoiceCaseCodecImpl(final Class<?> caseClass, final ChoiceCaseNode caseNode,
- final BindingCodec newInstance) {
- this.delegate = newInstance;
- this.dataType = caseClass;
- this.schema = caseNode;
- instantiatedLocations = new HashMap<>();
- }
-
- @Override
- public ValueWithQName<T> deserialize(final Node<?> input) {
- throw new UnsupportedOperationException("Direct invocation of this codec is not allowed.");
- }
-
- @Override
- public ValueWithQName<T> deserialize(final Node<?> input, final InstanceIdentifier<?> bindingIdentifier) {
- if (input == null) {
- return null;
- }
- QName qname = input.getNodeType();
- synchronized (instantiatedLocations) {
- ChoiceCaseNode instantiation = instantiatedLocations.get(bindingIdentifier);
- if (instantiation != null) {
- qname = instantiatedLocations.get(bindingIdentifier).getQName();
- }
- }
- @SuppressWarnings("unchecked")
- T value = (T) getDelegate().deserialize(new SimpleEntry(qname, input), bindingIdentifier);
- return new ValueWithQName<T>(qname, value);
- }
-
- @Override
- public CompositeNode serialize(final ValueWithQName<T> input) {
- throw new UnsupportedOperationException("Direct invocation of this codec is not allowed.");
- }
-
- @Override
- public BindingCodec getDelegate() {
- return delegate;
- }
-
- public ChoiceCaseNode getSchema() {
- return schema;
- }
-
- @Override
- @Deprecated
- public boolean isAcceptable(final Node<?> input) {
- return checkAgainstSchema(schema, input);
- }
-
- private static boolean checkAgainstSchema(final ChoiceCaseNode schema, final Node<?> node) {
- if (node instanceof CompositeNode) {
- CompositeNode input = (CompositeNode) node;
- for (Node<?> childNode : input.getValue()) {
- QName child = childNode.getNodeType();
- if (schema.getDataChildByName(child) != null) {
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public Class<?> getDataType() {
- return dataType;
- }
-
- public void adaptForPath(final InstanceIdentifier<?> augTarget, final ChoiceCaseNode choiceCaseNode) {
- synchronized (instantiatedLocations) {
- instantiatedLocations.put(augTarget, choiceCaseNode);
- }
- }
-
- @Override
- public boolean isApplicable(final InstanceIdentifier path, final CompositeNode input) {
- ChoiceCaseNode instantiatedSchema = null;
- synchronized (instantiatedLocations) {
- instantiatedSchema = instantiatedLocations.get(path);
- }
- if (instantiatedSchema == null) {
- return false;
- }
- return checkAgainstSchema(instantiatedSchema, input);
- }
-
- protected boolean isAugmenting(final QName choiceName, final QName proposedQName) {
- if (schema.isAugmenting()) {
- return true;
- }
- // Choice QName
- QName parentQName = Iterables.get(schema.getPath().getPathTowardsRoot(), 1);
- if (!parentQName.getNamespace().equals(schema.getQName().getNamespace())) {
- return true;
- }
- if (!parentQName.equals(choiceName)) {
- // This item is instantiation of choice via uses in other YANG
- // module
- if (choiceName.getNamespace().equals(schema.getQName().getNamespace())) {
- // Original definition of grouping is in same namespace
- // as original definition of case
- // so for sure case is introduced via instantiation of
- // grouping
- return false;
- }
- // Since we are still here, that means case has same namespace
- // as its parent, which is instantiation of grouping
- // but case namespace is different from parent node
- // so it is augmentation.
- return true;
- }
- return false;
- }
-
- @Override
- public String toString() {
- return "ChoiceCaseCodec [case=" + dataType + ", knownLocations=" + instantiatedLocations.keySet() + "]";
- }
- }
-
- private static class PublicChoiceCodecImpl<T> implements ChoiceCodec<T>,
- Delegator<BindingCodec<Map<QName, Object>, Object>> {
-
- private final BindingCodec<Map<QName, Object>, Object> delegate;
-
- public PublicChoiceCodecImpl(final BindingCodec<Map<QName, Object>, Object> delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public ValueWithQName<T> deserialize(final Node<?> input) {
- throw new UnsupportedOperationException("Direct invocation of this codec is not allowed.");
- }
-
- @Override
- public ValueWithQName<T> deserialize(final Node<?> input, final InstanceIdentifier<?> bindingIdentifier) {
- throw new UnsupportedOperationException("Direct invocation of this codec is not allowed.");
- }
-
- @Override
- public Node<?> serialize(final ValueWithQName<T> input) {
- throw new UnsupportedOperationException("Direct invocation of this codec is not allowed.");
- }
-
- @Override
- public BindingCodec<Map<QName, Object>, Object> getDelegate() {
- return delegate;
- }
-
- }
-
- class DispatchChoiceCodecImpl extends LocationAwareDispatchCodec<ChoiceCaseCodecImpl<?>> {
- private final Class<?> choiceType;
- private final QName choiceName;
-
- private DispatchChoiceCodecImpl(final Class<?> type, final LazyGeneratedCodecRegistry registry) {
- super(registry);
- choiceType = type;
- choiceName = BindingReflections.findQName(type);
- }
-
- @Override
- public Object deserializeImpl(final CompositeNode input, final InstanceIdentifier<?> path,
- final Iterable<ChoiceCaseCodecImpl<?>> codecs) {
- ChoiceCaseCodecImpl<?> caseCodec = Iterables.getOnlyElement(codecs);
- ValueWithQName<?> value = caseCodec.deserialize(input, path);
- if (value != null) {
- return value.getValue();
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public Object serialize(final Object input) {
- Preconditions.checkArgument(input instanceof Map.Entry<?, ?>, "Input must be QName, Value");
- @SuppressWarnings("rawtypes")
- QName derivedQName = (QName) ((Map.Entry) input).getKey();
- @SuppressWarnings("rawtypes")
- Object inputValue = ((Map.Entry) input).getValue();
- Preconditions.checkArgument(inputValue instanceof DataObject);
- Class<? extends DataContainer> inputType = ((DataObject) inputValue).getImplementedInterface();
- ChoiceCaseCodecImpl<?> codec = tryToLoadImplementation(inputType);
- Preconditions.checkState(codec != null, "Unable to get codec for %s", inputType);
- if (codec.isAugmenting(choiceName, derivedQName)) {
- // If choice is augmenting we use QName which defined this
- // augmentation
- return codec.getDelegate().serialize(new ValueWithQName<>(codec.getSchema().getQName(), inputValue));
- }
- return codec.getDelegate().serialize(input);
- }
-
- @SuppressWarnings("rawtypes")
- protected Optional<ChoiceCaseCodecImpl> tryToLoadImplementation(final Type potential) {
- try {
- @SuppressWarnings("unchecked")
- Class<? extends DataContainer> clazz = (Class<? extends DataContainer>) classLoadingStrategy
- .loadClass(potential);
- ChoiceCaseCodecImpl codec = tryToLoadImplementation(clazz);
- addImplementation(codec);
- return Optional.of(codec);
- } catch (ClassNotFoundException e) {
- LOG.warn("Failed to find class for choice {}", potential, e);
- }
- return Optional.absent();
- }
-
- @Override
- protected ChoiceCaseCodecImpl<?> tryToLoadImplementation(final Class<? extends DataContainer> inputType) {
- ChoiceCaseCodecImpl<?> codec = getCaseCodecFor(inputType);
- addImplementation(codec);
- return codec;
- }
-
- @Override
- protected void tryToLoadImplementations() {
- Type type = referencedType(choiceType);
- Collection<Type> potentialCases;
- synchronized (choiceToCases) {
- potentialCases = choiceToCases.get(type);
- }
- for (Type potential : potentialCases) {
- try {
- tryToLoadImplementation(potential);
- } catch (CodeGenerationException e) {
- LOG.warn("Failed to proactively generate choice code for {}", type, e);
- }
- }
- }
-
- @Override
- protected void adaptForPathImpl(final InstanceIdentifier<?> augTarget, final DataNodeContainer ctxNode) {
- tryToLoadImplementations();
- Optional<ChoiceSchemaNode> newChoice = BindingSchemaContextUtils.findInstantiatedChoice(ctxNode, choiceType);
- if(!newChoice.isPresent()) {
- // Choice is nested inside other choice, so we need to look two levels deep.
- in_choices: for(DataSchemaNode child : ctxNode.getChildNodes()) {
- if (child instanceof ChoiceSchemaNode) {
- Optional<ChoiceSchemaNode> potential = findChoiceInChoiceCases((ChoiceSchemaNode) child, choiceType);
- if(potential.isPresent()) {
- newChoice = potential;
- break in_choices;
- }
- }
- }
- }
-
- Preconditions.checkState(newChoice.isPresent(), "BUG: Unable to find instantiated choice node in schema.");
- for (@SuppressWarnings("rawtypes")
- Entry<Class, ChoiceCaseCodecImpl<?>> codec : getImplementations().entrySet()) {
- ChoiceCaseCodecImpl<?> caseCodec = codec.getValue();
- Optional<ChoiceCaseNode> instantiatedSchema = BindingSchemaContextUtils.findInstantiatedCase(
- newChoice.get(), caseCodec.getSchema());
- if (instantiatedSchema.isPresent()) {
- caseCodec.adaptForPath(augTarget, instantiatedSchema.get());
- }
- }
- }
-
- private Optional<ChoiceSchemaNode> findChoiceInChoiceCases(final ChoiceSchemaNode choice, final Class<?> choiceType) {
- for(ChoiceCaseNode caze : choice.getCases()) {
- Optional<ChoiceSchemaNode> potential = BindingSchemaContextUtils.findInstantiatedChoice(caze, choiceType);
- if(potential.isPresent()) {
- return potential;
- }
- }
- return Optional.absent();
- }
-
- @Override
- public String toString() {
- return "DispatchChoiceCodecImpl [choiceType=" + choiceType + "]";
- }
- }
-
- /**
- *
- * Dispatch codec for augmented object, which processes augmentations
- * <p>
- * This codec is used from DataObject codec generated using
- * {@link TransformerGenerator#transformerFor(Class)} and is wired during
- * {@link LazyGeneratedCodecRegistry#onDataContainerCodecCreated(Class, Class)}.
- * <p>
- * Instance of this codec is associated with class of Binding DTO which
- * represents target for augmentations.
- *
- */
- @SuppressWarnings({ "rawtypes", "unchecked" })
- static class AugmentableDispatchCodec extends LocationAwareDispatchCodec<AugmentationCodecWrapper> {
-
- private final Class augmentableType;
-
- /**
- * Construct augmetable dispatch codec.
- *
- * @param type
- * Class representing augmentation target
- * @param registry
- * Registry with which this codec is associated.
- */
- public AugmentableDispatchCodec(final Class type, final LazyGeneratedCodecRegistry registry) {
- super(registry);
- Preconditions.checkArgument(Augmentable.class.isAssignableFrom(type));
- augmentableType = type;
- }
-
- /**
- * Serializes object to list of values which needs to be injected into
- * resulting DOM Node. Injection of data to parent DOM Node is handled
- * by caller (in this case generated codec).
- *
- * TODO: Deprecate use of augmentation codec without instance instance
- * identifier
- *
- * @return list of nodes, which needs to be added to parent node.
- *
- */
- @Override
- public Object serialize(final Object input) {
- Preconditions.checkArgument(augmentableType.isInstance(input), "Object %s is not instance of %s ", input,
- augmentableType);
- if (input instanceof Augmentable<?>) {
- Map<Class<? extends Augmentation<?>>, Augmentation<?>> augmentations = BindingReflections
- .getAugmentations((Augmentable<?>) input);
- return serializeImpl(augmentations);
- }
- return null;
- }
-
- /**
- *
- * Serialization of augmentations, returns list of composite nodes,
- * which needs to be injected to parent node.
- *
- * @param input
- * Map of classes to augmentations
- * @return List of nodes, which should be added to parent node.
- */
- private List serializeImpl(final Map<Class<? extends Augmentation<?>>, Augmentation<?>> input) {
- List ret = new ArrayList<>();
- for (Entry<Class<? extends Augmentation<?>>, Augmentation<?>> entry : input.entrySet()) {
- AugmentationCodec codec = getRegistry().getCodecForAugmentation(entry.getKey());
- CompositeNode node = codec.serialize(new ValueWithQName(null, entry.getValue()));
- ret.addAll(node.getValue());
- }
- return ret;
- }
-
- /**
- *
- * Deserialization of augmentation which is location aware.
- *
- * Note: In case of composite nodes as an input, each codec is invoked
- * since there is no augmentation identifier and we need to look for
- * concrete classes. FIXME: Maybe faster variation will be by extending
- * {@link AugmentationCodecWrapper} to look for particular QNames, which
- * will filter incoming set of codecs.
- *
- *
- * @param input
- * Input representation of data
- * @param path
- * Wildcarded instance identifier representing location of
- * augmentation parent in conceptual schema tree
- * @param codecs
- * Set of codecs which are applicable for supplied
- * <code>path</code>, selected by caller to be used by
- * deserialization
- *
- *
- */
- @Override
- public Map<Class, Augmentation> deserializeImpl(final CompositeNode input, final InstanceIdentifier<?> path,
- final Iterable<AugmentationCodecWrapper> codecs) {
- LOG.trace("{}: Going to deserialize augmentations from {} in location {}. Available codecs {}", this,
- input, path, codecs);
- Map<Class, Augmentation> ret = new HashMap<>();
- for (AugmentationCodecWrapper codec : codecs) {
- // We add Augmentation Identifier to path, in order to
- // correctly identify children.
- Class type = codec.getDataType();
- final InstanceIdentifier augmentPath = path.augmentation(type);
- ValueWithQName<?> value = codec.deserialize(input, augmentPath);
- if (value != null && value.getValue() != null) {
- ret.put(type, (Augmentation) value.getValue());
- }
- }
- return ret;
- }
-
- /**
- *
- * Tries to load implementation of concrete augmentation codec for
- * supplied type
- *
- * Loading of codec may fail, because of supplied type may not be
- * visible by classloaders known by registry. If class was not found
- * returns {@link Optional#absent()}.
- *
- * @param potential
- * Augmentation class identifier for which codecs should be
- * loaded.
- * @return Optional with codec for supplied type
- *
- */
- protected Optional<AugmentationCodecWrapper> tryToLoadImplementation(final Type potential) {
- try {
- Class<? extends Augmentation<?>> clazz = (Class<? extends Augmentation<?>>) getRegistry().classLoadingStrategy
- .loadClass(potential);
- return Optional.of(tryToLoadImplementation(clazz));
- } catch (ClassNotFoundException e) {
- LOG.warn("Failed to find class for augmentation of {}", potential, e);
- }
- return Optional.absent();
- }
-
- @Override
- protected AugmentationCodecWrapper tryToLoadImplementation(final Class inputType) {
- AugmentationCodecWrapper<? extends Augmentation<?>> potentialImpl = getRegistry().getCodecForAugmentation(
- inputType);
- addImplementation(potentialImpl);
- return potentialImpl;
- }
-
- @Override
- protected void tryToLoadImplementations() {
- Type type = referencedType(augmentableType);
- Collection<Type> potentialAugmentations;
- synchronized (augmentableToAugmentations) {
- potentialAugmentations = new ArrayList(augmentableToAugmentations.get(type));
- }
- for (Type potential : potentialAugmentations) {
- try {
- tryToLoadImplementation(potential);
- } catch (CodeGenerationException e) {
- LOG.warn("Failed to proactively generate augment code for {}", type, e);
- }
- }
- }
-
- @Override
- protected void adaptForPathImpl(final InstanceIdentifier<?> augTarget, final DataNodeContainer ctxNode) {
- if (ctxNode instanceof AugmentationTarget) {
- Set<AugmentationSchema> availableAugmentations = ((AugmentationTarget) ctxNode)
- .getAvailableAugmentations();
- if (!availableAugmentations.isEmpty()) {
- updateAugmentationMapping(augTarget, availableAugmentations);
- }
- }
- }
-
- /**
- *
- * Adapts augmentation codec for specific provider location (target)
- *
- * Since augmentation are not forward-referencing and may be discovered
- * during runtime, we need to adapt {@link AugmentableDispatchCodec},
- * {@link AugmentationCodecWrapper} and {@link InstanceIdentifierCodec}
- * for this newly discovered location where augmentation may be used.
- *
- * Adaptation consists of:
- * <ol>
- * <li>scan of available (valid) augmentations for current location
- * <li>lookup for Java classes derived from this augmentations
- * <li>generation of missing codecs
- * <li>updating Augmentation codecs to work with new location
- * <li>updating Instance Identifier to work with new location
- *
- */
- private void updateAugmentationMapping(final InstanceIdentifier<?> augTarget,
- final Set<AugmentationSchema> availableAugmentations) {
- for (AugmentationSchema aug : availableAugmentations) {
-
- Type potentialType = getTypeForAugmentation(aug);
- if (potentialType != null) {
- Optional<AugmentationCodecWrapper> potentialImpl = tryToLoadImplementation(potentialType);
- if (potentialImpl.isPresent()) {
- potentialImpl.get().addApplicableFor(augTarget, aug);
- Class augType = potentialImpl.get().getDataType();
- InstanceIdentifier augPath = augTarget.augmentation(augType);
- try {
-
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier domPath = getRegistry()
- .getInstanceIdentifierCodec().serialize(augPath);
- if (domPath == null) {
- LOG.error("Unable to serialize instance identifier for {}", augPath);
- }
- } catch (Exception e) {
- LOG.error("Unable to serialize instance identifiers for {}", augPath, e);
- }
-
- }
- } else {
- // Omits warning for empty augmentations since they are not
- // represented in data
- if (!aug.getChildNodes().isEmpty()) {
- LOG.warn("Could not find generated type for augmentation {} with children {}", aug,
- aug.getChildNodes());
- }
- }
- }
- }
-
- private Type getTypeForAugmentation(final AugmentationSchema aug) {
- Optional<AugmentationSchema> currentAug = Optional.of(aug);
- while (currentAug.isPresent()) {
- Type potentialType = typeToAugment.inverse().get(currentAug.get());
- if (potentialType != null) {
- return potentialType;
- }
- currentAug = currentAug.get().getOriginalDefinition();
- }
- return null;
- }
-
- @Override
- public String toString() {
- return "AugmentableDispatchCodec [augmentable=" + augmentableType + "]";
- }
-
- }
-
- @SuppressWarnings("rawtypes")
- private static class AugmentationCodecWrapper<T extends Augmentation<?>> implements AugmentationCodec<T>,
- Delegator<BindingCodec>, LocationAwareBindingCodec<Node<?>, ValueWithQName<T>> {
-
- private final BindingCodec delegate;
- private final QName augmentationQName;
- private final Multimap<InstanceIdentifier<?>, QName> validAugmentationTargets;
- private final Class<?> augmentationType;
-
- public AugmentationCodecWrapper(final BindingCodec<Map<QName, Object>, Object> rawCodec, final Class<?> dataType) {
- this.delegate = rawCodec;
- this.augmentationType = dataType;
- this.augmentationQName = BindingReflections.findQName(rawCodec.getClass());
- this.validAugmentationTargets = Multimaps.synchronizedSetMultimap(HashMultimap
- .<InstanceIdentifier<?>, QName> create());
- }
-
- public void addApplicableFor(final InstanceIdentifier<?> path, final AugmentationSchema aug) {
- for (DataSchemaNode child : aug.getChildNodes()) {
- validAugmentationTargets.put(path, child.getQName());
- }
- }
-
- @Override
- public BindingCodec getDelegate() {
- return delegate;
- }
-
- @Override
- public CompositeNode serialize(final ValueWithQName<T> input) {
- @SuppressWarnings("unchecked")
- List<Map<QName, Object>> rawValues = (List<Map<QName, Object>>) getDelegate().serialize(input);
- List<Node<?>> serialized = new ArrayList<>(rawValues.size());
- for (Map<QName, Object> val : rawValues) {
- serialized.add(IntermediateMapping.toNode(val));
- }
- return new CompositeNodeTOImpl(input.getQname(), null, serialized);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public ValueWithQName<T> deserialize(final Node<?> input) {
- Object rawCodecValue = getDelegate().deserialize(input);
- return new ValueWithQName<T>(input.getNodeType(), (T) rawCodecValue);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public ValueWithQName<T> deserialize(final Node<?> input, final InstanceIdentifier<?> bindingIdentifier) {
- Object rawCodecValue = getDelegate().deserialize(input, bindingIdentifier);
- return new ValueWithQName<T>(input.getNodeType(), (T) rawCodecValue);
- }
-
- @Override
- public QName getAugmentationQName() {
- return augmentationQName;
- }
-
- @Override
- public boolean isAcceptable(final InstanceIdentifier<?> path) {
- if (path == null) {
- return false;
- }
- return validAugmentationTargets.containsKey(path);
- }
-
- @Override
- public boolean isApplicable(final InstanceIdentifier parentPath, final CompositeNode parentData) {
- return isAcceptable(parentPath);
- }
-
- @Override
- public Class<?> getDataType() {
- return augmentationType;
- }
-
- @Override
- public String toString() {
- return "AugmentationCodecWrapper [augmentation=" + augmentationType + ", knownLocations="
- + validAugmentationTargets.keySet() + "]";
- }
- }
-
- @SuppressWarnings("rawtypes")
- private class IdentityCompositeCodec implements IdentityCodec {
-
- @Override
- public Object deserialize(final Object input) {
- Preconditions.checkArgument(input instanceof QName);
- return deserialize((QName) input);
- }
-
- @Override
- public Class<?> deserialize(final QName input) {
- if (input == null) {
- return null;
- }
- Type type = qnamesToIdentityMap.get(input);
- if (type == null) {
- String packageName = BindingMapping.getRootPackageName(input);
- String className = BindingMapping.getClassName(input);
- type = new ReferencedTypeImpl(packageName, className);
- }
- try {
- final Class<?> cls = classLoadingStrategy.loadClass(type);
- if (cls != null) {
- serialize(cls);
- return cls;
- }
- } catch (Exception e) {
- LOG.warn("Identity {} was not deserialized, because of missing class {}", input,
- type.getFullyQualifiedName(), e);
- }
- return null;
-
- }
-
- @Override
- public Object deserialize(final Object input, final InstanceIdentifier bindingIdentifier) {
- return deserialize(input);
- }
-
- @Override
- public QName serialize(final Class input) {
- Preconditions.checkArgument(BaseIdentity.class.isAssignableFrom(input));
- bindingClassEncountered(input);
- QName qname = identityQNames.get(input);
- if (qname != null) {
- return qname;
- }
- qname = BindingReflections.findQName(input);
- if (qname != null) {
- identityQNames.put(input, qname);
- }
- return qname;
- }
-
- @Override
- public Object serialize(final Object input) {
- Preconditions.checkArgument(input instanceof Class);
- return serialize((Class) input);
- }
-
- }
-
- private static final Type referencedType(final Class<?> augmentableType) {
- return new ReferencedTypeImpl(augmentableType.getPackage().getName(), augmentableType.getSimpleName());
- }
-
-}
+++ /dev/null
-/**
- * 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.sal.binding.generator.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import javassist.ClassPool;
-import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
-import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
-import org.opendaylight.yangtools.binding.generator.util.Types;
-import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
-import org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils;
-import org.opendaylight.yangtools.sal.binding.model.api.Type;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.BindingMapping;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-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.PathArgument;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.codec.AugmentationCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.opendaylight.yangtools.yang.data.impl.codec.DataContainerCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
-import org.opendaylight.yangtools.yang.data.impl.codec.InstanceIdentifierCodec;
-import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.concurrent.GuardedBy;
-import java.net.URI;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-
-public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaContextListener,
-SchemaLock, AutoCloseable, SchemaContextHolder, TypeResolver {
-
- private static final Logger LOG = LoggerFactory.getLogger(RuntimeGeneratedMappingServiceImpl.class);
-
- private final ConcurrentMap<Type, Set<QName>> serviceTypeToRpc = new ConcurrentHashMap<>();
-
- /**
- * This is map of types which users are waiting for.
- */
- @GuardedBy("this")
- private final Multimap<Type, SettableFuture<Type>> promisedTypes = HashMultimap.create();
-
- private final ClassLoadingStrategy classLoadingStrategy;
-
- private final AbstractTransformerGenerator binding;
- private final LazyGeneratedCodecRegistry registry;
- private final ClassPool pool;
-
- /*
- * FIXME: updated here, access from AbstractTransformer
- */
- private final Map<Type, AugmentationSchema> typeToAugmentation = new ConcurrentHashMap<>();
- private final ConcurrentMap<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap<>();
- private final ConcurrentMap<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap<>();
- private final Map<SchemaPath, GeneratedTypeBuilder> pathToType = new ConcurrentHashMap<>();
-
- // FIXME: need to figure these out
- private final ConcurrentMap<Type, Type> typeDefinitions = new ConcurrentHashMap<>();
- private SchemaContext schemaContext;
-
- public RuntimeGeneratedMappingServiceImpl(final ClassPool pool) {
- this(pool, GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
- }
-
- public RuntimeGeneratedMappingServiceImpl(final ClassPool pool, final ClassLoadingStrategy strat) {
- this.pool = Preconditions.checkNotNull(pool);
- this.classLoadingStrategy = Preconditions.checkNotNull(strat);
- // FIXME: this escapes constructor
- binding = new TransformerGenerator(this, pool);
- registry = new LazyGeneratedCodecRegistry(this, binding, classLoadingStrategy);
- binding.setListener(registry);
-
- // if (ctx !== null) {
- // listenerRegistration = ctx.registerService(SchemaContextListener,
- // this, new Hashtable<String, String>());
- // }
- }
-
- @Override
- public synchronized SchemaContext getSchemaContext() {
- return schemaContext;
- }
-
- @Override
- public synchronized void onGlobalContextUpdated(final SchemaContext context) {
- this.schemaContext = Preconditions.checkNotNull(context);
- this.recreateBindingContext(context);
- this.registry.onGlobalContextUpdated(context);
- }
-
- @GuardedBy("this")
- private void recreateBindingContext(final SchemaContext schemaContext) {
- BindingGeneratorImpl newBinding = new BindingGeneratorImpl(false);
- newBinding.generateTypes(schemaContext);
-
- for (Map.Entry<Module, ModuleContext> entry : newBinding.getModuleContexts().entrySet()) {
-
- registry.onModuleContextAdded(schemaContext, entry.getKey(), entry.getValue());
- pathToType.putAll(entry.getValue().getChildNodes());
- Module module = entry.getKey();
- ModuleContext context = entry.getValue();
- updateBindingFor(context.getChildNodes(), schemaContext);
- updateBindingFor(context.getCases(), schemaContext);
- String namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
-
- if (!module.getRpcs().isEmpty()) {
- Set<QName> rpcs = new HashSet<>();
- for (RpcDefinition rpc : module.getRpcs()) {
- rpcs.add(rpc.getQName());
- }
- Type serviceClass = new ReferencedTypeImpl(namespace, BindingMapping.getClassName(module.getName())
- + "Service");
- serviceTypeToRpc.put(serviceClass, rpcs);
- updatePromisedSchemas(serviceClass);
- }
-
- Map<SchemaPath, Type> typedefs = context.getTypedefs();
- for (Map.Entry<SchemaPath, Type> typedef : typedefs.entrySet()) {
- Type value = typedef.getValue();
- Type typeRef = new ReferencedTypeImpl(value.getPackageName(), value.getName());
- typeDefinitions.put(typeRef, value);
- TypeDefinition<?> schemaNode = YangSchemaUtils.findTypeDefinition(schemaContext, typedef.getKey());
- if (schemaNode != null) {
-
- typeToSchemaNode.put(typeRef, schemaNode);
- } else {
- LOG.error("Type definition for {} is not available", value);
- }
- }
- List<GeneratedTypeBuilder> augmentations = context.getAugmentations();
- for (GeneratedTypeBuilder augmentation : augmentations) {
- typeToDefinition.put(augmentation, augmentation);
- }
- typeToAugmentation.putAll(context.getTypeToAugmentation());
- for (GeneratedTypeBuilder augmentation : augmentations) {
- updatePromisedSchemas(augmentation);
- }
- }
- }
-
- @Override
- public CompositeNode toDataDom(final DataObject data) {
- return toCompositeNodeImpl(data);
- }
-
- @Override
- public Entry<YangInstanceIdentifier, CompositeNode> toDataDom(
- final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
- try {
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier key = toDataDom(entry.getKey());
- CompositeNode data;
- if (Augmentation.class.isAssignableFrom(entry.getKey().getTargetType())) {
- data = toCompositeNodeImplAugument(key, entry.getValue());
- } else {
- data = toCompositeNodeImpl(key, entry.getValue());
- }
- return new SimpleEntry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode>(key,
- data);
-
- } catch (Exception e) {
- LOG.error("Error during serialization for {}.", entry.getKey(), e);
- throw e;
- }
- }
-
- private CompositeNode toCompositeNodeImpl(final DataObject object) {
- Class<? extends DataContainer> cls = object.getImplementedInterface();
- waitForSchema(cls);
- DataContainerCodec<DataObject> codec = (DataContainerCodec<DataObject>) registry.getCodecForDataObject(cls);
- return codec.serialize(new ValueWithQName<DataObject>(null, object));
- }
-
- private CompositeNode toCompositeNodeImpl(final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier identifier,
- final DataObject object) {
- PathArgument last = identifier.getLastPathArgument();
- Class<? extends DataContainer> cls = object.getImplementedInterface();
- waitForSchema(cls);
- DataContainerCodec<DataObject> codec = (DataContainerCodec<DataObject>) registry.getCodecForDataObject(cls);
- return codec.serialize(new ValueWithQName<DataObject>(last.getNodeType(), object));
- }
-
- private CompositeNode toCompositeNodeImplAugument(
- final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier identifier, final DataObject object) {
-
- // val cls = object.implementedInterface;
- // waitForSchema(cls);
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument last = identifier.getLastPathArgument();
- AugmentationCodec codec = registry.getCodecForAugmentation((Class) object.getImplementedInterface());
- CompositeNode ret = codec.serialize(new ValueWithQName<DataObject>(last.getNodeType(), object));
- if (last instanceof NodeIdentifierWithPredicates) {
- NodeIdentifierWithPredicates predicates = (NodeIdentifierWithPredicates) last;
- List<Node<?>> newNodes = new ArrayList<Node<?>>(predicates.getKeyValues().size());
- for (Map.Entry<QName, Object> predicate : predicates.getKeyValues().entrySet()) {
- newNodes.add(new SimpleNodeTOImpl<Object>(predicate.getKey(), null, predicate.getValue()));
- }
- newNodes.addAll(ret.getValue());
- return new CompositeNodeTOImpl(last.getNodeType(), null, newNodes);
- }
- return ret;
- }
-
- @Override
- public void waitForSchema(final Class<?> cls) {
- final ListenableFuture<Type> f = getSchemaDefinition(cls);
- if (f != null) {
- try {
- f.get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.warn("Waiting for schema for class {} failed", cls, e);
- throw new IllegalStateException(String.format("Failed to get schema for %s", cls), e);
- }
- LOG.info("Schema for {} became available, thread unblocked", cls);
- }
- }
-
- @Override
- public YangInstanceIdentifier toDataDom(
- final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
- for (final org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : path.getPathArguments()) {
- this.waitForSchema(arg.getType());
- }
-
- final InstanceIdentifierCodec c = registry.getInstanceIdentifierCodec();
- Preconditions.checkState(c != null, "InstanceIdentifierCodec not present");
- return c.serialize(path);
- }
-
- @Override
- public DataObject dataObjectFromDataDom(
- final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path,
- final CompositeNode domData) throws DeserializationException {
- if (domData == null) {
- return null;
- }
-
- try {
- final Class<? extends DataContainer> container = path.getTargetType();
- // FIXME: deprecate use without iid
- final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> wildcardedPath = createWildcarded(path);
-
- final DataContainerCodec<? extends DataContainer> transformer = registry.getCodecForDataObject(container);
- Preconditions.checkState(transformer != null, "Failed to find codec for type %s", container);
-
- final ValueWithQName<? extends DataContainer> deserialize = transformer.deserialize(domData, wildcardedPath);
- if (deserialize == null) {
- return null;
- }
-
- return (DataObject) deserialize.getValue();
- } catch (Exception e) {
- LOG.warn("Failed to deserialize path {} data {}", path, domData);
- throw new DeserializationException("Data deserialization failed", e);
- }
- }
-
- @Override
- public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object> fromDataDom(final YangInstanceIdentifier entry) throws DeserializationException {
- try {
- final InstanceIdentifierCodec c = registry.getInstanceIdentifierCodec();
- Preconditions.checkState(c != null, "InstanceIdentifierCodec not present");
- return c.deserialize(entry);
- } catch (Exception e) {
- LOG.warn("Failed to deserialize entry {}", entry);
- throw new DeserializationException("Entry deserialization failed", e);
- }
- }
-
- @Override
- public CodecRegistry getCodecRegistry() {
- return this.registry;
- }
-
- private void updateBindingFor(final Map<SchemaPath, GeneratedTypeBuilder> map, final SchemaContext module) {
- for (Map.Entry<SchemaPath, GeneratedTypeBuilder> entry : map.entrySet()) {
- SchemaNode schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.getKey());
-
- // LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName)
- Type typeRef = new ReferencedTypeImpl(entry.getValue().getPackageName(), entry.getValue().getName());
- typeToDefinition.put(typeRef, entry.getValue());
- if (schemaNode != null) {
- typeToSchemaNode.put(typeRef, schemaNode);
- updatePromisedSchemas(entry.getValue());
- }
- }
- }
-
-
- @Override
- public Set<QName> getRpcQNamesFor(final Class<? extends RpcService> service) {
- Set<QName> serviceRef = serviceTypeToRpc.get(new ReferencedTypeImpl(service.getPackage().getName(), service
- .getSimpleName()));
- if (serviceRef == null) {
- waitForSchema(service);
- serviceRef = serviceTypeToRpc.get(new ReferencedTypeImpl(service.getPackage().getName(), service
- .getSimpleName()));
- }
- return serviceRef;
- }
-
- private ListenableFuture<Type> getSchemaDefinition(final Class<?> cls) {
- final Type type = Types.typeForClass(cls);
- synchronized (this) {
- if (typeToDefinition.containsKey(type)) {
- return null;
- }
-
- LOG.info("Thread is going to wait for schema for: {}", type.getFullyQualifiedName());
- final SettableFuture<Type> f = SettableFuture.create();
- promisedTypes.put(type, f);
- return f;
- }
- }
-
- @GuardedBy("this")
- private void updatePromisedSchemas(final Type builder) {
- final Type ref = new ReferencedTypeImpl(builder.getPackageName(), builder.getName());
- final Collection<SettableFuture<Type>> futures = promisedTypes.get(ref);
-
- if (futures != null) {
- for (SettableFuture<Type> future : futures) {
- future.set(builder);
- }
- promisedTypes.removeAll(builder);
- }
- }
-
- @Override
- public void close() {
- // Nothing to do
- }
-
- @Override
- public DataContainer dataObjectFromDataDom(final Class<? extends DataContainer> container,
- final CompositeNode domData) {
- // FIXME: Add check for valids inputs
- // which are Notification and Rpc Input / Rpc Output
-
- org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataContainer> id = org.opendaylight.yangtools.yang.binding.InstanceIdentifier
- .create((Class) container);
- Preconditions.checkNotNull(id, "Failed to create path for type %s", container);
-
- try {
- return dataObjectFromDataDom(id, domData);
- } catch (DeserializationException e) {
- LOG.warn("Conversion of class {} path {} data {} failed", container, id, domData, e);
- throw new IllegalStateException("Failed to create data object", e);
- }
- }
-
- @Override
- public synchronized Optional<Class<? extends RpcService>> getRpcServiceClassFor(final String namespace, final String revision) {
- Module module = null;
- if (schemaContext != null) {
- module = schemaContext.findModuleByNamespaceAndRevision(URI.create(namespace), QName.parseRevision(revision));
- }
- if (module == null) {
- return Optional.absent();
- }
- try {
- Optional<Type> rpcTypeName = getRpcServiceType(module);
- if (rpcTypeName.isPresent()) {
- Class<?> rpcClass = classLoadingStrategy.loadClass(rpcTypeName.get().getFullyQualifiedName());
- return Optional.<Class<? extends RpcService>> of((Class<? extends RpcService>) rpcClass);
- }
- } catch (Exception e) {
- LOG.debug("RPC class not present for {},{}", namespace, revision, e);
- }
- return Optional.absent();
- }
-
- public Optional<Type> getRpcServiceType(final Module module) {
- String namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
- if (module.getRpcs().isEmpty()) {
- return Optional.<Type> absent();
- }
- return Optional.<Type> of(new ReferencedTypeImpl(namespace, BindingMapping.getClassName(module.getName())
- + BindingMapping.RPC_SERVICE_SUFFIX));
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- private static final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> createWildcarded(
- final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
-
- LinkedList<org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument> wildcardedArgs = new LinkedList<>();
- for(org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument pathArg : path.getPathArguments()) {
- if(pathArg instanceof IdentifiableItem<?,?>) {
- pathArg = new Item(pathArg.getType());
- }
- wildcardedArgs.add(pathArg);
- }
- return org.opendaylight.yangtools.yang.binding.InstanceIdentifier.create(wildcardedArgs);
- }
-
- @Override
- public final AugmentationSchema getAugmentation(final Type type) {
- return typeToAugmentation.get(type);
- }
-
- @Override
- public final GeneratedTypeBuilder getDefinition(final Type type) {
- return typeToDefinition.get(type);
- }
-
- @Override
- public final SchemaNode getSchemaNode(final Type type) {
- return typeToSchemaNode.get(type);
- }
-
- @Override
- public final GeneratedTypeBuilder getTypeBuilder(final SchemaPath path) {
- return pathToType.get(path);
- }
-}
+++ /dev/null
-/*
- * 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.sal.binding.generator.impl;
-
-public interface StaticFieldInitializer {
-
- void initializeStaticFields(Class<?> cls);
-}
+++ /dev/null
-/*
- * 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.sal.binding.generator.impl
-
-import static com.google.common.base.Preconditions.*
-import static javassist.Modifier.*
-import static org.opendaylight.yangtools.sal.binding.generator.impl.CodecMapping.*
-
-import static extension org.opendaylight.yangtools.sal.binding.generator.util.YangSchemaUtils.*
-
-import com.google.common.base.Joiner
-import com.google.common.base.Supplier
-import java.io.File
-import java.security.ProtectionDomain
-import java.util.AbstractMap.SimpleEntry
-import java.util.Collection
-import java.util.Collections
-import java.util.HashMap
-import java.util.HashSet
-import java.util.Iterator
-import java.util.List
-import java.util.Map
-import java.util.Map.Entry
-import java.util.Set
-import java.util.TreeSet
-import javassist.CannotCompileException
-import javassist.ClassPool
-import javassist.CtClass
-import javassist.CtField
-import javassist.CtMethod
-import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl
-import org.opendaylight.yangtools.binding.generator.util.Types
-import org.opendaylight.yangtools.sal.binding.generator.util.CodeGenerationException
-import org.opendaylight.yangtools.sal.binding.generator.util.SourceCodeGenerator
-import org.opendaylight.yangtools.sal.binding.generator.util.SourceCodeGeneratorFactory
-import org.opendaylight.yangtools.sal.binding.generator.util.XtendHelper
-import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
-import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
-import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
-import org.opendaylight.yangtools.sal.binding.model.api.Type
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
-import org.opendaylight.yangtools.util.ClassLoaderUtils
-import org.opendaylight.yangtools.yang.binding.Augmentation
-import org.opendaylight.yangtools.yang.binding.BindingCodec
-import org.opendaylight.yangtools.yang.binding.BindingDeserializer
-import org.opendaylight.yangtools.yang.binding.BindingMapping
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode
-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.NotificationDefinition
-import org.opendaylight.yangtools.yang.model.api.SchemaNode
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition
-import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
-import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit
-import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition
-import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition
-import org.opendaylight.yangtools.yang.model.util.EnumerationType
-import org.opendaylight.yangtools.yang.model.util.ExtendedType
-import org.slf4j.LoggerFactory
-
-class TransformerGenerator extends AbstractTransformerGenerator {
- private static val LOG = LoggerFactory.getLogger(TransformerGenerator)
-
- public static val STRING = Types.typeForClass(String);
- public static val BOOLEAN = Types.typeForClass(Boolean);
- public static val INTEGER = Types.typeForClass(Integer);
- public static val INSTANCE_IDENTIFIER = Types.typeForClass(InstanceIdentifier);
- //public static val DECIMAL = Types.typeForClass(Decimal);
- public static val LONG = Types.typeForClass(Long);
- public static val CLASS_TYPE = Types.typeForClass(Class);
-
- @Property
- var File classFileCapturePath;
-
- val CtClass BINDING_CODEC
- val CtClass ctQName
-
- val SourceCodeGeneratorFactory sourceCodeGeneratorFactory = new SourceCodeGeneratorFactory();
-
- public new(TypeResolver typeResolver, ClassPool pool) {
- super(typeResolver, pool)
-
- BINDING_CODEC = BindingCodec.asCtClass;
- ctQName = QName.asCtClass
- }
-
- override transformerForImpl(Class inputType) {
- return runOnClassLoader(inputType.classLoader) [ |
- val ret = getGeneratedClass(inputType)
- if (ret !== null) {
- listener.onClassProcessed(inputType);
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- }
- val ref = Types.typeForClass(inputType)
- val node = getSchemaNode(ref)
- createMapping(inputType, node, null)
- val typeSpecBuilder = getDefinition(ref)
- checkState(typeSpecBuilder !== null, "Could not find typedefinition for %s", inputType.name);
- val typeSpec = typeSpecBuilder.toInstance();
- val newret = generateTransformerFor(inputType, typeSpec, node);
- listener.onClassProcessed(inputType);
- return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- ]
- }
-
- def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType, DataSchemaNode node) {
- return runOnClassLoader(inputType.classLoader) [ |
- createMapping(inputType, node, null)
- val ret = getGeneratedClass(inputType)
- if (ret !== null) {
- listener.onClassProcessed(inputType);
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- }
- val ref = Types.typeForClass(inputType)
- var typeSpecBuilder = getDefinition(ref)
- if (typeSpecBuilder == null) {
- typeSpecBuilder = getTypeBuilder(node.path);
- }
-
- checkState(typeSpecBuilder !== null, "Could not find TypeDefinition for %s, $s", inputType.name, node);
- val typeSpec = typeSpecBuilder.toInstance();
- val newret = generateTransformerFor(inputType, typeSpec, node);
- listener.onClassProcessed(inputType);
- return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- ]
- }
-
- override augmentationTransformerForImpl(Class inputType) {
- return runOnClassLoader(inputType.classLoader) [ |
-
- val ret = getGeneratedClass(inputType)
- if (ret !== null) {
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- }
- val ref = Types.typeForClass(inputType)
- val node = getAugmentation(ref)
- val typeSpecBuilder = getDefinition(ref)
- val typeSpec = typeSpecBuilder.toInstance();
- //mappingForNodes(node.childNodes, typeSpec.allProperties, bindingId)
- val newret = generateAugmentationTransformerFor(inputType, typeSpec, node);
- listener.onClassProcessed(inputType);
- return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- ]
- }
-
- override caseCodecForImpl(Class inputType, ChoiceCaseNode node) {
- return runOnClassLoader(inputType.classLoader) [ |
- createMapping(inputType, node, null)
- val ret = getGeneratedClass(inputType)
- if (ret !== null) {
- return ret as Class<? extends BindingCodec<Object, Object>>;
- }
- val ref = Types.typeForClass(inputType)
- val typeSpecBuilder = getDefinition(ref)
- val typeSpec = typeSpecBuilder.toInstance();
- val newret = generateCaseCodec(inputType, typeSpec, node);
- return newret as Class<? extends BindingCodec<Object, Object>>;
- ]
- }
-
- override keyTransformerForIdentifiableImpl(Class parentType) {
- return runOnClassLoader(parentType.classLoader) [ |
- val inputName = parentType.name + "Key";
- val inputType = loadClass(inputName);
- val ret = getGeneratedClass(inputType)
- if (ret !== null) {
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- }
- val ref = Types.typeForClass(parentType)
- val node = getSchemaNode(ref) as ListSchemaNode
- val typeSpecBuilder = getDefinition(ref)
- val typeSpec = typeSpecBuilder.identifierDefinition;
- val newret = generateKeyTransformerFor(inputType, typeSpec, node);
- return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- ]
- }
-
- private def void createMapping(Class<?> inputType, SchemaNode node, InstanceIdentifier<?> parentId) {
- var ClassLoader cl = inputType.classLoader
- if (cl === null) {
- cl = Thread.currentThread.contextClassLoader
- }
-
- val Supplier<?> sup = [ |
- if (!(node instanceof DataNodeContainer)) {
- return null
- }
- var InstanceIdentifier<?> bindingId = getBindingIdentifierByPath(node.path)
- if (bindingId != null) {
- return null
- }
- val ref = Types.typeForClass(inputType)
- var typeSpecBuilder = getDefinition(ref)
- if (typeSpecBuilder == null) {
- typeSpecBuilder = getTypeBuilder(node.path);
- }
- checkState(typeSpecBuilder !== null, "Could not find type definition for %s, $s", inputType.name, node);
- val typeSpec = typeSpecBuilder.toInstance();
- var InstanceIdentifier<?> parent
- if (parentId == null) {
- bindingId = InstanceIdentifier.create(inputType as Class)
- parent = bindingId
- putPathToBindingIdentifier(node.path, bindingId)
- } else {
- parent = putPathToBindingIdentifier(node.path, parentId, inputType)
- }
- val Map<String, Type> properties = typeSpec.allProperties
- if (node instanceof DataNodeContainer) {
- mappingForNodes((node as DataNodeContainer).childNodes, properties, parent)
- } else if (node instanceof ChoiceSchemaNode) {
- mappingForNodes((node as ChoiceSchemaNode).cases, properties, parent)
- }
- return null ]
- ClassLoaderUtils.withClassLoader(cl, sup)
- }
-
- private def void mappingForNodes(Collection<? extends DataSchemaNode> childNodes, Map<String, Type> properties,
- InstanceIdentifier<?> parent) {
- for (DataSchemaNode child : childNodes) {
- val signature = properties.getFor(child)
- if (signature != null) {
- val Type childType = signature.value
- var Class<?> childTypeClass = null;
- if (child instanceof ListSchemaNode && childType instanceof ParameterizedType) {
- childTypeClass = loadClass((childType as ParameterizedType).actualTypeArguments.get(0))
- } else {
- childTypeClass = loadClass(childType)
- }
- createMapping(childTypeClass, child, parent)
- }
- }
- }
-
- def getIdentifierDefinition(GeneratedTypeBuilder builder) {
- val inst = builder.toInstance
- val keyMethod = inst.methodDefinitions.findFirst[name == "getKey"]
- return keyMethod.returnType as GeneratedTransferObject
- }
-
- override keyTransformerForIdentifierImpl(Class inputType) {
- return runOnClassLoader(inputType.classLoader) [ |
- val ret = getGeneratedClass(inputType)
- if (ret !== null) {
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- }
- val ref = Types.typeForClass(inputType)
- val node = getSchemaNode(ref) as ListSchemaNode
- val typeSpecBuilder = getDefinition(ref)
- val typeSpec = typeSpecBuilder.toInstance();
- val newret = generateKeyTransformerFor(inputType, typeSpec, node);
- return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- ]
- }
-
- private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
- return runOnClassLoader(inputType.classLoader) [ |
- val transformer = getGeneratedClass(inputType)
- if (transformer != null) {
- return transformer;
- }
- val newret = generateKeyTransformerFor(inputType, type, schema);
- return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- ]
- }
-
- private def Class<?> getGeneratedClass(Class<? extends Object> cls) {
-
- try {
- return loadClass(cls.codecClassName)
- } catch (ClassNotFoundException e) {
- return null;
- }
- }
-
- private def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
- val cls = loadClass(type.resolvedName + "Key");
- keyTransformerFor(cls, type, node);
- }
-
- private def serializer(Type type, DataSchemaNode node) {
- val cls = loadClass(type.resolvedName);
- transformerFor(cls, node);
- }
-
- private def Class<?> valueSerializer(GeneratedTransferObject type, TypeDefinition<?> typeDefinition) {
- val cls = loadClass(type.resolvedName);
- val transformer = cls.generatedClass;
- if (transformer !== null) {
- return transformer;
- }
- var baseType = typeDefinition;
- while (baseType.baseType != null) {
- baseType = baseType.baseType;
- }
- val finalType = baseType;
- return runOnClassLoader(cls.classLoader) [ |
- val valueTransformer = generateValueTransformer(cls, type, finalType);
- return valueTransformer;
- ]
- }
-
- private def Class<?> valueSerializer(Enumeration type, TypeDefinition<?> typeDefinition) {
- val cls = loadClass(type.resolvedName);
- val transformer = cls.generatedClass;
- if (transformer !== null) {
- return transformer;
- }
-
- return runOnClassLoader(cls.classLoader) [ |
- val valueTransformer = generateValueTransformer(cls, type, typeDefinition);
- return valueTransformer;
- ]
- }
-
- private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
- try {
-
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
- val properties = typeSpec.allProperties;
- val ctCls = createClass(inputType.codecClassName) [
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- staticQNameField(node.QName, sourceGenerator);
- implementsType(BINDING_CODEC)
- method(Object, "toDomStatic", #[QName, Object]) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- «QName.name» _resultName;
- if($1 != null) {
- _resultName = «QName.name».create($1,QNAME.getLocalName());
- } else {
- _resultName = QNAME;
- }
- java.util.List _childNodes = new java.util.ArrayList();
- «inputType.resolvedName» value = («inputType.name») $2;
- «FOR key : node.keyDefinition»
- «val propertyName = key.getterName»
- «val keyDef = node.getDataChildByName(key)»
- «val property = properties.get(propertyName)»
- «serializeProperty(keyDef, property, propertyName)»;
- «ENDFOR»
- return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
- }
- '''
- setBodyChecked(body, sourceGenerator)
- ]
- method(Object, "fromDomStatic", #[QName, Object]) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- if($2 == null){
- return null;
- }
- «QName.name» _localQName = $1;
- java.util.Map _compositeNode = (java.util.Map) $2;
- boolean _is_empty = true;
- «FOR key : node.keyDefinition»
- «val propertyName = key.getterName»
- «val keyDef = node.getDataChildByName(key)»
- «val property = properties.get(propertyName)»
- «deserializeProperty(keyDef, property, propertyName)»;
- «ENDFOR»
- «inputType.resolvedName» _value = new «inputType.name»(«node.keyDefinition.
- keyConstructorList»);
- return _value;
- }
- '''
- setBodyChecked(body, sourceGenerator)
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- java.util.Map.Entry _input = (java.util.Map.Entry) $1;
- «QName.name» _localQName = («QName.name») _input.getKey();
- «inputType.name» _keyValue = («inputType.name») _input.getValue();
- return toDomStatic(_localQName,_keyValue);
- }
- '''
- setBodyChecked(body, sourceGenerator)
- ]
- method(Object, "deserialize", Object) [
- val body = '''
- {
- «QName.name» _qname = QNAME;
- if($1 instanceof java.util.Map.Entry) {
- _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
- }
- return fromDomStatic(_qname,$1);
- }
- '''
- setBodyChecked(body, sourceGenerator)
- ]
- ]
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- sourceGenerator.outputGeneratedSource( ctCls )
- LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
- return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
- } catch (Exception e) {
- processException(inputType, e);
- return null;
- }
- }
-
- private def Class<? extends BindingCodec<Object, Object>> generateCaseCodec(Class<?> inputType, GeneratedType type,
- ChoiceCaseNode node) {
- try {
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- //log.info("Generating DOM Codec for {} with {}, TCCL is: {}", inputType, inputType.classLoader,Thread.currentThread.contextClassLoader)
- val ctCls = createClass(type.codecClassName) [
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- implementsType(BINDING_CODEC)
- staticQNameField(node.QName, sourceGenerator);
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, AUGMENTATION_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- method(Object, "toDomStatic", #[QName, Object]) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
- java.util.List _childNodes = new java.util.ArrayList();
- «type.resolvedName» value = («type.resolvedName») $2;
- «transformDataContainerBody(type, type.allProperties, node)»
- return ($r) _childNodes;
- }
- '''
- setBodyChecked( body, sourceGenerator)
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- java.util.Map.Entry _input = (java.util.Map.Entry) $1;
- «QName.name» _localName = QNAME;
- if(_input.getKey() != null) {
- _localName = («QName.name») _input.getKey();
- }
- return toDomStatic(_localName,_input.getValue());
- }
- '''
- setBodyChecked( body, sourceGenerator)
- ]
- method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
- modifiers = PUBLIC + FINAL + STATIC
- setBodyChecked( deserializeBody(type, node, getBindingIdentifierByPath(node.path)),
- sourceGenerator )
- ]
- method(Object, "deserialize", #[Object, InstanceIdentifier]) [
- val body = '''
- {
- //System.out.println("«type.name»#deserialize: " +$1);
- java.util.Map.Entry _input = (java.util.Map.Entry) $1;
- return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue(),$2);
- }
- '''
- setBodyChecked( body, sourceGenerator)
- ]
- ]
-
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Object, Object>>
- sourceGenerator.outputGeneratedSource( ctCls )
- listener?.onDataContainerCodecCreated(inputType, ret);
- LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
- return ret;
- } catch (Exception e) {
- processException(inputType, e);
- return null;
- }
- }
-
- private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
- Class<?> inputType, GeneratedType typeSpec, SchemaNode node) {
- try {
-
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
- val ctCls = createClass(typeSpec.codecClassName) [
-
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- staticQNameField(node.QName, sourceGenerator);
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- staticField(it, AUGMENTATION_CODEC, BindingCodec, sourceGenerator)
- implementsType(BINDING_CODEC)
-
- method(Object, "toDomStatic", #[QName, Object]) [
- modifiers = PUBLIC + FINAL + STATIC
- setBodyChecked( serializeBodyFacade(typeSpec, node), sourceGenerator )
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- java.util.Map.Entry _input = (java.util.Map.Entry) $1;
- «QName.name» _localName = QNAME;
- if(_input.getKey() != null) {
- _localName = («QName.name») _input.getKey();
- }
- return toDomStatic(_localName,_input.getValue());
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
-
- method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
- modifiers = PUBLIC + FINAL + STATIC
- setBodyChecked( deserializeBody(typeSpec, node, getBindingIdentifierByPath(node.path)),
- sourceGenerator )
- ]
-
- method(Object, "deserialize", #[Object, InstanceIdentifier]) [
- val body = '''
- {
- «QName.name» _qname = QNAME;
- if($1 instanceof java.util.Map.Entry) {
- _qname = («QName.name») ((java.util.Map.Entry) $1).getKey();
- }
- return fromDomStatic(_qname,$1,$2);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- ]
-
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
-
- sourceGenerator.outputGeneratedSource( ctCls )
-
- listener?.onDataContainerCodecCreated(inputType, ret);
- LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
- return ret;
- } catch (Exception e) {
- processException(inputType, e);
- return null;
- }
- }
-
- private def Class<? extends BindingCodec<Map<QName, Object>, Object>> generateAugmentationTransformerFor(
- Class<?> inputType, GeneratedType type, AugmentationSchema node) {
- try {
-
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
- val properties = type.allProperties
- val ctCls = createClass(type.codecClassName) [
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- staticQNameField(node.augmentationQName, sourceGenerator);
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, AUGMENTATION_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- implementsType(BINDING_CODEC)
-
- method(Object, "toDomStatic", #[QName, Object]) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- ////System.out.println("Qname " + $1);
- ////System.out.println("Value " + $2);
- «QName.name» _resultName = «QName.name».create(QNAME,QNAME.getLocalName());
- java.util.List _childNodes = new java.util.ArrayList();
- «type.resolvedName» value = («type.resolvedName») $2;
- «FOR child : node.childNodes»
- «var signature = properties.getFor(child)»
- ////System.out.println("«signature.key»" + value.«signature.key»());
- «serializeProperty(child, signature.value, signature.key)»
- «ENDFOR»
- return ($r) _childNodes;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- java.util.Map.Entry _input = (java.util.Map.Entry) $1;
- «QName.name» _localName = QNAME;
- if(_input.getKey() != null) {
- _localName = («QName.name») _input.getKey();
- }
- return toDomStatic(_localName,_input.getValue());
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
-
- method(Object, "fromDomStatic", #[QName, Object, InstanceIdentifier]) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- «QName.name» _localQName = QNAME;
-
- if($2 == null) {
- return null;
- }
- java.util.Map _compositeNode = (java.util.Map) $2;
- //System.out.println(_localQName + " " + _compositeNode);
- «type.builderName» _builder = new «type.builderName»();
- boolean _is_empty = true;
- «FOR child : node.childNodes»
- «val signature = properties.getFor(child)»
- «deserializeProperty(child, signature.value, signature.key)»
- _builder.«signature.key.toSetter»(«signature.key»);
- «ENDFOR»
- if(_is_empty) {
- return null;
- }
- return _builder.build();
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
-
- method(Object, "deserialize", #[Object, InstanceIdentifier]) [
- val body = '''
- {
- return fromDomStatic(QNAME,$1,$2);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- ]
-
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain) as Class<? extends BindingCodec<Map<QName,Object>, Object>>
- sourceGenerator.outputGeneratedSource( ctCls )
- listener?.onDataContainerCodecCreated(inputType, ret);
- return ret;
- } catch (Exception e) {
- processException(inputType, e);
- return null;
- }
- }
-
- private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(
- Class<?> inputType, GeneratedType typeSpec, ChoiceSchemaNode node) {
- try {
-
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
- val ctCls = createClass(typeSpec.codecClassName) [
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- //staticQNameField(inputType);
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- staticField(it, DISPATCH_CODEC, BindingCodec, sourceGenerator)
- //staticField(it,QNAME_TO_CASE_MAP,BindingCodec)
- implementsType(BINDING_CODEC)
- method(List, "toDomStatic", #[QName, Object]) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- if($2 == null) {
- return null;
- }
- if («DISPATCH_CODEC» == null) {
- throw new «IllegalStateException.name»("Implementation of codec was not initialized.");
- }
- java.util.Map.Entry _input = new «SimpleEntry.name»($1,$2);
- Object _ret = «DISPATCH_CODEC».serialize(_input);
- ////System.out.println("«typeSpec.name»#toDomStatic: " + _ret);
- return («List.name») _ret;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "fromDomStatic", #[QName, Map, InstanceIdentifier]) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- if («DISPATCH_CODEC» == null) {
- throw new «IllegalStateException.name»("Implementation of codec was not initialized.");
- }
- return «DISPATCH_CODEC».deserialize($2,$3);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "deserialize", #[Object, InstanceIdentifier]) [
- val body = '''
- {
- throw new «UnsupportedOperationException.name»("Direct invocation not supported.");
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- ]
-
- val rawRet = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- sourceGenerator.outputGeneratedSource( ctCls )
- val ret = rawRet as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- listener?.onChoiceCodecCreated(inputType, ret, node);
- LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
- return ret;
- } catch (Exception e) {
- processException(inputType, e);
- return null;
- }
- }
-
- private def keyConstructorList(List<QName> qnames) {
- val names = new TreeSet<String>()
- for (name : qnames) {
- val fieldName = name.getterName;
- names.add(fieldName);
- }
- return Joiner.on(",").join(names);
- }
-
- private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
- val ret = serializeBody(type, node);
- return ret;
- }
-
- private def String deserializeBody(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) {
- val ret = deserializeBodyImpl(type, node, bindingId);
- return ret;
- }
-
- private def deserializeKey(GeneratedType type, ListSchemaNode node) {
- if (node.keyDefinition != null && !node.keyDefinition.empty) {
- return '''
- «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
- _builder.setKey(getKey);
- ''';
- }
- }
-
- private def String deserializeBodyWithAugmentations(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) '''
- {
- «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
- if($2 == null) {
- return null;
- }
- java.util.Map _compositeNode = (java.util.Map) $2;
- //System.out.println(_localQName + " " + _compositeNode);
- «type.builderName» _builder = new «type.builderName»();
- «deserializeDataNodeContainerBody(type, node, bindingId)»
- «type.deserializeAugmentations»
- return _builder.build();
- }
- '''
-
- private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node, InstanceIdentifier<?> bindingId) '''
- {
- «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
-
- if($2 == null) {
- return null;
- }
- java.util.Map _compositeNode = (java.util.Map) $2;
- «type.builderName» _builder = new «type.builderName»();
- return _builder.build();
- }
- '''
-
- private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node, InstanceIdentifier<?> bindingId) '''
- {
- «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
- if($2 == null) {
- return null;
- }
- java.util.Map _compositeNode = (java.util.Map) $2;
- //System.out.println(_localQName + " " + _compositeNode);
- «type.builderName» _builder = new «type.builderName»();
- «deserializeKey(type, node)»
- «deserializeDataNodeContainerBody(type, node, bindingId)»
- «type.deserializeAugmentations»
- return _builder.build();
- }
- '''
-
- private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node, InstanceIdentifier<?> bindingId) {
- return deserializeBodyWithAugmentations(type, node, bindingId);
- }
-
- private def dispatch String deserializeBodyImpl(GeneratedType type, NotificationDefinition node, InstanceIdentifier<?> bindingId) {
- return deserializeBodyWithAugmentations(type, node, bindingId);
- }
-
- private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node, InstanceIdentifier<?> bindingId) {
- return deserializeBodyWithAugmentations(type, node, bindingId);
- }
-
- private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node, InstanceIdentifier<?> bindingId) {
- deserializeNodeContainerBodyImpl(type, type.allProperties, node, bindingId);
- }
-
- private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, Type> properties,
- DataNodeContainer node, InstanceIdentifier<?> bindingId) {
- val ret = '''
- boolean _is_empty = true;
- «FOR child : node.childNodes»
- «val signature = properties.getFor(child)»
- «IF signature !== null»
- «deserializeProperty(child, signature.value, signature.key)»
- _builder.«signature.key.toSetter»(«signature.key»);
- «ENDIF»
- «ENDFOR»
- '''
- return ret;
- }
-
- def deserializeAugmentations(GeneratedType type) '''
- «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
- java.util.Map _augmentation = (java.util.Map) «AUGMENTATION_CODEC».deserialize(_compositeNode,$3);
- if(_augmentation != null) {
- «Iterator.name» _entries = _augmentation.entrySet().iterator();
- while(_entries.hasNext()) {
- java.util.Map.Entry _entry = (java.util.Map.Entry) _entries.next();
- ////System.out.println("Aug. key:" + _entry.getKey());
- Class _type = (Class) _entry.getKey();
- «Augmentation.resolvedName» _value = («Augmentation.name») _entry.getValue();
- if(_value != null) {
- _builder.addAugmentation(_type,_value);
- }
- }
- }
- '''
-
- private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
- String propertyName) '''
- java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
- localName»"));
- ////System.out.println("«propertyName»#deCode"+_dom_«propertyName»);
- java.util.List «propertyName» = new java.util.ArrayList();
- if(_dom_«propertyName» != null) {
- java.util.List _serialized = new java.util.ArrayList();
- java.util.Iterator _iterator = _dom_«propertyName».iterator();
- boolean _hasNext = _iterator.hasNext();
- while(_hasNext) {
- Object _listItem = _iterator.next();
- _is_empty = false;
- ////System.out.println(" item" + _listItem);
- «val param = type.actualTypeArguments.get(0)»
- «InstanceIdentifier.resolvedName» iid = $3.builder().child(«param.resolvedName».class).build();
- Object _value = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».fromDomStatic(_localQName,_listItem,iid);
- ////System.out.println(" value" + _value);
- «propertyName».add(_value);
- _hasNext = _iterator.hasNext();
- }
- }
-
- ////System.out.println(" list" + «propertyName»);
- '''
-
- private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
- String propertyName) '''
- java.util.List _dom_«propertyName» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
- localName»"));
- java.util.List «propertyName» = new java.util.ArrayList();
- if(_dom_«propertyName» != null) {
- java.util.List _serialized = new java.util.ArrayList();
- java.util.Iterator _iterator = _dom_«propertyName».iterator();
- boolean _hasNext = _iterator.hasNext();
- while(_hasNext) {
- _is_empty = false;
- Object _listItem = _iterator.next();
- if(_listItem instanceof java.util.Map.Entry) {
- Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
- Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue", schema.type)»;
- «propertyName».add(_value);
- }
- _hasNext = _iterator.hasNext();
- }
- }
- '''
-
- private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
- java.util.List _dom_«propertyName»_list =
- _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
- «type.resolvedName» «propertyName» = null;
- if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
- _is_empty = false;
- java.util.Map.Entry _dom_«propertyName» = (java.util.Map.Entry) _dom_«propertyName»_list.get(0);
- Object _inner_value = _dom_«propertyName».getValue();
- «propertyName» = «deserializeValue(type, "_inner_value", schema.type)»;
- }
- '''
-
- private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
- String propertyName) '''
- java.util.List _dom_«propertyName»_list =
- _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
- «type.resolvedName» «propertyName» = null;
- if(_dom_«propertyName»_list != null && _dom_«propertyName»_list.size() > 0) {
- _is_empty = false;
- java.util.Map _dom_«propertyName» = (java.util.Map) _dom_«propertyName»_list.get(0);
- «InstanceIdentifier.resolvedName» iid = $3.builder().child(«type.resolvedName».class).build();
- «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_dom_«propertyName»,iid);
- }
- '''
-
- private def dispatch CharSequence deserializeProperty(ChoiceSchemaNode schema, Type type, String propertyName) '''
- «type.resolvedName» «propertyName» = «type.serializer(schema).resolvedName».fromDomStatic(_localQName,_compositeNode,$3);
- if(«propertyName» != null) {
- _is_empty = false;
- }
- '''
-
- private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter,
- TypeDefinition<?> typeDefinition) '''
- («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
- '''
-
- private def dispatch String deserializeValue(Enumeration type, String domParameter, TypeDefinition<?> typeDefinition) '''
- («type.resolvedName») «type.valueSerializer(typeDefinition).resolvedName».fromDomValue(«domParameter»)
- '''
-
- private def dispatch String deserializeValue(Type type, String domParameter, TypeDefinition<?> typeDef) {
- if (INSTANCE_IDENTIFIER.equals(type)) {
- return '''(«InstanceIdentifier.name») «INSTANCE_IDENTIFIER_CODEC».deserialize(«domParameter»)'''
- } else if (CLASS_TYPE.equals(type)) {
- return '''(«Class.name») «IDENTITYREF_CODEC».deserialize(«domParameter»)'''
- } else if (typeDef!=null && typeDef instanceof EmptyTypeDefinition) {
- if(domParameter == null) {
- return ''' Boolean.FALSE '''
- } else {
- return ''' Boolean.TRUE '''
- }
- }
- return '''(«type.resolvedName») «domParameter»'''
- }
-
- private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
- Class<?> inputType, GeneratedTransferObject typeSpec, TypeDefinition<?> typeDef) {
- try {
-
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- val returnType = typeSpec.valueReturnType;
- if (returnType == null) {
- val ctCls = createDummyImplementation(inputType, typeSpec, sourceGenerator);
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- sourceGenerator.outputGeneratedSource( ctCls )
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- }
-
- val ctCls = createClass(typeSpec.codecClassName) [
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- if (inputType.isYangBindingAvailable) {
- implementsType(BINDING_CODEC)
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- implementsType(BindingDeserializer.asCtClass)
- }
- method(Object, "toDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val ctSpec = typeSpec.asCtClass;
- val body = '''
- {
- ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
-
- if($1 == null) {
- return null;
- }
- «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
- ////System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
- «returnType.resolvedName» _value = _encapsulatedValue.getValue();
- ////System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
- Object _domValue = «serializeValue(returnType, "_value", null)»;
- return _domValue;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- return toDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "fromDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
-
- if($1 == null) {
- return null;
- }
- «returnType.resolvedName» _simpleValue = «deserializeValue(returnType, "$1", null)»;
- «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
- return _value;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "deserialize", Object) [
- val body = '''
- {
- return fromDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- ]
-
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- sourceGenerator.outputGeneratedSource( ctCls )
- LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- } catch (Exception e) {
- LOG.error("Cannot compile DOM Codec for {}", inputType, e);
- val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
- exception.addSuppressed(e);
- throw exception;
- }
- }
-
- private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
- Class<?> inputType, GeneratedTransferObject typeSpec, UnionTypeDefinition typeDef) {
- try {
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- val ctCls = createClass(typeSpec.codecClassName) [
- val properties = typeSpec.allProperties;
- val getterToTypeDefinition = XtendHelper.getTypes(typeDef).toMap[type|type.QName.getterName];
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- if (inputType.isYangBindingAvailable) {
- implementsType(BINDING_CODEC)
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- implementsType(BindingDeserializer.asCtClass)
- }
- method(Object, "toDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val ctSpec = inputType.asCtClass;
- val body = '''
- {
- ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
-
- if($1 == null) {
- return null;
- }
- «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
- «FOR property : properties.entrySet»
- «IF property.key != "getValue"»
- «property.value.resolvedName» «property.key» = («property.value.resolvedName») _value.«property.
- key»();
- if(«property.key» != null) {
- return «serializeValue(property.value, property.key,
- getterToTypeDefinition.get(property.key))»;
- }
- «ENDIF»
- «ENDFOR»
-
- return null;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- return toDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "fromDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- ////System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
-
- if($1 == null) {
- return null;
- }
- if($1 instanceof String) {
- String _simpleValue = (String) $1;
- return new «typeSpec.resolvedName»(_simpleValue.toCharArray());
- }
- return null;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "deserialize", Object) [
- val body = '''
- {
- return fromDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- ]
-
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- sourceGenerator.outputGeneratedSource( ctCls )
- LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- } catch (Exception e) {
- LOG.error("Cannot compile DOM Codec for {}", inputType, e);
- val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
- exception.addSuppressed(e);
- throw exception;
- }
- }
-
- private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
- Class<?> inputType, GeneratedTransferObject typeSpec, BitsTypeDefinition typeDef) {
- try {
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- val ctCls = createClass(typeSpec.codecClassName) [
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- if (inputType.isYangBindingAvailable) {
- implementsType(BINDING_CODEC)
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- implementsType(BindingDeserializer.asCtClass)
- }
- method(Object, "toDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val ctSpec = typeSpec.asCtClass;
- val body = '''
- {
- ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
-
- if($1 == null) {
- return null;
- }
- «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
- «HashSet.resolvedName» _value = new «HashSet.resolvedName»();
- //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
-
- «FOR bit : typeDef.bits»
- «val getter = bit.getterName()»
- if(Boolean.TRUE.equals(_encapsulatedValue.«getter»())) {
- _value.add("«bit.name»");
- }
- «ENDFOR»
- «Set.resolvedName» _domValue = «Collections.resolvedName».unmodifiableSet(_value);
- //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_domValue);
-
- return _domValue;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- return toDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "fromDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val sortedBits = IterableExtensions.sort(typeDef.bits, [o1, o2|o1.propertyName.compareTo(o2.propertyName)])
- val body = '''
- {
- //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
-
- if($1 == null) {
- return null;
- }
- «Set.resolvedName» _domValue = («Set.resolvedName») $1;
- «FOR bit : sortedBits»
- Boolean «bit.propertyName» = Boolean.valueOf(_domValue.contains("«bit.name»"));
- «ENDFOR»
-
- return new «inputType.resolvedName»(«FOR bit : sortedBits SEPARATOR ","»«bit.propertyName»«ENDFOR»);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "deserialize", Object) [
- val body = '''
- {
- return fromDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- ]
-
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- sourceGenerator.outputGeneratedSource( ctCls )
- LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
- return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
- } catch (Exception e) {
- LOG.error("Cannot compile DOM Codec for {}", inputType, e);
- val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
- exception.addSuppressed(e);
- throw exception;
- }
- }
-
- def String getPropertyName(Bit bit) {
- '''_«BindingMapping.getPropertyName(bit.name)»'''
- }
-
- def String getterName(Bit bit) {
-
- val paramName = BindingMapping.getPropertyName(bit.name);
- return '''is«paramName.toFirstUpper»''';
- }
-
- def boolean isYangBindingAvailable(Class<?> class1) {
- try {
- val bindingCodecClass = class1.classLoader.loadClass(BINDING_CODEC.name);
- return bindingCodecClass !== null;
- } catch (ClassNotFoundException e) {
- return false;
- }
- }
-
- private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec,
- SourceCodeGenerator sourceGenerator ) {
- LOG.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
- return createClass(typeSpec.codecClassName) [
- if (object.isYangBindingAvailable) {
- implementsType(BINDING_CODEC)
- staticField(it, INSTANCE_IDENTIFIER_CODEC, BindingCodec, sourceGenerator)
- staticField(it, IDENTITYREF_CODEC, BindingCodec, sourceGenerator)
- implementsType(BindingDeserializer.asCtClass)
- }
- //implementsType(BindingDeserializer.asCtClass)
- method(Object, "toDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- if($1 == null) {
- return null;
- }
- return $1.toString();
- }'''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- return toDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "fromDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''return null;'''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "deserialize", Object) [
- val body = '''
- {
- return fromDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- ]
- }
-
- private def Type getValueReturnType(GeneratedTransferObject object) {
- for (prop : object.properties) {
- if (prop.name == "value") {
- return prop.returnType;
- }
- }
- if (object.superType != null) {
- return getValueReturnType(object.superType);
- }
- return null;
- }
-
- private def dispatch Class<?> generateValueTransformer(Class<?> inputType, Enumeration typeSpec, TypeDefinition<?> type) {
- var EnumerationType enumSchemaType
- if (type instanceof EnumerationType) {
- enumSchemaType = type as EnumerationType
- } else {
- val typeRef = new ReferencedTypeImpl(typeSpec.packageName, typeSpec.name);
- val schema = getSchemaNode(typeRef) as ExtendedType;
- enumSchemaType = schema.baseType as EnumerationType;
- }
- val enumSchema = enumSchemaType;
- try {
- val SourceCodeGenerator sourceGenerator = sourceCodeGeneratorFactory.getInstance( null );
-
- //log.info("Generating DOM Codec for {} with {}", inputType, inputType.classLoader)
- val ctCls = createClass(typeSpec.codecClassName) [
- //staticField(Map,"AUGMENTATION_SERIALIZERS");
- //implementsType(BINDING_CODEC)
- method(Object, "toDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- if($1 == null) {
- return null;
- }
- «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
- «FOR en : enumSchema.values»
- if(«typeSpec.resolvedName».«BindingMapping.getClassName(en.name)».equals(_value)) {
- return "«en.name»";
- }
- «ENDFOR»
- return null;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "serialize", Object) [
- val body = '''
- {
- return toDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "fromDomValue", Object) [
- modifiers = PUBLIC + FINAL + STATIC
- val body = '''
- {
- if($1 == null) {
- return null;
- }
- String _value = (String) $1;
- «FOR en : enumSchema.values»
- if("«en.name»".equals(_value)) {
- return «typeSpec.resolvedName».«BindingMapping.getClassName(en.name)»;
- }
- «ENDFOR»
- return null;
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- method(Object, "deserialize", Object) [
- val body = '''
- {
- return fromDomValue($1);
- }
- '''
- setBodyChecked( body, sourceGenerator )
- ]
- ]
-
- val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
- sourceGenerator.outputGeneratedSource( ctCls )
- LOG.debug("DOM Codec for {} was generated {}", inputType, ret)
- return ret;
- } catch (CodeGenerationException e) {
- throw new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
- } catch (Exception e) {
- LOG.error("Cannot compile DOM Codec for {}", inputType, e);
- val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
- exception.addSuppressed(e);
- throw exception;
- }
-
- }
-
- def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
- val cls = newClass.toClass(loader, domain);
- if (classFileCapturePath !== null) {
- newClass.writeFile(classFileCapturePath.absolutePath);
- }
- listener?.onCodecCreated(cls);
- return cls;
- }
-
- def debugWriteClass(CtClass class1) {
- val path = class1.name.replace(".", "/") + ".class"
-
- val captureFile = new File(classFileCapturePath, path);
- captureFile.createNewFile
-
- }
-
- /**
- * Default catch all
- *
- **/
- private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, String propertyName) '''
- «type.resolvedName» «propertyName» = null;
- '''
-
- private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
- String propertyName) {
- _deserializeProperty(container, type.toInstance, propertyName)
- }
-
- static def toSetter(String it) {
-
- if (startsWith("is")) {
- return "set" + substring(2);
- } else if (startsWith("get")) {
- return "set" + substring(3);
- }
- return "set" + it;
- }
-
- /*
- private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, String propertyName) '''
- «type.resolvedName» «propertyName» = value.«propertyName»();
- if(«propertyName» != null) {
- Object domValue = «type.serializer».toDomStatic(QNAME,«propertyName»);
- _childNodes.add(domValue);
- }
- '''
- */
- private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
-
- private def staticQNameField(CtClass it, QName node, SourceCodeGenerator sourceGenerator) {
- val field = new CtField(ctQName, "QNAME", it);
- field.modifiers = PUBLIC + FINAL + STATIC;
- val code = '''«QName.asCtClass.name».cachedReference(«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»"))'''
- addField(field, code )
-
- sourceGenerator.appendField( field, code );
- }
-
- private def String serializeBodyImpl(GeneratedType type, DataNodeContainer nodeContainer) '''
- {
- «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
- java.util.List _childNodes = new java.util.ArrayList();
- «type.resolvedName» value = («type.resolvedName») $2;
- «transformDataContainerBody(type, type.allProperties, nodeContainer)»
- «serializeAugmentations»
- return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
- }
- '''
-
- private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) {
- return serializeBodyImpl(type, node);
- }
-
- private def dispatch String serializeBody(GeneratedType type, NotificationDefinition node) {
- return serializeBodyImpl(type, node);
- }
-
- private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) {
- return serializeBodyImpl(type, node);
- }
-
- private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) {
- return serializeBodyImpl(type, node);
- }
-
- private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
- {
- «QName.name» _resultName = «QName.name».create($1,QNAME.getLocalName());
- java.util.List _childNodes = new java.util.ArrayList();
- «type.resolvedName» value = («type.resolvedName») $2;
- return ($r) java.util.Collections.singletonMap(_resultName,_childNodes);
- }
- '''
-
- private def transformDataContainerBody(Type type, Map<String, Type> properties, DataNodeContainer node) {
- val ret = '''
- «FOR child : node.childNodes»
- «val signature = properties.getFor(child)»
- «IF signature !== null»
- ////System.out.println("«type.name»#«signature.key»" + value.«signature.key»());
- «serializeProperty(child, signature.value, signature.key)»
- «ENDIF»
- «ENDFOR»
- '''
- return ret;
- }
-
- private static def serializeAugmentations() '''
- java.util.List _augmentations = (java.util.List) «AUGMENTATION_CODEC».serialize(value);
- if(_augmentations != null) {
- _childNodes.addAll(_augmentations);
- }
- '''
-
- private static def Entry<String, Type> getFor(Map<String, Type> map, DataSchemaNode node) {
- var sig = map.get(node.getterName);
- if (sig != null) {
- return new SimpleEntry(node.getterName, sig);
- }
- sig = map.get(node.booleanGetterName);
- if (sig != null) {
- return new SimpleEntry(node.booleanGetterName, map.get(node.booleanGetterName));
- }
- return null;
- }
-
- private static def String getBooleanGetterName(DataSchemaNode node) {
- return "is" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
- }
-
- private static def String getGetterName(DataSchemaNode node) {
- return "get" + BindingMapping.getPropertyName(node.QName.localName).toFirstUpper;
- }
-
- private static def String getGetterName(QName node) {
- return "get" + BindingMapping.getPropertyName(node.localName).toFirstUpper;
- }
-
- private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
- String propertyName) '''
- «type.resolvedName» «propertyName» = value.«propertyName»();
- ////System.out.println("«propertyName»:" + «propertyName»);
- if(«propertyName» != null) {
- java.util.Iterator _iterator = «propertyName».iterator();
- boolean _hasNext = _iterator.hasNext();
- while(_hasNext) {
- Object _listItem = _iterator.next();
- Object _domValue = «type.actualTypeArguments.get(0).serializer(schema).resolvedName».toDomStatic(_resultName,_listItem);
- _childNodes.add(_domValue);
- _hasNext = _iterator.hasNext();
- }
- }
- '''
-
- private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, String propertyName) '''
- «type.resolvedName» «propertyName» = value.«propertyName»();
-
- if(«propertyName» != null) {
- «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
- Object _propValue = «serializeValue(type, propertyName, schema.type)»;
- if(_propValue != null) {
- Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
- _childNodes.add(_domValue);
- }
- }
- '''
-
- private def dispatch serializeValue(GeneratedTransferObject type, String parameter, TypeDefinition<?> typeDefinition) {
- '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
- }
-
- private def dispatch serializeValue(Enumeration type, String parameter, TypeDefinition<?> typeDefinition) {
- '''«type.valueSerializer(typeDefinition).resolvedName».toDomValue(«parameter»)'''
- }
-
- private def dispatch serializeValue(Type type, String parameter, EmptyTypeDefinition typeDefinition) {
- '''(«parameter».booleanValue() ? "" : null)'''
- }
-
- private def dispatch serializeValue(Type signature, String property, TypeDefinition<?> typeDefinition) {
- serializeValue(signature,property)
- }
-
- private def dispatch serializeValue(Type signature, String property, Void typeDefinition) {
- serializeValue(signature,property)
- }
-
- private def dispatch serializeValue(Type signature, String property) {
- if (INSTANCE_IDENTIFIER == signature) {
- return '''«INSTANCE_IDENTIFIER_CODEC».serialize(«property»)'''
- } else if (CLASS_TYPE.equals(signature)) {
- return '''(«QName.resolvedName») «IDENTITYREF_CODEC».serialize(«property»)'''
- }
- if ("char[]" == signature.name) {
- return '''new String(«property»)''';
- }
- return '''«property»''';
- }
-
- private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, ParameterizedType type,
- String propertyName) '''
- «type.resolvedName» «propertyName» = value.«propertyName»();
- if(«propertyName» != null) {
- «QName.name» _qname = «QName.name».create(_resultName,"«schema.QName.localName»");
- java.util.Iterator _iterator = «propertyName».iterator();
- boolean _hasNext = _iterator.hasNext();
- while(_hasNext) {
- Object _listItem = _iterator.next();
- Object _propValue = «serializeValue(type.actualTypeArguments.get(0), "_listItem", schema.type)»;
- Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
- _childNodes.add(_domValue);
- _hasNext = _iterator.hasNext();
- }
- }
- '''
-
- private def dispatch CharSequence serializeProperty(ChoiceSchemaNode container, GeneratedType type,
- String propertyName) '''
- «type.resolvedName» «propertyName» = value.«propertyName»();
- if(«propertyName» != null) {
- java.util.List domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
- _childNodes.addAll(domValue);
- }
- '''
-
- /**
- * Default catch all
- *
- **/
- private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, String propertyName) '''
- «type.resolvedName» «propertyName» = value.«propertyName»();
- if(«propertyName» != null) {
- Object domValue = «propertyName»;
- _childNodes.add(domValue);
- }
- '''
-
- private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
- String propertyName) {
- serializeProperty(container, type.toInstance, propertyName)
- }
-
- private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
- String propertyName) '''
- «type.resolvedName» «propertyName» = value.«propertyName»();
- if(«propertyName» != null) {
- Object domValue = «type.serializer(container).resolvedName».toDomStatic(_resultName,«propertyName»);
- _childNodes.add(domValue);
- }
- '''
-
- private def codecClassName(GeneratedType typeSpec) {
- return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
- }
-
- private def codecClassName(Class<?> typeSpec) {
- return '''«typeSpec.name»$Broker$Codec$DOM'''
- }
-
- private def HashMap<String, Type> getAllProperties(GeneratedType type) {
- val ret = new HashMap<String, Type>();
- type.collectAllProperties(ret);
- return ret;
- }
-
- private def dispatch void collectAllProperties(GeneratedType type, Map<String, Type> set) {
- for (definition : type.methodDefinitions) {
- set.put(definition.name, definition.returnType);
- }
- for (property : type.properties) {
- set.put(property.getterName, property.returnType);
- }
- for (parent : type.implements) {
- parent.collectAllProperties(set);
- }
- }
-
- def String getGetterName(GeneratedProperty property) {
- return "get" + property.name.toFirstUpper
- }
-
- private def dispatch void collectAllProperties(Type type, Map<String, Type> set) {
- // NOOP for generic type.
- }
-
- def String getResolvedName(Type type) {
- return type.asCtClass.name;
- }
-
- def String getResolvedName(Class<?> type) {
- return type.asCtClass.name;
- }
-
- def CtClass asCtClass(Type type) {
- val cls = loadClass(type.fullyQualifiedName)
- return cls.asCtClass;
- }
-
- private def dispatch processException(Class<?> inputType, CodeGenerationException e) {
- LOG.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.", inputType);
- throw e;
- }
-
- private def dispatch processException(Class<?> inputType, Exception e) {
- LOG.error("Cannot compile DOM Codec for {}", inputType, e);
- val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType, e);
- throw exception;
- }
-
- private def setBodyChecked(CtMethod method, String body, SourceCodeGenerator sourceGenerator ) {
- try {
- method.setBody(body);
-
- sourceGenerator.appendMethod( method, body );
- } catch (CannotCompileException e) {
- LOG.error("Cannot compile method: {}#{} {}, Reason: {} Body: {}", method.declaringClass, method.name,
- method.signature, e.message, body)
- throw e;
- }
- }
-}
-
+++ /dev/null
-/*
- * 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.sal.binding.generator.impl;
-
-import org.opendaylight.yangtools.sal.binding.model.api.Type;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-/**
- * Internal interface exposed to TransformerGenerator
- */
-interface TypeResolver {
- AugmentationSchema getAugmentation(Type type);
- GeneratedTypeBuilder getDefinition(Type type);
- SchemaNode getSchemaNode(Type type);
- GeneratedTypeBuilder getTypeBuilder(SchemaPath path);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 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.sal.binding.generator.impl;
\ No newline at end of file
import java.net.URL;
import org.opendaylight.yangtools.restconf.client.api.auth.AuthenticationHolder;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder;
/**
* An interface for acquiring #{@link RestconfClientContext} instances.
*/
public interface RestconfClientContextFactory {
- /**
- * Get a #{@link RestconfClientContext} attached to the server pointed to by an URL.
- * @param baseUrl URL pointer to the backend server
- * @return RestconfClientContext attached to the backend server.
- * @throws UnsupportedProtocolException if the factory cannot handle the protocol specified in the URL.
- */
- @Deprecated
- RestconfClientContext getRestconfClientContext(URL baseUrl,BindingIndependentMappingService mappingService,SchemaContextHolder holder) throws UnsupportedProtocolException;
- void setAuthentication(AuthenticationHolder authenticationHolder);
RestconfClientContext getRestconfClientContext(URL baseUrl, SchemaContextHolder schemaContextHolder)
throws UnsupportedProtocolException;
+ void setAuthentication(AuthenticationHolder authenticationHolder);
+
}
import org.opendaylight.yangtools.restconf.client.api.RestconfClientContextFactory;
import org.opendaylight.yangtools.restconf.client.api.UnsupportedProtocolException;
import org.opendaylight.yangtools.restconf.client.api.auth.AuthenticationHolder;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(RestconfClientFactory.class);
private AuthenticationHolder authenticationHolder;
- @Override
- @Deprecated
- public RestconfClientContext getRestconfClientContext(URL baseUrl, BindingIndependentMappingService mappingService, SchemaContextHolder schemaContextHolder) throws UnsupportedProtocolException {
- if (!baseUrl.getProtocol().equals("http")){
- throw new UnsupportedProtocolException("Unsupported protocol "+baseUrl.getProtocol());
- }
- RestconfClientImpl restconfClient = new RestconfClientImpl(baseUrl,mappingService,schemaContextHolder);
- if (null!=authenticationHolder){
- restconfClient.setAuthenticationHolder(authenticationHolder);
- }
- return restconfClient;
- }
+
@Override
public RestconfClientContext getRestconfClientContext(URL baseUrl, SchemaContextHolder schemaContextHolder) throws UnsupportedProtocolException {
import org.opendaylight.yangtools.restconf.utils.XmlTools;
import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder;
import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
private DataObjectSerializerGenerator generator;
- @Deprecated
- public RestconfClientImpl(final URL url, final BindingIndependentMappingService mappingService,
- final SchemaContextHolder schemaContextHolder) {
- this(url,schemaContextHolder);
- }
-
public RestconfClientImpl(final URL url, final SchemaContextHolder schemaContextHolder) {
Preconditions.checkArgument(url != null, "Restconf endpoint URL must be supplied.");
Preconditions.checkNotNull(schemaContextHolder, "Schema Context Holder must not be null.");
*/
package org.opendaylight.yangtools.restconf.client;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
import com.google.common.util.concurrent.ListenableFuture;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutionException;
-import javassist.ClassPool;
import org.junit.Before;
import org.opendaylight.yangtools.restconf.client.api.RestconfClientContext;
import org.opendaylight.yangtools.restconf.client.api.UnsupportedProtocolException;
import org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo;
import org.opendaylight.yangtools.restconf.client.api.event.ListenableEventStreamContext;
import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
public class RestconfClientImplTest {
public static final String JSON = "+json";
public static final String XML = "+xml";
private RestconfClientContext restconfClientContext;
- private RuntimeGeneratedMappingServiceImpl mappingService;
-
@Before
public void setupRestconfClientContext() throws MalformedURLException, UnsupportedProtocolException {
- mappingService = new RuntimeGeneratedMappingServiceImpl(new ClassPool());
final ModuleInfoBackedContext moduleInfo = ModuleInfoBackedContext.create();
moduleInfo.addModuleInfos(BindingReflections.loadModuleInfos());
- mappingService.onGlobalContextUpdated(moduleInfo.tryToCreateSchemaContext().get());
- this.restconfClientContext = new RestconfClientFactory().getRestconfClientContext(new URL(restconfUrl),mappingService, mappingService);
+ this.restconfClientContext = new RestconfClientFactory().getRestconfClientContext(new URL(restconfUrl),new SchemaContextHolder() {
+
+ @Override
+ public SchemaContext getSchemaContext() {
+ return moduleInfo.tryToCreateSchemaContext().get();
+ }
+ });
assertNotNull(this.restconfClientContext);
}
}
if (streamsFuture.isDone()){
try {
- Set<EventStreamInfo> streams = (Set<EventStreamInfo>) streamsFuture.get();
+ Set<EventStreamInfo> streams = streamsFuture.get();
assertNotNull(streams);
} catch (InterruptedException e) {
fail(e.getMessage());
}
if (servicesFuture.isDone()){
try {
- Set<Class<? extends RpcService>> streams = (Set<Class<? extends RpcService>>) servicesFuture.get();
+ Set<Class<? extends RpcService>> streams = servicesFuture.get();
assertNotNull(streams);
} catch (InterruptedException e) {
fail(e.getMessage());
import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
import org.opendaylight.yangtools.yang.binding.DataObject;
private static final ReportedLspKey LSP1_KEY = new ReportedLspKey("one");
private static final ReportedLspKey LSP2_KEY = new ReportedLspKey("two");
- private RuntimeGeneratedMappingServiceImpl mappingService;
+
private Optional<SchemaContext> schemaContext;
private DataObjectSerializerGenerator generator;
private BindingNormalizedNodeCodecRegistry registry;
@Before
public void setup() {
- this.mappingService = new RuntimeGeneratedMappingServiceImpl(ClassPool.getDefault());
-
final ModuleInfoBackedContext moduleInfo = ModuleInfoBackedContext.create();
moduleInfo.addModuleInfos(BindingReflections.loadModuleInfos());
schemaContext = moduleInfo.tryToCreateSchemaContext();
- this.mappingService.onGlobalContextUpdated(moduleInfo.tryToCreateSchemaContext().get());
JavassistUtils utils = JavassistUtils.forClassPool(ClassPool.getDefault());
generator = StreamWriterGenerator.create(utils);
registry = new BindingNormalizedNodeCodecRegistry(generator);
+++ /dev/null
-/*
- * 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.impl.codec;
-
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-
-public interface AugmentationCodec<A extends Augmentation<?>> extends DomCodec<A> {
- @Override
- CompositeNode serialize(ValueWithQName<A> input);
-
- @Override
- ValueWithQName<A> deserialize(Node<?> input);
-
- QName getAugmentationQName();
-
- /**
- * Check if this codec was created for augmentation with given target node
- * path.
- *
- * @param path
- * identifier of augmentation target node
- * @return true, if this codec is generated for augmentation pointing node
- * with given path, false otherwise
- */
- boolean isAcceptable(InstanceIdentifier<?> path);
-}
+++ /dev/null
-/*
- * 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.impl.codec;
-
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-import com.google.common.base.Optional;
-
-public interface BindingIndependentMappingService {
-
- /**
- * Get codec registry.
- *
- * @return codec registry
- */
- CodecRegistry getCodecRegistry();
-
- /**
- * Convert given DataObject data to DOM-like node.
- *
- * @param data
- * DataObject instance
- * @return CompositeNode created from DataObject instance
- */
- CompositeNode toDataDom(DataObject data);
-
- /**
- * Create map entry representing node data (key = data schema node
- * identifier, value = value is node data representation as Composite node)
- * from entry representing node class (key = class object identifier, value
- * = class object).
- *
- * @param entry
- * map entry, where key is class object identifier and value
- * class object
- * @return data schema node identifier
- */
- Entry<org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier, CompositeNode> toDataDom(
- Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry);
-
- /**
- * Create data schema node identifier from class object identifier.
- *
- * @param path
- * class object identifier
- * @return data schema node identifier
- */
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier toDataDom(InstanceIdentifier<? extends DataObject> path);
-
- /**
- * Create DataObject instance from CompositeNode data based on given path.
- *
- * @param path
- * node identifier
- * @param result
- * node data
- * @return inputClass instance created from composite node input
- */
- DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result)
- throws DeserializationException;
-
- /**
- * Create class object identifier from data schema node identifier.
- *
- * @param entry
- * data schema node identifier
- * @return class object identifier
- */
- InstanceIdentifier<?> fromDataDom(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier entry)
- throws DeserializationException;
-
- /**
- * Returns the list of currently-known QNames for instances of a service.
- *
- * @param service
- * RPC service
- * @return List of QNames. The user may not modify this list.
- */
- Set<QName> getRpcQNamesFor(Class<? extends RpcService> service);
-
- /**
- * Get RpcService by namespace and revision.
- *
- * @param namespace
- * rpc service namespace
- * @param revision
- * rpc service revision
- * @return Optional reference on RpcServices based on given namespace and
- * revision
- */
- Optional<Class<? extends RpcService>> getRpcServiceClassFor(String namespace, String revision);
-
- /**
- * Create inputClass instance from CompositeNode data.
- *
- * @param inputClass
- * expected type of resulting object
- * @param domInput
- * node data
- * @return inputClass instance created from composite node input
- */
- DataContainer dataObjectFromDataDom(Class<? extends DataContainer> inputClass, CompositeNode domInput);
-
-}
+++ /dev/null
-/*
- * 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.impl.codec;
-
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-
-public interface ChoiceCaseCodec<C extends DataContainer> extends DataContainerCodec<C> {
- @Override
- CompositeNode serialize(ValueWithQName<C> input);
-
- @Override
- ValueWithQName<C> deserialize(Node<?> input);
-
- boolean isAcceptable(Node<?> input);
-}
+++ /dev/null
-/*
- * 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.impl.codec;
-
-import org.opendaylight.yangtools.yang.data.api.Node;
-
-public interface ChoiceCodec<C> extends DomCodec<C> {
- @Override
- Node<?> serialize(ValueWithQName<C> input);
-
- @Override
- ValueWithQName<C> deserialize(Node<?> input);
-}
+++ /dev/null
-/*
- * 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.impl.codec;
-
-import java.util.List;
-
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.binding.Augmentation;
-import org.opendaylight.yangtools.yang.binding.BaseIdentity;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.common.QName;
-
-public interface CodecRegistry {
-
- InstanceIdentifierCodec getInstanceIdentifierCodec();
-
- IdentityCodec<?> getIdentityCodec();
-
- <T extends DataContainer> DataContainerCodec<T> getCodecForDataObject(Class<T> object);
-
- <T extends Identifiable<?>> IdentifierCodec<?> getIdentifierCodecForIdentifiable(Class<T> object);
-
- <T extends Identifier<?>> IdentifierCodec<T> getCodecForIdentifier(Class<T> object);
-
- <T extends Augmentation<?>> AugmentationCodec<T> getCodecForAugmentation(Class<T> object);
-
- <T extends BaseIdentity> IdentityCodec<T> getCodecForIdentity(Class<T> codec);
-
- Class<?> getClassForPath(List<QName> names);
-
- IdentifierCodec<?> getKeyCodecForPath(List<QName> names);
-
-
- void bindingClassEncountered(Class<?> cls);
-
- void putPathToClass(List<QName> names, Class<?> cls);
-
- QName getQNameForAugmentation(Class<?> cls);
-}
+++ /dev/null
-/*
- * 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.impl.codec;
-
-import org.opendaylight.yangtools.yang.binding.DataContainer;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-
-public interface DataContainerCodec<T extends DataContainer> extends DomCodec<T> {
-
- @Override
- CompositeNode serialize(ValueWithQName<T> input);
-
- @Override
- ValueWithQName<T> deserialize(Node<?> input);
-
- ValueWithQName<T> deserialize(Node<?> input, InstanceIdentifier<?> bindingIdentifier);
-
-}
+++ /dev/null
-/*
- * 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.impl.codec;
-
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-
-public interface IdentifierCodec<I extends Identifier<?>> extends DomCodec<I> {
- @Override
- ValueWithQName<I> deserialize(Node<?> input);
-
- @Override
- CompositeNode serialize(ValueWithQName<I> input);
-}
+++ /dev/null
-/*
- * 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.impl.codec;
-
-import org.opendaylight.yangtools.yang.binding.BindingCodec;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public interface InstanceIdentifierCodec extends BindingCodec<YangInstanceIdentifier, InstanceIdentifier<?>> {
- @Override
- YangInstanceIdentifier serialize(InstanceIdentifier<?> input);
-
- @Override
- InstanceIdentifier<?> deserialize(YangInstanceIdentifier input);
-}