Merge "Added karaf branding."
[controller.git] / opendaylight / config / yang-jmx-generator-plugin / src / main / java / org / opendaylight / controller / config / yangjmxgenerator / plugin / gofactory / AbsFactoryGeneratedObjectFactory.java
1 /*
2  * Copyright (c) 2013 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
9 package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory;
10
11 import static java.lang.String.format;
12
13 import com.google.common.base.Optional;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.controller.config.api.DependencyResolver;
17 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
18 import org.opendaylight.controller.config.api.ModuleIdentifier;
19 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
20 import org.opendaylight.controller.config.api.annotations.Description;
21 import org.opendaylight.controller.config.spi.Module;
22 import org.opendaylight.controller.config.spi.ModuleFactory;
23 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
24 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractFactoryTemplate;
25 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory;
26 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation;
27 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field;
28 import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName;
29 import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject;
30 import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder;
31 import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder;
32 import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.TypeName;
33 import org.opendaylight.yangtools.yang.common.QName;
34
35 public class AbsFactoryGeneratedObjectFactory {
36     private static final String BUNDLE_CONTEXT = "org.osgi.framework.BundleContext";
37
38     public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional<String> copyright) {
39         FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractFactoryName());
40         FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getStubModuleName());
41         Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription());
42
43         AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe);
44         Optional<String> header = abstractFactoryTemplate.getHeaderString();
45
46         List<FullyQualifiedName> providedServices = new ArrayList<>();
47         for(String providedService: mbe.getProvidedServices().keySet()) {
48             providedServices.add(FullyQualifiedName.fromString(providedService));
49         }
50
51         return toGeneratedObject(absFactoryFQN, copyright,
52                 header, classJavaDoc, mbe.getYangModuleQName(),
53                 mbe.getGloballyUniqueName(),
54                 providedServices,
55                 moduleFQN,
56                 abstractFactoryTemplate.getFields());
57     }
58
59     public GeneratedObject toGeneratedObject(FullyQualifiedName absFactoryFQN, Optional<String> copyright,
60                                              Optional<String> header, Optional<String> classJavaDoc, QName yangModuleQName,
61                                              String globallyUniqueName,
62                                              List<FullyQualifiedName> providedServices,
63                                              FullyQualifiedName moduleFQN,
64                                              List<Field> moduleFields) {
65         JavaFileInputBuilder b = new JavaFileInputBuilder();
66         Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName);
67         b.addClassAnnotation(moduleQNameAnnotation);
68
69         b.setFqn(absFactoryFQN);
70         b.setTypeName(TypeName.absClassType);
71
72         b.setCopyright(copyright);
73         b.setHeader(header);
74         b.setClassJavaDoc(classJavaDoc);
75         b.addImplementsFQN(new FullyQualifiedName(ModuleFactory.class));
76         if (classJavaDoc.isPresent()) {
77             b.addClassAnnotation(format("@%s(value=\"%s\")", Description.class.getCanonicalName(), classJavaDoc.get()));
78         }
79
80         b.addToBody(format("public static final java.lang.String NAME = \"%s\";", globallyUniqueName));
81         b.addToBody(format("private static final java.util.Set<Class<? extends %s>> serviceIfcs;",
82                 AbstractServiceInterface.class.getCanonicalName()));
83
84         b.addToBody("@Override\n public final String getImplementationName() { \n return NAME; \n}");
85
86         b.addToBody(getServiceIfcsInitialization(providedServices));
87
88         // createModule
89         b.addToBody(format("\n"+
90             "@Override\n"+
91             "public %s createModule(String instanceName, %s dependencyResolver, %s bundleContext) {\n"+
92                 "return instantiateModule(instanceName, dependencyResolver, bundleContext);\n"+
93             "}\n",
94                 Module.class.getCanonicalName(), DependencyResolver.class.getCanonicalName(), BUNDLE_CONTEXT));
95
96         b.addToBody(getCreateModule(moduleFQN, moduleFields));
97
98         b.addToBody(format("\n"+
99             "public %s instantiateModule(String instanceName, %s dependencyResolver, %s oldModule, %s oldInstance, %s bundleContext) {\n"+
100                 "return new %s(new %s(NAME, instanceName), dependencyResolver, oldModule, oldInstance);\n"+
101             "}\n",
102                 moduleFQN, DependencyResolver.class.getCanonicalName(), moduleFQN, AutoCloseable.class.getCanonicalName(),
103                 BUNDLE_CONTEXT, moduleFQN, ModuleIdentifier.class.getCanonicalName()));
104
105         b.addToBody(format("\n"+
106             "public %s instantiateModule(String instanceName, %s dependencyResolver, %s bundleContext) {\n"+
107                 "return new %s(new %s(NAME, instanceName), dependencyResolver);\n"+
108             "}\n", moduleFQN, DependencyResolver.class.getCanonicalName(), BUNDLE_CONTEXT,
109                 moduleFQN, ModuleIdentifier.class.getCanonicalName()
110         ));
111
112         b.addToBody(format("\n"+
113             "public %s handleChangedClass(%s old) throws Exception {\n"+
114                 "throw new UnsupportedOperationException(\"Class reloading is not supported\");\n"+
115             "}\n", moduleFQN, DynamicMBeanWithInstance.class.getCanonicalName()));
116
117         b.addToBody(format("\n"+
118             "@Override\n"+
119             "public java.util.Set<%s> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, %s bundleContext) {\n"+
120                 "return new java.util.HashSet<%s>();\n"+
121             "}\n", moduleFQN, BUNDLE_CONTEXT, moduleFQN));
122
123         return new GeneratedObjectBuilder(b.build()).toGeneratedObject();
124     }
125
126     private static String getCreateModule(FullyQualifiedName moduleFQN, List<Field> moduleFields) {
127         String result = "\n"+
128             "@Override\n"+
129             format("public %s createModule(String instanceName, %s dependencyResolver, %s old, %s bundleContext) throws Exception {\n",
130                                 Module.class.getCanonicalName(), DependencyResolver.class.getCanonicalName(),
131                                 DynamicMBeanWithInstance.class.getCanonicalName(), BUNDLE_CONTEXT)+
132                 format("%s oldModule = null;\n",moduleFQN)+
133                 "try {\n"+
134                     format("oldModule = (%s) old.getModule();\n",moduleFQN)+
135                 "} catch(Exception e) {\n"+
136                     "return handleChangedClass(old);\n"+
137                 "}\n"+
138             format("%s module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);\n", moduleFQN);
139
140         for(Field field: moduleFields) {
141             result += format("module.set%s(oldModule.get%1$s());\n", field.getName());
142         }
143
144         result += "\n"+
145                 "return module;\n"+
146             "}\n";
147         return result;
148     }
149
150     private static String getServiceIfcsInitialization(List<FullyQualifiedName> providedServices) {
151         String generic = format("Class<? extends %s>", AbstractServiceInterface.class.getCanonicalName());
152
153         String result = format("static {\n"+
154             "java.util.Set<%1$s> serviceIfcs2 = new java.util.HashSet<%1$s>();\n", generic);
155
156         for(FullyQualifiedName fqn: providedServices) {
157             result += format("serviceIfcs2.add(%s.class);\n", fqn);
158         }
159         result += "serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2);\n"+
160             "}\n";
161
162         // add isModuleImplementingServiceInterface and getImplementedServiceIntefaces methods
163
164         result += format("\n"+
165             "@Override\n"+
166             "public final boolean isModuleImplementingServiceInterface(Class<? extends %1$s> serviceInterface) {\n"+
167                 "for (Class<?> ifc: serviceIfcs) {\n"+
168                     "if (serviceInterface.isAssignableFrom(ifc)){\n"+
169                         "return true;\n"+
170                     "}\n"+
171                 "}\n"+
172                 "return false;\n"+
173             "}\n"+
174             "\n"+
175             "@Override\n"+
176             "public java.util.Set<Class<? extends %1$s>> getImplementedServiceIntefaces() {\n"+
177                 "return serviceIfcs;\n"+
178             "}\n", AbstractServiceInterface.class.getCanonicalName());
179
180         return result;
181     }
182
183 }