New test utility AssertDataObjects
[mdsal.git] / binding / mdsal-binding-test-utils / src / main / java / org / opendaylight / mdsal / binding / testutils / AugmentableExtension.java
1 /*
2  * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.mdsal.binding.testutils;
9
10 import com.google.common.collect.ClassToInstanceMap;
11 import com.google.common.collect.ImmutableClassToInstanceMap;
12 import java.lang.reflect.InvocationHandler;
13 import java.lang.reflect.Proxy;
14 import org.eclipse.xtext.xbase.lib.util.ReflectExtensions;
15 import org.opendaylight.yangtools.binding.data.codec.util.AugmentationReader;
16 import org.opendaylight.yangtools.yang.binding.Augmentable;
17 import org.opendaylight.yangtools.yang.binding.Augmentation;
18
19 /**
20  * Adds an {@link #getAugmentations(Augmentable)} method to {@link Augmentable}.
21  *
22  * <p>Note that the generated *Impl classes in the *Builder do not implement
23  * {@link AugmentationReader}, only the LazyDataObject (package local) does.
24  *
25  * @see Augmentable
26  * @see AugmentationReader
27  *
28  * @author Michael Vorburger
29  */
30 //package-local: no need to expose this, consider it an implementation detail; public API is the AssertDataObjects
31 class AugmentableExtension {
32
33     private static final ReflectExtensions REFLECT_EXTENSIONS = new ReflectExtensions();
34
35     public ClassToInstanceMap<Augmentation<?>> getAugmentations(Augmentable<?> augmentable) {
36         if (augmentable instanceof AugmentationReader) {
37             AugmentationReader augmentationReader = (AugmentationReader) augmentable;
38             return ImmutableClassToInstanceMap.copyOf(augmentationReader.getAugmentations(augmentable));
39         } else if (Proxy.isProxyClass(augmentable.getClass())) {
40             InvocationHandler invocationHandler = Proxy.getInvocationHandler(augmentable);
41             // class LazyDataObject implements InvocationHandler, AugmentationReader
42             AugmentationReader augmentationReader = (AugmentationReader) invocationHandler;
43             return ImmutableClassToInstanceMap.copyOf(augmentationReader.getAugmentations(augmentable));
44         } else {
45             try {
46                 return ImmutableClassToInstanceMap.copyOf(REFLECT_EXTENSIONS.get(augmentable, "augmentation"));
47             } catch (ClassCastException | SecurityException | NoSuchFieldException | IllegalArgumentException
48                     | IllegalAccessException e) {
49                 throw new IllegalArgumentException("TODO Implement getAugmentations() for an Augmentable which "
50                         + "is neither a (Proxy of an) AugmentationReader nor has an internal field named "
51                         + "'augmentation': " + augmentable.getClass(), e);
52             }
53         }
54     }
55
56 }