Extend AugmentableExtension to handle AugmentationHolder
[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.mdsal.binding.dom.codec.util.AugmentationReader;
16 import org.opendaylight.yangtools.yang.binding.Augmentable;
17 import org.opendaylight.yangtools.yang.binding.Augmentation;
18 import org.opendaylight.yangtools.yang.binding.AugmentationHolder;
19
20 /**
21  * Adds an {@link #getAugmentations(Augmentable)} method to {@link Augmentable}.
22  *
23  * <p>Note that the generated *Impl classes in the *Builder do not implement
24  * {@link AugmentationReader}, only the LazyDataObject (package local) does.
25  *
26  * @see Augmentable
27  * @see AugmentationReader
28  *
29  * @author Michael Vorburger
30  */
31 // package-local: no need to expose this, consider it an implementation detail; public API is the AssertDataObjects
32 // FIXME: 5.0.0: this is a duplication of BindingReflections.getAugmentations() ... but why?
33 class AugmentableExtension {
34
35     private static final ReflectExtensions REFLECT_EXTENSIONS = new ReflectExtensions();
36
37     public ClassToInstanceMap<Augmentation<?>> getAugmentations(final Augmentable<?> augmentable) {
38         if (augmentable instanceof AugmentationReader) {
39             AugmentationReader augmentationReader = (AugmentationReader) augmentable;
40             return ImmutableClassToInstanceMap.copyOf(augmentationReader.getAugmentations(augmentable));
41         } else if (augmentable instanceof AugmentationHolder) {
42             AugmentationHolder<?> augmentationHolder = (AugmentationHolder<?>) augmentable;
43             return ImmutableClassToInstanceMap.copyOf(augmentationHolder.augmentations());
44         } else if (Proxy.isProxyClass(augmentable.getClass())) {
45             InvocationHandler invocationHandler = Proxy.getInvocationHandler(augmentable);
46             // class LazyDataObject implements InvocationHandler, AugmentationReader
47             AugmentationReader augmentationReader = (AugmentationReader) invocationHandler;
48             return ImmutableClassToInstanceMap.copyOf(augmentationReader.getAugmentations(augmentable));
49         } else {
50             try {
51                 return ImmutableClassToInstanceMap.copyOf(REFLECT_EXTENSIONS.get(augmentable, "augmentation"));
52             } catch (ClassCastException | SecurityException | NoSuchFieldException | IllegalArgumentException
53                     | IllegalAccessException e) {
54                 throw new IllegalArgumentException("TODO Implement getAugmentations() for an Augmentable which "
55                         + "is neither a (Proxy of an) AugmentationReader nor has an internal field named "
56                         + "'augmentation': " + augmentable.getClass(), e);
57             }
58         }
59     }
60
61 }