import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSortedMap;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.SortedMap;
+import java.util.TreeMap;
import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
import org.opendaylight.yangtools.sal.binding.model.api.Type;
import org.opendaylight.yangtools.yang.binding.Augmentable;
abstract class DataObjectCodecContext<T extends DataNodeContainer> extends DataContainerCodecContext<T> {
private static final Logger LOG = LoggerFactory.getLogger(DataObjectCodecContext.class);
+ private static final Lookup LOOKUP = MethodHandles.publicLookup();
+ private static final MethodType CONSTRUCTOR_TYPE = MethodType.methodType(void.class, InvocationHandler.class);
+ private static final MethodType DATAOBJECT_TYPE = MethodType.methodType(DataObject.class, InvocationHandler.class);
+ private static final Comparator<Method> METHOD_BY_ALPHABET = new Comparator<Method>() {
+ @Override
+ public int compare(final Method o1, final Method o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ };
private final ImmutableMap<String, LeafNodeCodecContext> leafChild;
private final ImmutableMap<YangInstanceIdentifier.PathArgument, NodeContextSupplier> byYang;
- private final ImmutableMap<Method, NodeContextSupplier> byMethod;
+ private final ImmutableSortedMap<Method, NodeContextSupplier> byMethod;
private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byStreamClass;
private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClass;
- protected final Method augmentationGetter;
+ private final MethodHandle proxyConstructor;
+
+ // FIXME: this field seems to be unused
+ private final Method augmentationGetter;
protected DataObjectCodecContext(final DataContainerCodecPrototype<T> prototype) {
super(prototype);
Map<Class<?>, Method> clsToMethod = BindingReflections.getChildrenClassToMethod(bindingClass());
Map<YangInstanceIdentifier.PathArgument, NodeContextSupplier> byYangBuilder = new HashMap<>();
- Map<Method, NodeContextSupplier> byMethodBuilder = new HashMap<>();
+ SortedMap<Method, NodeContextSupplier> byMethodBuilder = new TreeMap<>(METHOD_BY_ALPHABET);
Map<Class<?>, DataContainerCodecPrototype<?>> byStreamClassBuilder = new HashMap<>();
Map<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClassBuilder = new HashMap<>();
}
}
}
- this.byMethod = ImmutableMap.copyOf(byMethodBuilder);
+ this.byMethod = ImmutableSortedMap.copyOfSorted(byMethodBuilder);
if (Augmentable.class.isAssignableFrom(bindingClass())) {
try {
augmentationGetter = bindingClass().getMethod("getAugmentation", Class.class);
this.byStreamClass = ImmutableMap.copyOf(byStreamClassBuilder);
byBindingArgClassBuilder.putAll(byStreamClass);
this.byBindingArgClass = ImmutableMap.copyOf(byBindingArgClassBuilder);
+
+ final Class<?> proxyClass = Proxy.getProxyClass(bindingClass().getClassLoader(), new Class[] { bindingClass() });
+ try {
+ proxyConstructor = LOOKUP.findConstructor(proxyClass, CONSTRUCTOR_TYPE).asType(DATAOBJECT_TYPE);
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new IllegalStateException("Failed to find contructor for class " + proxyClass);
+ }
}
@Override
return null;
}
+ protected final DataObject createBindingProxy(final NormalizedNodeContainer<?, ?, ?> node) {
+ try {
+ return (DataObject) proxyConstructor.invokeExact((InvocationHandler)new LazyDataObject(this, node));
+ } catch (Throwable e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
public Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAllAugmentationsFrom(
final NormalizedNodeContainer<?, PathArgument, NormalizedNode<?, ?>> data) {
return byMethod.keySet();
}
-}
\ No newline at end of file
+}