93661699c4712debfc4cba9d4306e4a8e06e2913
[controller.git] / opendaylight / config / config-manager / src / test / java / org / opendaylight / controller / config / manager / impl / ClassBasedModuleFactory.java
1 /*
2  * Copyright (c) 2013, 2017 Cisco Systems, 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.controller.config.manager.impl;
9
10 import com.google.common.base.Preconditions;
11 import java.lang.reflect.Constructor;
12 import java.lang.reflect.InvocationTargetException;
13 import java.util.Arrays;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Set;
17 import org.opendaylight.controller.config.api.DependencyResolver;
18 import org.opendaylight.controller.config.api.DependencyResolverFactory;
19 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
20 import org.opendaylight.controller.config.api.ModuleIdentifier;
21 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
22 import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper;
23 import org.opendaylight.controller.config.spi.Module;
24 import org.opendaylight.controller.config.spi.ModuleFactory;
25 import org.osgi.framework.BundleContext;
26
27 /**
28  * Creates new modules by reflection. Provided class must have this constructor:
29  * ctor(DynamicMBeanWithInstance.class, ModuleIdentifier.class). When
30  * reconfiguring, both parameters will be non null. When creating new instance
31  * first parameter will be null.
32  *
33  */
34 public class ClassBasedModuleFactory implements ModuleFactory {
35     private final String implementationName;
36     private final Class<? extends Module> configBeanClass;
37
38     /**
39      * Module factory constructor.
40      *
41      * @param implementationName
42      *            name of the implementation
43      * @param configBeanClass
44      *            class that will be instantiated when createModule is called. This
45      *            class must implement Module interface and all exported interfaces.
46      */
47     public ClassBasedModuleFactory(final String implementationName, final Class<? extends Module> configBeanClass) {
48         this.implementationName = implementationName;
49         this.configBeanClass = configBeanClass;
50     }
51
52     @Override
53     public String getImplementationName() {
54         return implementationName;
55     }
56
57     @Override
58     public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
59             final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
60         Preconditions.checkNotNull(old);
61         return constructModule(instanceName, dependencyResolver, old);
62     }
63
64     @Override
65     public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
66             final BundleContext bundleContext) {
67         try {
68             return constructModule(instanceName, dependencyResolver, null);
69         } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
70             throw new RuntimeException(e);
71         }
72     }
73
74     private Module constructModule(final String instanceName, final DependencyResolver dependencyResolver,
75             final DynamicMBeanWithInstance old)
76             throws InstantiationException, IllegalAccessException, InvocationTargetException {
77         Preconditions.checkNotNull(dependencyResolver);
78         ModuleIdentifier moduleIdentifier = new ModuleIdentifier(implementationName, instanceName);
79         Constructor<? extends Module> declaredConstructor;
80         try {
81             declaredConstructor = configBeanClass.getDeclaredConstructor(DynamicMBeanWithInstance.class,
82                     ModuleIdentifier.class);
83         } catch (final NoSuchMethodException e) {
84             throw new IllegalStateException(
85                     "Did not find constructor with parameters (DynamicMBeanWithInstance) in " + configBeanClass, e);
86         }
87         Preconditions.checkState(declaredConstructor != null);
88         return declaredConstructor.newInstance(old, moduleIdentifier);
89     }
90
91     @Override
92     public boolean isModuleImplementingServiceInterface(
93             final Class<? extends AbstractServiceInterface> serviceInterface) {
94         Class<?>[] classes = configBeanClass.getInterfaces();
95         List<Class<?>> ifc = Arrays.asList(classes);
96         if (ifc.contains(serviceInterface)) {
97             return true;
98         }
99         for (Class<?> c : classes) {
100             ifc = Arrays.asList(c.getInterfaces());
101             if (ifc.contains(serviceInterface)) {
102                 return true;
103             }
104         }
105         return false;
106     }
107
108     @Override
109     public Set<Module> getDefaultModules(final DependencyResolverFactory dependencyResolverFactory,
110             final BundleContext bundleContext) {
111         return new HashSet<>();
112     }
113
114     @Override
115     public Set<Class<? extends AbstractServiceInterface>> getImplementedServiceIntefaces() {
116         return InterfacesHelper.getAllAbstractServiceClasses(configBeanClass);
117     }
118 }