2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory;
11 import static java.lang.String.format;
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;
35 public class AbsFactoryGeneratedObjectFactory {
36 private static final String BUNDLE_CONTEXT = "org.osgi.framework.BundleContext";
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());
43 AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe);
44 Optional<String> header = abstractFactoryTemplate.getHeaderString();
46 List<FullyQualifiedName> providedServices = new ArrayList<>();
47 for(String providedService: mbe.getProvidedServices().keySet()) {
48 providedServices.add(FullyQualifiedName.fromString(providedService));
51 return toGeneratedObject(absFactoryFQN, copyright,
52 header, classJavaDoc, mbe.getYangModuleQName(),
53 mbe.getGloballyUniqueName(),
56 abstractFactoryTemplate.getFields());
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();
67 b.addImportFQN(new FullyQualifiedName(Module.class));
68 b.addImportFQN(new FullyQualifiedName(ModuleIdentifier.class));
70 Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName);
71 b.addClassAnnotation(moduleQNameAnnotation);
73 b.setFqn(absFactoryFQN);
74 b.setTypeName(TypeName.absClassType);
76 b.setCopyright(copyright);
78 b.setClassJavaDoc(classJavaDoc);
79 b.addImplementsFQN(new FullyQualifiedName(ModuleFactory.class));
80 if (classJavaDoc.isPresent()) {
81 b.addClassAnnotation(format("@%s(value=\"%s\")", Description.class.getCanonicalName(), classJavaDoc.get()));
84 b.addToBody(format("public static final java.lang.String NAME = \"%s\";", globallyUniqueName));
85 b.addToBody(format("private static final java.util.Set<Class<? extends %s>> serviceIfcs;",
86 AbstractServiceInterface.class.getCanonicalName()));
88 b.addToBody("@Override\n public final String getImplementationName() { \n return NAME; \n}");
90 b.addToBody(getServiceIfcsInitialization(providedServices));
93 b.addToBody(format("\n"+
95 "public %s createModule(String instanceName, %s dependencyResolver, %s bundleContext) {\n"+
96 "return instantiateModule(instanceName, dependencyResolver, bundleContext);\n"+
98 Module.class.getCanonicalName(), DependencyResolver.class.getCanonicalName(), BUNDLE_CONTEXT));
100 b.addToBody(getCreateModule(moduleFQN, moduleFields));
102 b.addToBody(format("\n"+
103 "public %s instantiateModule(String instanceName, %s dependencyResolver, %s oldModule, %s oldInstance, %s bundleContext) {\n"+
104 "return new %s(new %s(NAME, instanceName), dependencyResolver, oldModule, oldInstance);\n"+
106 moduleFQN, DependencyResolver.class.getCanonicalName(), moduleFQN, AutoCloseable.class.getCanonicalName(),
107 BUNDLE_CONTEXT, moduleFQN, ModuleIdentifier.class.getCanonicalName()));
109 b.addToBody(format("\n"+
110 "public %s instantiateModule(String instanceName, %s dependencyResolver, %s bundleContext) {\n"+
111 "return new %s(new %s(NAME, instanceName), dependencyResolver);\n"+
112 "}\n", moduleFQN, DependencyResolver.class.getCanonicalName(), BUNDLE_CONTEXT,
113 moduleFQN, ModuleIdentifier.class.getCanonicalName()
116 b.addToBody(format("\n"+
117 "public %s handleChangedClass(%s dependencyResolver, %s old, %s bundleContext) throws Exception {\n" +
118 // "// @Deprecated return handleChangedClass(old);\n" +
119 "String instanceName = old.getModule().getIdentifier().getInstanceName();\n" +
120 "%1$s newModule = new %1$s(new ModuleIdentifier(NAME, instanceName), dependencyResolver);\n" +
121 "Module oldModule = old.getModule();\n" +
122 "Class<? extends Module> oldModuleClass = oldModule.getClass();\n" +
123 genCodeToCopyAttributes(moduleFields) +
124 "return newModule;\n" +
125 "}\n", moduleFQN, DependencyResolver.class.getCanonicalName(), DynamicMBeanWithInstance.class.getCanonicalName(), BUNDLE_CONTEXT));
127 b.addToBody(format("\n@Deprecated\n"+
128 "public %s handleChangedClass(%s old) throws Exception {\n"+
129 "throw new UnsupportedOperationException(\"Class reloading is not supported\");\n"+
130 "}\n", moduleFQN, DynamicMBeanWithInstance.class.getCanonicalName()));
132 b.addToBody(format("\n"+
134 "public java.util.Set<%s> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, %s bundleContext) {\n"+
135 "return new java.util.HashSet<>();\n"+
136 "}\n", moduleFQN, BUNDLE_CONTEXT));
138 return new GeneratedObjectBuilder(b.build()).toGeneratedObject();
141 private String genCodeToCopyAttributes(List<Field> moduleFields) {
142 StringBuilder sb = new StringBuilder("\n");
143 for (Field field : moduleFields) {
144 sb.append(format("newModule.set%1$s( (%2$s) oldModuleClass.getMethod(\"get%1$s\").invoke(oldModule));\n", field.getName(), field.getType()));
147 return sb.toString();
150 private static String getCreateModule(FullyQualifiedName moduleFQN, List<Field> moduleFields) {
151 StringBuilder result = new StringBuilder("\n" +
154 format("public %s createModule(String instanceName, %s dependencyResolver, %s old, %s bundleContext) "
155 + "throws Exception {\n",
156 Module.class.getCanonicalName(), DependencyResolver.class.getCanonicalName(),
157 DynamicMBeanWithInstance.class.getCanonicalName(), BUNDLE_CONTEXT))
158 .append(format("%s oldModule;\n", moduleFQN))
160 .append(format("oldModule = (%s) old.getModule();\n", moduleFQN))
161 .append("} catch(Exception e) {\n"
162 + "return handleChangedClass(dependencyResolver, old, bundleContext);\n"
164 .append(format("%s module = instantiateModule(instanceName, dependencyResolver, oldModule, old"
165 + ".getInstance(), bundleContext);\n",
168 for (Field field : moduleFields) {
169 result.append(format("module.set%s(oldModule.get%1$s());\n", field.getName()));
175 return result.toString();
178 private static String getServiceIfcsInitialization(List<FullyQualifiedName> providedServices) {
179 String generic = format("Class<? extends %s>", AbstractServiceInterface.class.getCanonicalName());
181 StringBuilder result = new StringBuilder("static {\n");
182 if (!providedServices.isEmpty()) {
183 result.append(format("java.util.Set<%1$s> serviceIfcs2 = new java.util.HashSet<>();\n", generic));
185 for (FullyQualifiedName fqn : providedServices) {
186 result.append(format("serviceIfcs2.add(%s.class);\n", fqn));
189 result.append("serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2);\n");
191 result.append("serviceIfcs = java.util.Collections.emptySet();\n");
193 result.append("}\n");
195 // add isModuleImplementingServiceInterface and getImplementedServiceIntefaces methods
197 result.append(format("\n"
199 + "public final boolean isModuleImplementingServiceInterface(Class<? extends %1$s> serviceInterface) "
201 + "for (Class<?> ifc: serviceIfcs) {\n"
202 + "if (serviceInterface.isAssignableFrom(ifc)){\n"
210 + "public java.util.Set<Class<? extends %1$s>> getImplementedServiceIntefaces() {\n"
211 + "return serviceIfcs;\n"
212 + "}\n", AbstractServiceInterface.class.getCanonicalName()));
214 return result.toString();