--- /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.Objects;
+import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+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 org.eclipse.xtext.xbase.lib.Functions.Function0;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.sal.binding.generator.impl.CodecTypeUtils;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+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.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.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+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<?>, 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(
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier input) {
+ Class<?> baType = null;
+ List<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument> biArgs = input.getPath();
+ List<QName> scannedPath = new ArrayList<>(biArgs.size());
+ List<InstanceIdentifier.PathArgument> baArgs = new ArrayList<InstanceIdentifier.PathArgument>(biArgs.size());
+ for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.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) {
+ Class<? extends DataObject> augment = (Class<? extends DataObject>) injectAugment.get(scannedPath);
+ if (augment != null) {
+ baArgs.add(new Item(augment));
+ }
+ }
+ baArgs.add(baArg);
+ }
+ InstanceIdentifier ret = new InstanceIdentifier(baArgs, (Class<? extends DataObject>) baType);
+ LOG.debug("DOM Instance Identifier {} deserialized to {}", input, ret);
+ return ret;
+ }
+
+ private org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument _deserializePathArgument(
+ final NodeIdentifier argument, final List<QName> processedPath) {
+ final Class cls = codecRegistry.getClassForPath(processedPath);
+ Item<DataObject> item = new Item<>(cls);
+ return item;
+ }
+
+ private org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument _deserializePathArgument(
+ final NodeIdentifierWithPredicates argument, final List<QName> processedPath) {
+ final Class type = codecRegistry.getClassForPath(processedPath);
+ final IdentifierCodec codec = codecRegistry
+ .<Identifiable<? extends Object>> getIdentifierCodecForIdentifiable(type);
+ CompositeNode _compositeNode = this.toCompositeNode(argument);
+ ValueWithQName<CompositeNode> deserialize = codec.deserialize(_compositeNode);
+ Object value = null;
+ if (deserialize != null) {
+ value = deserialize.getValue();
+ }
+ return CodecTypeUtils.newIdentifiableItem(type, value);
+ }
+
+ public CompositeNode toCompositeNode(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.InstanceIdentifier serialize(InstanceIdentifier<?> input) {
+ Class<?> previousAugmentation = null;
+ List<InstanceIdentifier.PathArgument> pathArgs = input.getPath();
+ QName previousQName = null;
+ List<PathArgument> components = new ArrayList<>(pathArgs.size());
+ List<QName> qnamePath = new ArrayList<>(pathArgs.size());
+ for (InstanceIdentifier.PathArgument baArg : pathArgs) {
+
+ if (!Augmentation.class.isAssignableFrom(baArg.getType())) {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument biArg = serializePathArgument(
+ baArg, previousQName);
+ previousQName = biArg.getNodeType();
+ components.add(biArg);
+ qnamePath.add(biArg.getNodeType());
+ ImmutableList<QName> immutableList = ImmutableList.copyOf(qnamePath);
+ codecRegistry.putPathToClass(immutableList, baArg.getType());
+ if (previousAugmentation != null) {
+ updateAugmentationInjection(baArg.getType(), immutableList, previousAugmentation);
+ }
+ previousAugmentation = null;
+ } else {
+ previousQName = codecRegistry.getQNameForAugmentation(baArg.getType());
+ previousAugmentation = baArg.getType();
+ }
+ }
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ret = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(
+ components);
+ LOG.debug("Binding Instance Identifier {} serialized to DOM InstanceIdentifier {}", input, ret);
+ return ret;
+ }
+
+ public Class<? extends Object> updateAugmentationInjection(Class<? extends DataObject> class1,
+ ImmutableList<QName> list, Class<?> augmentation) {
+ if (classToPreviousAugment.get(class1) == null) {
+ classToPreviousAugment.put(class1, new ConcurrentHashMap<List<QName>, Class<?>>());
+ }
+ return classToPreviousAugment.get(class1).put(list, augmentation);
+ }
+
+ private PathArgument _serializePathArgument(Item<?> argument, 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 _serializePathArgument(IdentifiableItem argument, QName previousQname) {
+ Map<QName, Object> predicates = new HashMap<>();
+ Class type = argument.getType();
+ 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());
+ }
+ ValueWithQName combinedInput = new ValueWithQName(previousQname, argument.getKey());
+ CompositeNode compositeOutput = keyCodec.serialize(combinedInput);
+ 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 _deserializePathArgument((NodeIdentifier) argument, processedPath);
+ } else if (argument instanceof NodeIdentifierWithPredicates) {
+ return _deserializePathArgument((NodeIdentifierWithPredicates) argument, processedPath);
+ } else {
+ throw new IllegalArgumentException("Unhandled parameter types: "
+ + Arrays.<Object> asList(argument, processedPath).toString());
+ }
+ }
+
+ private PathArgument serializePathArgument(
+ final org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument argument,
+ final QName previousQname) {
+ if (argument instanceof IdentifiableItem) {
+ return _serializePathArgument((IdentifiableItem) argument, previousQname);
+ } else if (argument instanceof Item) {
+ return _serializePathArgument((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.collect.ImmutableList
-import java.util.ArrayList
-import java.util.Collections
-import java.util.HashMap
-import java.util.List
-import java.util.Map
-import java.util.WeakHashMap
-import java.util.concurrent.ConcurrentHashMap
-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.InstanceIdentifier.NodeIdentifier
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
-import org.opendaylight.yangtools.yang.data.api.Node
-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.LoggerFactory
-
-class InstanceIdentifierCodecImpl implements InstanceIdentifierCodec {
-
- private static val LOG = LoggerFactory.getLogger(InstanceIdentifierCodecImpl);
- val CodecRegistry codecRegistry;
-
- val Map<Class<?>, Map<List<QName>, Class<?>>> classToPreviousAugment = Collections.synchronizedMap(new WeakHashMap);
-
- public new(CodecRegistry registry) {
- codecRegistry = registry;
- }
-
-
- override deserialize(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier input) {
- var Class<?> baType = null
- val biArgs = input.path
- val scannedPath = new ArrayList<QName>(biArgs.size);
- val baArgs = new ArrayList<InstanceIdentifier.PathArgument>(biArgs.size)
- for(biArg : biArgs) {
- scannedPath.add(biArg.nodeType);
- val baArg = deserializePathArgument(biArg,scannedPath)
- baType = baArg?.type
- val injectAugment = classToPreviousAugment.get(baType);
- if(injectAugment != null) {
- val augment = injectAugment.get(scannedPath) as Class<? extends DataObject>;
- if(augment != null) {
- baArgs.add(new Item(augment));
- }
- }
- baArgs.add(baArg)
- }
- val ret = new InstanceIdentifier(baArgs,baType as Class<? extends DataObject>);
- LOG.debug("DOM Instance Identifier {} deserialized to {}",input,ret);
- return ret;
- }
-
- private def dispatch InstanceIdentifier.PathArgument deserializePathArgument(NodeIdentifier argument,List<QName> processedPath) {
- val Class cls = codecRegistry.getClassForPath(processedPath);
- return new Item(cls);
- }
-
-
- private def dispatch InstanceIdentifier.PathArgument deserializePathArgument(NodeIdentifierWithPredicates argument,List<QName> processedPath) {
- val Class type = codecRegistry.getClassForPath(processedPath);
- val IdentifierCodec codec = codecRegistry.getIdentifierCodecForIdentifiable(type);
- val value = codec.deserialize(argument.toCompositeNode())?.value;
- return CodecTypeUtils.newIdentifiableItem(type,value);
- }
-
- def CompositeNode toCompositeNode(NodeIdentifierWithPredicates predicates) {
- val keyValues = predicates.keyValues.entrySet;
- val values = new ArrayList<Node<?>>(keyValues.size)
- for(keyValue : keyValues) {
- values.add(new SimpleNodeTOImpl(keyValue.key,null,keyValue.value))
- }
- return new CompositeNodeTOImpl(predicates.nodeType,null,values);
- }
-
- override serialize(InstanceIdentifier<?> input) {
- var Class<?> previousAugmentation = null
- val pathArgs = input.path as List<InstanceIdentifier.PathArgument>
- var QName previousQName = null;
- val components = new ArrayList<PathArgument>(pathArgs.size);
- val qnamePath = new ArrayList<QName>(pathArgs.size);
- for(baArg : pathArgs) {
-
- if(!Augmentation.isAssignableFrom(baArg.type)) {
- val biArg = serializePathArgument(baArg,previousQName);
- previousQName = biArg.nodeType;
- components.add(biArg);
- qnamePath.add(biArg.nodeType);
- val immutableList = ImmutableList.copyOf(qnamePath);
- codecRegistry.putPathToClass(immutableList,baArg.type);
- if(previousAugmentation !== null) {
- updateAugmentationInjection(baArg.type,immutableList,previousAugmentation)
- }
-
- previousAugmentation = null;
- } else {
- previousQName = codecRegistry.getQNameForAugmentation(baArg.type as Class<?>);
- previousAugmentation = baArg.type;
- }
- }
- val ret = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(components);
- LOG.debug("Binding Instance Identifier {} serialized to DOM InstanceIdentifier {}",input,ret);
- return ret;
- }
-
- def updateAugmentationInjection(Class<? extends DataObject> class1, ImmutableList<QName> list, Class<?> augmentation) {
- if(classToPreviousAugment.get(class1) == null) {
- classToPreviousAugment.put(class1,new ConcurrentHashMap());
- }
- classToPreviousAugment.get(class1).put(list,augmentation);
- }
-
- private def dispatch PathArgument serializePathArgument(Item<?> argument, QName previousQname) {
- val type = argument.type;
- val qname = BindingReflections.findQName(type);
- if(previousQname == null || (BindingReflections.isAugmentationChild(argument.type))) {
- return new NodeIdentifier(qname);
- }
- return new NodeIdentifier(QName.create(previousQname,qname.localName));
- }
-
- @SuppressWarnings("rawtypes")
- private def dispatch PathArgument serializePathArgument(IdentifiableItem argument, QName previousQname) {
- val Map<QName,Object> predicates = new HashMap();
- val type = argument.type;
- val keyCodec = codecRegistry.getIdentifierCodecForIdentifiable(type);
- var QName qname = BindingReflections.findQName(type);
- if(previousQname != null && !(BindingReflections.isAugmentationChild(argument.type))) {
- qname = QName.create(previousQname,qname.localName);
- }
- val combinedInput = new ValueWithQName(previousQname,argument.key)
- val compositeOutput = keyCodec.serialize(combinedInput as ValueWithQName);
- for(outputValue :compositeOutput.value) {
- predicates.put(outputValue.nodeType,outputValue.value);
- }
- if(previousQname == null) {
- return new NodeIdentifierWithPredicates(qname,predicates);
- }
- return new NodeIdentifierWithPredicates(qname,predicates);
- }
-}
--- /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.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
+
+@SuppressWarnings("unchecked")
+public class IntermediateMapping {
+
+ public static Node<? extends Object> toNode(final Map<? extends Object, ? extends Object> map) {
+ if ((map instanceof Node<?>)) {
+ return ((Node<?>) map);
+ }
+ 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);
+ }
+
+ 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 org.opendaylight.yangtools.yang.data.api.Node
-import java.util.Map
-import org.opendaylight.yangtools.yang.common.QName
-import java.util.List
-import java.util.ArrayList
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
-import com.google.common.base.Preconditions
-
-class IntermediateMapping {
-
-
-
- static def Node<?> toNode(Map<?,?> map) {
- if(map instanceof Node<?>) {
- return map as Node<?>;
- }
- val nodeMap = map as Map<QName,Object>;
- Preconditions.checkArgument(map.size == 1);
- val elem = nodeMap.entrySet.iterator.next;
- val qname = elem.key;
- val value = elem.value;
- toNodeImpl(qname, value);
- }
-
-
- static def dispatch Node<?> toNodeImpl(QName name, List<?> objects) {
- val values = new ArrayList<Node<?>>(objects.size);
- for (obj : objects) {
- if(obj instanceof Node<?>) {
- values.add(obj as Node<?>);
- } else if(obj instanceof Map<?,?>) {
- values.add(toNode(obj as Map<?,?>));
- }
- }
- return new CompositeNodeTOImpl(name, null, values);
- }
-
- static def dispatch Node<?> toNodeImpl(QName name, Map<QName, Object> object) {
- throw new UnsupportedOperationException("Unsupported node hierarchy.");
- }
-
- static def dispatch Node<?> toNodeImpl(QName name, Object object) {
- return new SimpleNodeTOImpl(name, null, object);
- }
-}
--- /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.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.util.concurrent.SettableFuture;
+
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Future;
+
+import javassist.ClassPool;
+
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Extension;
+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.impl.BindingGeneratorImpl;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.impl.LazyGeneratedCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext;
+import org.opendaylight.yangtools.sal.binding.generator.impl.SchemaLock;
+import org.opendaylight.yangtools.sal.binding.generator.impl.TransformerGenerator;
+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.RpcService;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.Node;
+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.ValueWithQName;
+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;
+
+public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaContextListener,
+ SchemaLock, AutoCloseable, SchemaContextHolder {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RuntimeGeneratedMappingServiceImpl.class);
+
+ private ClassPool pool;
+
+ @Extension
+ private TransformerGenerator binding;
+
+ @Extension
+ private LazyGeneratedCodecRegistry registry;
+
+ private final ConcurrentMap<Type, Type> typeDefinitions = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Type, Set<QName>> serviceTypeToRpc = new ConcurrentHashMap<>();
+ private final HashMultimap<Type, SettableFuture<Type>> promisedTypes = HashMultimap.create();
+ private final ClassLoadingStrategy classLoadingStrategy;
+ private SchemaContext schemaContext;
+
+ public RuntimeGeneratedMappingServiceImpl() {
+ this(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy());
+ }
+
+ public RuntimeGeneratedMappingServiceImpl(ClassLoadingStrategy strat) {
+ classLoadingStrategy = strat;
+ }
+
+ public ClassPool getPool() {
+ return this.pool;
+ }
+
+ public void setPool(final ClassPool pool) {
+ this.pool = pool;
+ }
+
+ @Override
+ public SchemaContext getSchemaContext() {
+ return schemaContext;
+ }
+
+ public void setSchemaContext(final SchemaContext schemaContext) {
+ this.schemaContext = schemaContext;
+ }
+
+ public TransformerGenerator getBinding() {
+ return this.binding;
+ }
+
+ public void setBinding(final TransformerGenerator binding) {
+ this.binding = binding;
+ }
+
+ public LazyGeneratedCodecRegistry getRegistry() {
+ return registry;
+ }
+
+ public void setRegistry(final LazyGeneratedCodecRegistry registry) {
+ this.registry = registry;
+ }
+
+ public ConcurrentMap<Type, GeneratedTypeBuilder> getTypeToDefinition() {
+ return typeToDefinition;
+ }
+
+ public ConcurrentMap<Type, Type> getTypeDefinitions() {
+ return typeDefinitions;
+ }
+
+ public ConcurrentMap<Type, SchemaNode> getTypeToSchemaNode() {
+ return typeToSchemaNode;
+ }
+
+ public ConcurrentMap<Type, Set<QName>> getServiceTypeToRpc() {
+ return serviceTypeToRpc;
+ }
+
+ @Override
+ public void onGlobalContextUpdated(final SchemaContext arg0) {
+ this.setSchemaContext(arg0);
+ this.recreateBindingContext(arg0);
+ LazyGeneratedCodecRegistry _registry = this.getRegistry();
+ _registry.onGlobalContextUpdated(arg0);
+ }
+
+ private void recreateBindingContext(SchemaContext schemaContext) {
+ BindingGeneratorImpl newBinding = new BindingGeneratorImpl();
+ newBinding.generateTypes(schemaContext);
+
+ for (Map.Entry<Module, ModuleContext> entry : newBinding.getModuleContexts().entrySet()) {
+
+ registry.onModuleContextAdded(schemaContext, entry.getKey(), entry.getValue());
+ binding.getPathToType().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);
+ }
+
+ 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());
+ binding.getTypeDefinitions().put(typeRef, value);
+ TypeDefinition<?> schemaNode = YangSchemaUtils.findTypeDefinition(schemaContext, typedef.getKey());
+ if (schemaNode != null) {
+
+ binding.getTypeToSchemaNode().put(typeRef, schemaNode);
+ } else {
+ LOG.error("Type definition for {} is not available", value);
+ }
+ }
+ List<GeneratedTypeBuilder> augmentations = context.getAugmentations();
+ for (GeneratedTypeBuilder augmentation : augmentations) {
+ binding.getTypeToDefinition().put(augmentation, augmentation);
+ }
+ binding.getTypeToAugmentation().putAll(context.getTypeToAugmentation());
+ for (GeneratedTypeBuilder augmentation : augmentations) {
+ updatePromisedSchemas(augmentation);
+ }
+ }
+ }
+
+ public CompositeNode toDataDom(final DataObject data) {
+ return toCompositeNodeImpl(data);
+ }
+
+ @Override
+ public Entry<InstanceIdentifier, CompositeNode> toDataDom(
+ final Entry<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+ try {
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier 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.InstanceIdentifier, CompositeNode>(key,
+ data);
+
+ } catch (Exception e) {
+ LOG.error("Error during serialization for {}.", entry.getKey(), e);
+ throw e;
+ }
+ }
+
+ private CompositeNode toCompositeNodeImpl(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(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier,
+ DataObject object) {
+ PathArgument last = identifier.getPath().get(identifier.getPath().size() - 1);
+ 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(
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier, DataObject object) {
+
+ // val cls = object.implementedInterface;
+ // waitForSchema(cls);
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument last = identifier.getPath().get(
+ identifier.getPath().size() - 1);
+ 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.getChildren());
+ return new CompositeNodeTOImpl(last.getNodeType(), null, newNodes);
+ }
+ return ret;
+ }
+
+ @Override
+ public void waitForSchema(Class class1) {
+ if (registry.isCodecAvailable(class1)) {
+ return;
+ }
+ Type ref = Types.typeForClass(class1);
+ getSchemaWithRetry(ref);
+ }
+
+ public InstanceIdentifier toDataDom(
+ final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
+ for (final org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument arg : path.getPath()) {
+ this.waitForSchema(arg.getType());
+ }
+ return registry.getInstanceIdentifierCodec().serialize(path);
+ }
+
+ @Override
+ public DataObject dataObjectFromDataDom(
+ final org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path,
+ final CompositeNode node) {
+ return (DataObject) dataObjectFromDataDom(path.getTargetType(), node);
+ }
+
+ @Override
+ public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object> fromDataDom(
+ final InstanceIdentifier entry) {
+ try {
+ return tryDeserialization(new Callable<org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object>>() {
+ @Override
+ public org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends Object> call() {
+ return getRegistry().getInstanceIdentifierCodec().deserialize(entry);
+ }
+ });
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ @Override
+ public CodecRegistry getCodecRegistry() {
+ return this.getRegistry();
+ }
+
+ private static <T> T tryDeserialization(Callable<T> deserializationBlock) throws DeserializationException {
+ try {
+ return deserializationBlock.call();
+ } catch (Exception e) {
+ // FIXME: Make this block providing more information.
+ throw new DeserializationException(e);
+ }
+ }
+
+ private void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, 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());
+ }
+ }
+ }
+
+ public void init() {
+ binding = new TransformerGenerator(pool);
+ registry = new LazyGeneratedCodecRegistry(this, classLoadingStrategy);
+
+ registry.setGenerator(binding);
+ // binding.staticFieldsInitializer = registry
+ binding.setListener(registry);
+ binding.setTypeToDefinition(typeToDefinition);
+ binding.setTypeToSchemaNode(typeToSchemaNode);
+ binding.setTypeDefinitions(typeDefinitions);
+
+ // if (ctx !== null) {
+ // listenerRegistration = ctx.registerService(SchemaServiceListener,
+ // this, new Hashtable<String, String>());
+ // }
+ }
+
+ @Override
+ public Set<QName> getRpcQNamesFor(Class<? extends RpcService> service) {
+ Set<QName> serviceRef = serviceTypeToRpc.get(new ReferencedTypeImpl(service.getPackage().getName(), service
+ .getSimpleName()));
+ if (serviceRef == null) {
+ serviceRef = Collections.emptySet();
+ }
+ return serviceRef;
+ }
+
+ private void getSchemaWithRetry(Type type) {
+ try {
+ if (typeToDefinition.containsKey(type)) {
+ return;
+ }
+ LOG.info("Thread blocked waiting for schema for: {}", type.getFullyQualifiedName());
+ waitForTypeDefinition(type).get();
+ LOG.info("Schema for {} became available, thread unblocked", type.getFullyQualifiedName());
+ } catch (Throwable t) {
+ Exceptions.sneakyThrow(t);
+ }
+ }
+
+ private Future<Type> waitForTypeDefinition(final Type type) {
+ final SettableFuture<Type> future = SettableFuture.<Type> create();
+ promisedTypes.put(type, future);
+ return future;
+ }
+
+ private void updatePromisedSchemas(Type builder) {
+ Type ref = new ReferencedTypeImpl(builder.getPackageName(), builder.getName());
+ Set<SettableFuture<Type>> futures = promisedTypes.get(ref);
+ if (futures == null || futures.isEmpty()) {
+ return;
+ }
+ for (SettableFuture<Type> future : futures) {
+ future.set(builder);
+ }
+ promisedTypes.removeAll(builder);
+ }
+
+ @Override
+ public void close() throws Exception {
+ }
+
+ @Override
+ public DataContainer dataObjectFromDataDom(final Class<? extends DataContainer> container,
+ final CompositeNode domData) {
+ try {
+ return tryDeserialization(new Callable<DataObject>() {
+ @Override
+ public DataObject call() throws Exception {
+ if (Objects.equal(domData, null)) {
+ return null;
+ }
+ final DataContainerCodec<? extends DataContainer> transformer = getRegistry()
+ .getCodecForDataObject(container);
+ ValueWithQName<? extends DataContainer> deserialize = transformer.deserialize(domData);
+ DataContainer value = null;
+ if (deserialize != null) {
+ value = deserialize.getValue();
+ }
+ return ((DataObject) value);
+ }
+ });
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ @Override
+ public Optional<Class<? extends RpcService>> getRpcServiceClassFor(String namespace, String revision) {
+ Module module = null;
+ if (schemaContext != null) {
+ module = schemaContext.findModuleByName(namespace, QName.parseRevision(revision));
+ }
+ if (module == null) {
+ return Optional.absent();
+ }
+ try {
+ Optional<Type> rpcTypeName = getRpcServiceType(module);
+ if (rpcTypeName.isPresent()) {
+ Class<?> rpcClass = binding.getClassLoadingStrategy().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(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));
+ }
+
+}
+++ /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.collect.FluentIterable
-import com.google.common.collect.HashMultimap
-import com.google.common.util.concurrent.SettableFuture
-import java.util.AbstractMap.SimpleEntry
-import java.util.ArrayList
-import java.util.Collections
-import java.util.Map
-import java.util.Map.Entry
-import java.util.Set
-import java.util.concurrent.Callable
-import java.util.concurrent.ConcurrentHashMap
-import java.util.concurrent.ConcurrentMap
-import java.util.concurrent.Future
-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.GeneratedType
-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
-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.InstanceIdentifier.NodeIdentifierWithPredicates
-import org.opendaylight.yangtools.yang.data.api.Node
-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.DataContainerCodec
-import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException
-import org.opendaylight.yangtools.yang.data.impl.codec.ValueWithQName
-import org.opendaylight.yangtools.yang.model.api.Module
-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.util.SchemaContextUtil
-import org.slf4j.LoggerFactory
-
-class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaContextListener,
-SchemaLock, AutoCloseable, SchemaContextHolder {
-
- @Property
- ClassPool pool;
-
- private static val LOG = LoggerFactory.getLogger(RuntimeGeneratedMappingServiceImpl);
-
- @Property
- extension TransformerGenerator binding;
-
- @Property
- extension LazyGeneratedCodecRegistry registry;
-
- @Property
- val ConcurrentMap<Type, Type> typeDefinitions = new ConcurrentHashMap();
-
- @Property
- val ConcurrentMap<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
-
- @Property
- val ConcurrentMap<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
-
- @Property
- val ConcurrentMap<Type, Set<QName>> serviceTypeToRpc = new ConcurrentHashMap();
-
- val promisedTypes = HashMultimap.<Type, SettableFuture<Type>>create;
-
- val ClassLoadingStrategy classLoadingStrategy;
-
- @Property
- var SchemaContext schemaContext;
-
- new() {
- this(GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy())
- }
-
- new(ClassLoadingStrategy strat){
- classLoadingStrategy = strat
- }
-
- //ServiceRegistration<SchemaServiceListener> listenerRegistration
- override onGlobalContextUpdated(SchemaContext arg0) {
- schemaContext = arg0
- recreateBindingContext(arg0);
- registry.onGlobalContextUpdated(arg0);
- }
-
- def recreateBindingContext(SchemaContext schemaContext) {
- val newBinding = new BindingGeneratorImpl();
- newBinding.generateTypes(schemaContext);
-
- for (entry : newBinding.moduleContexts.entrySet) {
-
- registry.onModuleContextAdded(schemaContext, entry.key, entry.value);
- binding.pathToType.putAll(entry.value.childNodes)
- val module = entry.key;
- val context = entry.value;
- updateBindingFor(context.childNodes, schemaContext);
- updateBindingFor(context.cases, schemaContext);
- val namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
-
- if (!module.rpcs.empty) {
- val rpcs = FluentIterable.from(module.rpcs).transform[QName].toSet
- val serviceClass = new ReferencedTypeImpl(namespace,
- BindingGeneratorUtil.parseToClassName(module.name) + "Service");
- serviceTypeToRpc.put(serviceClass, rpcs);
- }
-
- val typedefs = context.typedefs;
- for (typedef : typedefs.entrySet) {
- val typeRef = new ReferencedTypeImpl(typedef.value.packageName, typedef.value.name)
- binding.typeDefinitions.put(typeRef, typedef.value as GeneratedType);
- val schemaNode = YangSchemaUtils.findTypeDefinition(schemaContext, typedef.key);
- if (schemaNode != null) {
-
- binding.typeToSchemaNode.put(typeRef, schemaNode);
- } else {
- LOG.error("Type definition for {} is not available", typedef.value);
- }
-
- }
- val augmentations = context.augmentations;
- for (augmentation : augmentations) {
- binding.typeToDefinition.put(augmentation, augmentation);
- }
- binding.typeToAugmentation.putAll(context.typeToAugmentation);
- for (augmentation : augmentations) {
- updatePromisedSchemas(augmentation);
- }
- }
- }
-
- override CompositeNode toDataDom(DataObject data) {
- toCompositeNodeImpl(data);
- }
-
- override Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
- Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry) {
-
- try {
- val key = toDataDom(entry.key)
- var CompositeNode data;
- if (Augmentation.isAssignableFrom(entry.key.targetType)) {
- data = toCompositeNodeImplAugument(key, entry.value);
- } else {
- data = toCompositeNodeImpl(key, entry.value);
- }
- return new SimpleEntry(key, data);
-
- } catch (Exception e) {
- LOG.error("Error during serialization for {}.", entry.key, e);
- throw e;
- }
- }
-
- private def CompositeNode toCompositeNodeImpl(DataObject object) {
- val cls = object.implementedInterface;
- waitForSchema(cls);
- val codec = registry.getCodecForDataObject(cls) as DataContainerCodec<DataObject>;
- val ret = codec.serialize(new ValueWithQName(null, object));
- return ret as CompositeNode;
- }
-
- private def CompositeNode toCompositeNodeImpl(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier,
- DataObject object) {
- val last = identifier.path.last;
- val cls = object.implementedInterface;
- waitForSchema(cls);
- val codec = registry.getCodecForDataObject(cls) as DataContainerCodec<DataObject>;
- val ret = codec.serialize(new ValueWithQName(last.nodeType, object));
- return ret as CompositeNode;
- }
-
- private def CompositeNode toCompositeNodeImplAugument(
- org.opendaylight.yangtools.yang.data.api.InstanceIdentifier identifier, DataObject object) {
-
- //val cls = object.implementedInterface;
- //waitForSchema(cls);
- val last = identifier.path.last;
- val codec = registry.getCodecForAugmentation(object.implementedInterface as Class) as AugmentationCodec;
- val ret = codec.serialize(new ValueWithQName(last.nodeType, object));
- if (last instanceof NodeIdentifierWithPredicates) {
- val predicates = last as NodeIdentifierWithPredicates;
- val newNodes = new ArrayList<Node<?>>(predicates.keyValues.size);
- for (predicate : predicates.keyValues.entrySet) {
- newNodes.add(new SimpleNodeTOImpl(predicate.key, null, predicate.value));
- }
- newNodes.addAll(ret.children);
- return new CompositeNodeTOImpl(last.nodeType, null, newNodes);
- }
- return ret as CompositeNode;
- }
-
- override waitForSchema(Class class1) {
-
- if (registry.isCodecAvailable(class1)) {
- return;
- }
- val ref = Types.typeForClass(class1);
- getSchemaWithRetry(ref);
- }
-
- override org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
- InstanceIdentifier<? extends DataObject> path) {
- for (arg : path.path) {
- waitForSchema(arg.type);
- }
- return registry.instanceIdentifierCodec.serialize(path);
- }
-
- override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode node) {
- dataObjectFromDataDom(path.targetType, node) as DataObject;
- }
-
- override fromDataDom(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry) {
- return tryDeserialization[ |
- registry.instanceIdentifierCodec.deserialize(entry);
- ]
- }
-
- override getCodecRegistry() {
- return getRegistry();
- }
-
- private static def <T> T tryDeserialization(Callable<T> deserializationBlock) throws DeserializationException {
- try {
- deserializationBlock.call()
- } catch (Exception e) {
-
- // FIXME: Make this block providing more information.
- throw new DeserializationException(e);
- }
- }
-
- private def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
-
- for (entry : map.entrySet) {
- val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
-
- //LOG.info("{} : {}",entry.key,entry.value.fullyQualifiedName)
- val typeRef = new ReferencedTypeImpl(entry.value.packageName, entry.value.name)
- typeToDefinition.put(typeRef, entry.value);
- if (schemaNode != null) {
- typeToSchemaNode.put(typeRef, schemaNode);
- updatePromisedSchemas(entry.value);
- }
-
- }
- }
-
- public def void init() {
- binding = new TransformerGenerator(pool);
- registry = new LazyGeneratedCodecRegistry(this, classLoadingStrategy)
-
- registry.generator = binding
-
- //binding.staticFieldsInitializer = registry
- binding.listener = registry
- binding.typeToDefinition = typeToDefinition
- binding.typeToSchemaNode = typeToSchemaNode
- binding.typeDefinitions = typeDefinitions
-
- // if (ctx !== null) {
- // listenerRegistration = ctx.registerService(SchemaServiceListener, this, new Hashtable<String, String>());
- // }
- }
-
- override getRpcQNamesFor(Class<? extends RpcService> service) {
- var serviceRef = serviceTypeToRpc.get(new ReferencedTypeImpl(service.package.name, service.simpleName))
- if (serviceRef == null) {
- serviceRef = Collections.emptySet()
- }
- return serviceRef
- }
-
- private def void getSchemaWithRetry(Type type) {
- if (typeToDefinition.containsKey(type)) {
- return;
- }
- LOG.info("Thread blocked waiting for schema for: {}", type.fullyQualifiedName)
- type.waitForTypeDefinition.get();
- LOG.info("Schema for {} became available, thread unblocked", type.fullyQualifiedName)
- }
-
- private def Future<Type> waitForTypeDefinition(Type type) {
- val future = SettableFuture.<Type>create()
- promisedTypes.put(type, future);
- return future;
- }
-
- private def void updatePromisedSchemas(Type builder) {
- val ref = new ReferencedTypeImpl(builder.packageName, builder.name);
- val futures = promisedTypes.get(ref);
- if (futures === null || futures.empty) {
- return;
- }
- for (future : futures) {
- future.set(builder);
- }
- promisedTypes.removeAll(builder);
- }
-
- override close() throws Exception {
- //listenerRegistration?.unregister();
- }
-
- override dataObjectFromDataDom(Class<? extends DataContainer> container, CompositeNode domData) {
- return tryDeserialization[ |
- if (domData == null) {
- return null;
- }
- val transformer = registry.getCodecForDataObject(container);
- val ret = transformer.deserialize(domData)?.value as DataObject;
- return ret;
- ]
- }
-
- override getRpcServiceClassFor(String namespace, String revision) {
- val module = schemaContext?.findModuleByName(namespace.toString, QName.parseRevision(revision));
- if (module == null) {
- return Optional.absent();
- }
- try {
- val rpcTypeName = module.rpcServiceType;
- if (rpcTypeName.present) {
- val rpcClass = binding.classLoadingStrategy.loadClass(rpcTypeName.get.fullyQualifiedName);
- return Optional.of(rpcClass as Class<? extends RpcService>);
- }
- } catch (Exception e) {
- LOG.debug("RPC class not present for {},{}", namespace, revision, e);
- }
- return Optional.absent()
- }
-
- def Optional<Type> getRpcServiceType(Module module) {
- val namespace = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
- if (module.rpcs.empty) {
- return Optional.<Type>absent();
- }
- return Optional.<Type>of(
- new ReferencedTypeImpl(namespace,
- BindingMapping.getClassName(module.name) + BindingMapping.RPC_SERVICE_SUFFIX));
- }
-}
--- /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.util;
+
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.ClassPool;
+
+import java.util.Arrays;
+
+import javassist.ClassPath;
+import javassist.CtField;
+import javassist.Modifier;
+import javassist.NotFoundException;
+import javassist.LoaderClassPath;
+import javassist.ClassClassPath;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.xtext.xbase.lib.Conversions;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.Collections;
+
+public class JavassistUtils {
+
+ private static final Logger LOG = LoggerFactory.getLogger(JavassistUtils.class);
+
+ private final Map<ClassLoader, LoaderClassPath> loaderClassPaths = Collections
+ .synchronizedMap(new WeakHashMap<ClassLoader, LoaderClassPath>());
+ private ClassPool classPool;
+ private final Lock lock = new ReentrantLock();
+
+ public JavassistUtils(ClassPool pool) {
+ classPool = pool;
+ }
+
+ public Lock getLock() {
+ return lock;
+ }
+
+ public void method(final CtClass it, final Class<? extends Object> returnType, final String name,
+ final Class<? extends Object> parameter, final MethodGenerator function1) {
+ try {
+ List<CtClass> _asList = Arrays.<CtClass> asList(asCtClass(parameter));
+ CtMethod _ctMethod = new CtMethod(asCtClass(returnType), name, ((CtClass[]) Conversions.unwrapArray(
+ _asList, CtClass.class)), it);
+ final CtMethod method = _ctMethod;
+ function1.process(method);
+ it.addMethod(method);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public void method(final CtClass it, final Class<? extends Object> returnType, final String name,
+ final Class<? extends Object> parameter1, final Class<? extends Object> parameter2,
+ final MethodGenerator function1) {
+ try {
+ List<CtClass> _asList = Arrays.<CtClass> asList(asCtClass(parameter1), asCtClass(parameter2));
+ CtMethod method = new CtMethod(asCtClass(returnType), name, ((CtClass[]) Conversions.unwrapArray(_asList,
+ CtClass.class)), it);
+ function1.process(method);
+ it.addMethod(method);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public void staticMethod(final CtClass it, final Class<? extends Object> returnType, final String name,
+ final Class<? extends Object> parameter, final MethodGenerator function1) {
+ try {
+ List<CtClass> _asList = Arrays.<CtClass> asList(asCtClass(parameter));
+ CtMethod _ctMethod = new CtMethod(asCtClass(returnType), name, ((CtClass[]) Conversions.unwrapArray(
+ _asList, CtClass.class)), it);
+ final CtMethod method = _ctMethod;
+ function1.process(method);
+ it.addMethod(method);
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
+ try {
+ for (CtMethod method : source.getMethods()) {
+ if (method.getDeclaringClass() == source) {
+ CtMethod redeclaredMethod = new CtMethod(method, target, null);
+ function1.process(redeclaredMethod);
+ target.addMethod(redeclaredMethod);
+ }
+ }
+ } catch (Throwable t) {
+ Exceptions.sneakyThrow(t);
+ }
+ }
+
+ public CtClass createClass(String fqn, ClassGenerator cls) {
+ CtClass target = classPool.makeClass(fqn);
+ cls.process(target);
+ return target;
+ }
+
+ public CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
+ CtClass target = classPool.makeClass(fqn);
+ implementsType(target, superInterface);
+ cls.process(target);
+ return target;
+ }
+
+ public void implementsType(final CtClass it, final CtClass supertype) {
+ Preconditions.checkArgument(supertype.isInterface(), "Supertype must be interface");
+ it.addInterface(supertype);
+ }
+
+ public CtClass asCtClass(final Class<? extends Object> class1) {
+ return get(this.classPool, class1);
+ }
+
+ public CtField field(final CtClass it, final String name, final Class<? extends Object> returnValue) {
+ try {
+ final CtField field = new CtField(asCtClass(returnValue), name, it);
+ field.setModifiers(Modifier.PUBLIC);
+ it.addField(field);
+ return field;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public CtField staticField(final CtClass it, final String name, final Class<? extends Object> returnValue) {
+ try {
+ final CtField field = new CtField(asCtClass(returnValue), name, it);
+ field.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
+ it.addField(field);
+ return field;
+ } catch (Throwable _e) {
+ throw Exceptions.sneakyThrow(_e);
+ }
+ }
+
+ public CtClass get(final ClassPool pool, final Class<? extends Object> cls) {
+ try {
+ return pool.get(cls.getName());
+ } catch (NotFoundException nfe1) {
+ appendClassLoaderIfMissing(cls.getClassLoader());
+ try {
+ return pool.get(cls.getName());
+ } catch (final NotFoundException nfe2) {
+ LOG.warn("Appending ClassClassPath for {}", cls);
+ pool.appendClassPath(new ClassClassPath(cls));
+ try {
+ return pool.get(cls.getName());
+ } catch (Throwable t) {
+ throw Exceptions.sneakyThrow(t);
+ }
+ } catch (Throwable t1) {
+ Exceptions.sneakyThrow(t1);
+ return null;
+ }
+ } catch (Throwable t) {
+ Exceptions.sneakyThrow(t);
+ return null;
+ }
+ }
+
+ public void appendClassLoaderIfMissing(ClassLoader loader) {
+ if (loaderClassPaths.containsKey(loader)) {
+ return;
+ }
+ ClassPath ctLoader = new LoaderClassPath(loader);
+ classPool.appendClassPath(ctLoader);
+ }
+
+ public void ensureClassLoader(Class<?> child) {
+ appendClassLoaderIfMissing(child.getClassLoader());
+ }
+}
+++ /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.util
-
-import javassist.CtClass
-import javassist.CtMethod
-import javassist.ClassPool
-import java.util.Arrays
-import static com.google.common.base.Preconditions.*;
-import javassist.CtField
-import javassist.Modifier
-import javassist.NotFoundException
-import javassist.LoaderClassPath
-import javassist.ClassClassPath
-import java.util.concurrent.locks.Lock
-import java.util.concurrent.locks.ReentrantLock
-import org.slf4j.LoggerFactory
-import java.util.WeakHashMap
-import java.util.Collections
-
-class JavassistUtils {
-
- private static val LOG = LoggerFactory.getLogger(JavassistUtils);
-
- private val loaderClassPaths = Collections.synchronizedMap(new WeakHashMap<ClassLoader,LoaderClassPath>());
-
- ClassPool classPool
-
- @Property
- val Lock lock = new ReentrantLock();
-
- new(ClassPool pool) {
- classPool = pool;
- }
-
- def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
- val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
- function1.process(method);
- it.addMethod(method);
- }
-
- def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter1, Class<?> parameter2, MethodGenerator function1) {
- val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter1.asCtClass,parameter2.asCtClass), it);
- function1.process(method);
- it.addMethod(method);
- }
-
-
- def void staticMethod(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
- val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
- function1.process(method);
- it.addMethod(method);
- }
-
- def void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
- for (method : source.methods) {
- if (method.declaringClass == source) {
- val redeclaredMethod = new CtMethod(method, target, null);
- function1.process(redeclaredMethod);
- target.addMethod(redeclaredMethod);
- }
- }
- }
-
- def CtClass createClass(String fqn, ClassGenerator cls) {
-
- val target = classPool.makeClass(fqn);
- cls.process(target);
- return target;
- }
-
- def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
-
- val target = classPool.makeClass(fqn);
- target.implementsType(superInterface);
- cls.process(target);
- return target;
- }
-
- def void implementsType(CtClass it, CtClass supertype) {
- checkArgument(supertype.interface, "Supertype must be interface");
- addInterface(supertype);
- }
-
- def asCtClass(Class<?> class1) {
- classPool.get(class1);
- }
-
- def CtField field(CtClass it, String name, Class<?> returnValue) {
- val field = new CtField(returnValue.asCtClass, name, it);
- field.modifiers = Modifier.PUBLIC
- addField(field);
- return field;
- }
-
- def CtField staticField(CtClass it, String name, Class<?> returnValue) {
- val field = new CtField(returnValue.asCtClass, name, it);
- field.modifiers = Modifier.PUBLIC + Modifier.STATIC
- addField(field);
- return field;
- }
-
- def get(ClassPool pool, Class<?> cls) {
- try {
- return pool.get(cls.name)
- } catch (NotFoundException e) {
- appendClassLoaderIfMissing(cls.classLoader)
- try {
- return pool.get(cls.name)
- } catch (NotFoundException ef) {
- LOG.warn("Appending ClassClassPath for {}",cls);
- pool.appendClassPath(new ClassClassPath(cls));
-
- return pool.get(cls.name)
- }
- }
- }
-
- def void appendClassLoaderIfMissing(ClassLoader loader) {
- if(loaderClassPaths.containsKey(loader)) {
- return;
- }
- val ctLoader = new LoaderClassPath(loader);
- classPool.appendClassPath(ctLoader);
- }
-
- def void ensureClassLoader(Class<?> child) {
- appendClassLoaderIfMissing(child.classLoader);
- }
-}