3a6ff18081961b9c6c15b68cc53e45a3e01369e0
[controller.git] / opendaylight / config / yang-jmx-generator-plugin / src / main / java / org / opendaylight / controller / config / yangjmxgenerator / plugin / ftl / TemplateFactory.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 package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl;
9
10 import com.google.common.base.Function;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.Collections2;
13 import com.google.common.collect.Lists;
14 import com.google.common.collect.Maps;
15 import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
16 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
17 import org.opendaylight.controller.config.api.runtime.RuntimeBean;
18 import org.opendaylight.controller.config.spi.Module;
19 import org.opendaylight.controller.config.yangjmxgenerator.AbstractEntry;
20 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
21 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
22 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
23 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
24 import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute.Dependency;
25 import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute;
26 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
27 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
28 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute;
29 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
30 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
31 import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute;
32 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation;
33 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation.Parameter;
34 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Constructor;
35 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field;
36 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Header;
37 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDeclaration;
38 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition;
39 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField;
40 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper;
41 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
42 import org.opendaylight.yangtools.sal.binding.model.api.Type;
43
44 import javax.management.openmbean.SimpleType;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Collection;
48 import java.util.Collections;
49 import java.util.HashMap;
50 import java.util.List;
51 import java.util.Map;
52 import java.util.Map.Entry;
53
54 public class TemplateFactory {
55
56     public static Map<String, FtlTemplate> getFtlTemplates(
57             ModuleMXBeanEntry entry) {
58         Map<String, FtlTemplate> result = new HashMap<>();
59
60         result.putAll(TemplateFactory.tOsFromMbe(entry));
61
62         // IFC
63         result.put(entry.getMXBeanInterfaceName() + ".java",
64                 TemplateFactory.mXBeanInterfaceTemplateFromMbe(entry));
65
66         // ABS fact
67         result.put(entry.getAbstractFactoryName() + ".java",
68                 TemplateFactory.abstractFactoryTemplateFromMbe(entry));
69
70         // ABS module
71         result.put(entry.getAbstractModuleName() + ".java",
72                 TemplateFactory.abstractModuleTemplateFromMbe(entry));
73
74         return result;
75     }
76
77     public static Map<String, FtlTemplate> getFtlStubTemplates(
78             ModuleMXBeanEntry entry) {
79         Map<String, FtlTemplate> result = new HashMap<>();
80         // STUB fact
81         result.put(entry.getStubFactoryName() + ".java",
82                 TemplateFactory.stubFactoryTemplateFromMbe(entry));
83
84         result.put(entry.getStubModuleName() + ".java",
85                 TemplateFactory.stubModuleTemplateFromMbe(entry));
86         return result;
87     }
88
89     public static Map<String, FtlTemplate> getFtlTemplates(
90             ServiceInterfaceEntry entry) {
91
92         Map<String, FtlTemplate> result = new HashMap<>();
93         result.put(entry.getTypeName() + ".java",
94                 TemplateFactory.serviceInterfaceFromSie(entry));
95
96         return result;
97     }
98
99     /**
100      * Get map of file name as key, FtlFile instance representing runtime mx
101      * bean as value that should be persisted from this instance.
102      */
103     public static Map<String, FtlTemplate> getTOAndMXInterfaceFtlFiles(
104             RuntimeBeanEntry entry) {
105         Map<String, FtlTemplate> result = new HashMap<>();
106         { // create GeneralInterfaceFtlFile for runtime MXBean. Attributes will
107           // be transformed to getter methods
108             String mxBeanTypeName = entry.getJavaNameOfRuntimeMXBean();
109             List<String> extendedInterfaces = Arrays.asList(RuntimeBean.class
110                     .getCanonicalName());
111             List<MethodDeclaration> methods = new ArrayList<>();
112
113             // convert attributes to getters
114             for (AttributeIfc attributeIfc : entry.getAttributes()) {
115                 String returnType = null;
116                 returnType = getReturnType(entry, attributeIfc);
117                 String getterName = "get"
118                         + attributeIfc.getUpperCaseCammelCase();
119                 MethodDeclaration getter = new MethodDeclaration(returnType,
120                         getterName, Collections.<Field> emptyList());
121                 methods.add(getter);
122             }
123
124             // add rpc methods
125             for (Rpc rpc : entry.getRpcs()) {
126                 // convert JavaAttribute parameters into fields
127                 List<Field> fields = new ArrayList<>();
128                 for (JavaAttribute ja : rpc.getParameters()) {
129                     Field field = new Field(Collections.<String> emptyList(),
130                             ja.getType().getFullyQualifiedName(),
131                             ja.getLowerCaseCammelCase());
132                     fields.add(field);
133                 }
134                 MethodDeclaration operation = new MethodDeclaration(
135                         getReturnType(entry, rpc.getReturnType()), rpc.getName(), fields);
136                 methods.add(operation);
137             }
138
139             // FIXME header
140             GeneralInterfaceTemplate runtimeMxBeanIfc = new GeneralInterfaceTemplate(
141                     null, entry.getPackageName(), mxBeanTypeName,
142                     extendedInterfaces, methods);
143
144             result.put(runtimeMxBeanIfc.getTypeDeclaration().getName()
145                     + ".java", runtimeMxBeanIfc);
146         }
147
148         result.putAll(TemplateFactory.tOsFromRbe(entry));
149
150         return result;
151     }
152
153     private static String getReturnType(RuntimeBeanEntry entry, AttributeIfc attributeIfc) {
154         String returnType;
155         if (attributeIfc instanceof TypedAttribute) {
156             returnType = ((TypedAttribute) attributeIfc).getType()
157                     .getFullyQualifiedName();
158         } else if (attributeIfc instanceof TOAttribute) {
159             String fullyQualifiedName = FullyQualifiedNameHelper
160                     .getFullyQualifiedName(entry.getPackageName(),
161                             attributeIfc.getUpperCaseCammelCase());
162
163             returnType = fullyQualifiedName;
164         } else if (attributeIfc instanceof ListAttribute) {
165             AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
166                     .getInnerAttribute();
167
168             String innerTpe = innerAttr instanceof TypedAttribute ? ((TypedAttribute) innerAttr)
169                     .getType().getFullyQualifiedName()
170                     : FullyQualifiedNameHelper.getFullyQualifiedName(
171                             entry.getPackageName(),
172                             attributeIfc.getUpperCaseCammelCase());
173
174             returnType = "java.util.List<" + innerTpe + ">";
175         } else if (attributeIfc == VoidAttribute.getInstance()) {
176             return "void";
177         } else {
178             throw new UnsupportedOperationException(
179                     "Attribute not supported: "
180                             + attributeIfc.getClass());
181         }
182         return returnType;
183     }
184
185     public static GeneralInterfaceTemplate serviceInterfaceFromSie(
186             ServiceInterfaceEntry sie) {
187
188         List<String> extendedInterfaces = Lists
189                 .newArrayList(AbstractServiceInterface.class.getCanonicalName());
190         if (sie.getBase().isPresent()) {
191             extendedInterfaces.add(sie.getBase().get().getFullyQualifiedName());
192         }
193
194         // FIXME header
195         GeneralInterfaceTemplate sieTemplate = new GeneralInterfaceTemplate(
196                 getHeaderFromEntry(sie), sie.getPackageName(),
197                 sie.getTypeName(), extendedInterfaces,
198                 Lists.<MethodDeclaration> newArrayList());
199         sieTemplate.setJavadoc(sie.getNullableDescription());
200
201         if (sie.getNullableDescription() != null)
202             sieTemplate.getAnnotations().add(
203                     Annotation.createDescriptionAnnotation(sie
204                             .getNullableDescription()));
205         sieTemplate.getAnnotations().add(Annotation.createSieAnnotation(sie.getQName(), sie.getExportedOsgiClassName
206                 ()));
207
208         return sieTemplate;
209     }
210
211     public static AbstractFactoryTemplate abstractFactoryTemplateFromMbe(
212             ModuleMXBeanEntry mbe) {
213         AbstractFactoryAttributesProcessor attrProcessor = new AbstractFactoryAttributesProcessor();
214         attrProcessor.processAttributes(mbe.getAttributes(),
215                 mbe.getPackageName());
216
217         Collection<String> transformed = Collections2.transform(mbe
218                 .getProvidedServices().keySet(),
219                 new Function<String, String>() {
220
221                     @Override
222                     public String apply(String input) {
223                         return input + ".class";
224                     }
225                 });
226
227         return new AbstractFactoryTemplate(getHeaderFromEntry(mbe),
228                 mbe.getPackageName(), mbe.getAbstractFactoryName(),
229                 mbe.getGloballyUniqueName(), mbe.getFullyQualifiedName(mbe
230                         .getStubModuleName()), attrProcessor.getFields(),
231                 Lists.newArrayList(transformed));
232     }
233
234     public static AbstractModuleTemplate abstractModuleTemplateFromMbe(
235             ModuleMXBeanEntry mbe) {
236         AbstractModuleAttributesProcessor attrProcessor = new AbstractModuleAttributesProcessor();
237         attrProcessor.processAttributes(mbe.getAttributes(),
238                 mbe.getPackageName());
239
240         List<ModuleField> moduleFields = attrProcessor.getModuleFields();
241         List<String> implementedIfcs = Lists.newArrayList(
242                 Module.class.getCanonicalName(),
243                 mbe.getFullyQualifiedName(mbe.getMXBeanInterfaceName()));
244
245         for (String implementedService : mbe.getProvidedServices().keySet()) {
246             implementedIfcs.add(implementedService);
247         }
248
249         boolean generateRuntime = false;
250         String registratorFullyQualifiedName = null;
251         if (mbe.getRuntimeBeans() != null
252                 && mbe.getRuntimeBeans().isEmpty() == false) {
253             generateRuntime = true;
254             RuntimeBeanEntry rootEntry = RuntimeRegistratorFtlTemplate
255                     .findRoot(mbe.getRuntimeBeans());
256             registratorFullyQualifiedName = rootEntry
257                     .getPackageName()
258                     .concat(".")
259                     .concat(RuntimeRegistratorFtlTemplate.getJavaNameOfRuntimeRegistrator(rootEntry));
260             implementedIfcs.add(RuntimeBeanRegistratorAwareModule.class
261                     .getCanonicalName());
262         }
263
264         AbstractModuleTemplate abstractModuleTemplate = new AbstractModuleTemplate(
265                 getHeaderFromEntry(mbe), mbe.getPackageName(),
266                 mbe.getAbstractModuleName(), implementedIfcs, moduleFields,
267                 attrProcessor.getMethods(), generateRuntime,
268                 registratorFullyQualifiedName);
269
270         if (mbe.getNullableDescription() != null)
271             abstractModuleTemplate.getAnnotations().add(
272                     Annotation.createDescriptionAnnotation(mbe
273                             .getNullableDescription()));
274         return abstractModuleTemplate;
275     }
276
277     public static StubFactoryTemplate stubFactoryTemplateFromMbe(
278             ModuleMXBeanEntry mbe) {
279         return new StubFactoryTemplate(getHeaderFromEntry(mbe),
280                 mbe.getPackageName(), mbe.getStubFactoryName(),
281                 mbe.getFullyQualifiedName(mbe.getAbstractFactoryName()),
282                 mbe.getStubModuleName());
283     }
284
285     public static StubModuleTemplate stubModuleTemplateFromMbe(
286             ModuleMXBeanEntry mbe) {
287         return new StubModuleTemplate(getHeaderFromEntry(mbe),
288                 mbe.getPackageName(), mbe.getStubModuleName(),
289                 mbe.getFullyQualifiedName(mbe.getAbstractModuleName()));
290     }
291
292     public static GeneralInterfaceTemplate mXBeanInterfaceTemplateFromMbe(
293             ModuleMXBeanEntry mbe) {
294         MXBeanInterfaceAttributesProcessor attrProcessor = new MXBeanInterfaceAttributesProcessor();
295         attrProcessor.processAttributes(mbe.getAttributes(),
296                 mbe.getPackageName());
297         GeneralInterfaceTemplate ifcTemplate = new GeneralInterfaceTemplate(
298                 getHeaderFromEntry(mbe), mbe.getPackageName(),
299                 mbe.getMXBeanInterfaceName(), Lists.<String> newArrayList(),
300                 attrProcessor.getMethods());
301         ifcTemplate.setJavadoc(mbe.getNullableDescription());
302         return ifcTemplate;
303     }
304
305     public static Map<String, GeneralClassTemplate> tOsFromMbe(
306             ModuleMXBeanEntry mbe) {
307         Map<String, GeneralClassTemplate> retVal = Maps.newHashMap();
308         TOAttributesProcessor processor = new TOAttributesProcessor();
309         processor.processAttributes(mbe.getAttributes(), mbe.getPackageName());
310         for (org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor
311                 .getTOs()) {
312             List<Constructor> constructors = Lists.newArrayList();
313             constructors.add(new Constructor(to.getName(), "super();"));
314
315             Header header = getHeaderFromEntry(mbe);
316             retVal.put(
317                     to.getType(),
318                     new GeneralClassTemplate(header, mbe.getPackageName(), to
319                             .getName(), Collections.<String> emptyList(),
320                             Collections.<String> emptyList(), to.getFields(),
321                             to.getMethods(), false, false, constructors));
322         }
323         return retVal;
324     }
325
326     public static Map<String, GeneralClassTemplate> tOsFromRbe(
327             RuntimeBeanEntry rbe) {
328         Map<String, GeneralClassTemplate> retVal = Maps.newHashMap();
329         TOAttributesProcessor processor = new TOAttributesProcessor();
330         Map<String, AttributeIfc> yangPropertiesToTypesMap = Maps.newHashMap(rbe.getYangPropertiesToTypesMap());
331
332         // Add TOs from output parameters
333         for (Rpc rpc : rbe.getRpcs()) {
334             AttributeIfc returnType = rpc.getReturnType();
335
336             if (returnType == VoidAttribute.getInstance())
337                 continue;
338             if (returnType instanceof JavaAttribute)
339                 continue;
340             if (returnType instanceof ListAttribute && returnType.getOpenType() instanceof SimpleType)
341                 continue;
342
343             Preconditions.checkState(yangPropertiesToTypesMap.containsKey(returnType.getAttributeYangName()) == false,
344                     "Duplicate TO %s for %s", returnType.getAttributeYangName(), rbe);
345             yangPropertiesToTypesMap.put(returnType.getAttributeYangName(), returnType);
346         }
347
348         processor.processAttributes(yangPropertiesToTypesMap, rbe.getPackageName());
349         for (org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor
350                 .getTOs()) {
351             List<Constructor> constructors = Lists.newArrayList();
352             constructors.add(new Constructor(to.getName(), "super();"));
353
354             // TODO header
355             retVal.put(
356                     to.getType(),
357                     new GeneralClassTemplate(null, rbe.getPackageName(), to
358                             .getName(), Collections.<String> emptyList(),
359                             Collections.<String> emptyList(), to.getFields(),
360                             to.getMethods(), false, false, constructors));
361         }
362         return retVal;
363     }
364
365     private static Header getHeaderFromEntry(AbstractEntry mbe) {
366         return new Header(mbe.getYangModuleName(), mbe.getYangModuleLocalname());
367     }
368
369     // TODO refactor attribute processors
370
371     private static class TOAttributesProcessor {
372
373         private final List<TOInternal> tos = Lists.newArrayList();
374
375         void processAttributes(Map<String, AttributeIfc> attributes,
376                 String packageName) {
377             for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
378                 AttributeIfc attributeIfc = attrEntry.getValue();
379                 if (attributeIfc instanceof TOAttribute) {
380                     createTOInternal(packageName, attributeIfc);
381                 }
382                 if (attributeIfc instanceof ListAttribute) {
383                     AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
384                             .getInnerAttribute();
385                     if (innerAttr instanceof TOAttribute) {
386                         createTOInternal(packageName, innerAttr);
387                     }
388                 }
389             }
390         }
391
392         private void createTOInternal(String packageName,
393                 AttributeIfc attributeIfc) {
394             String fullyQualifiedName = FullyQualifiedNameHelper
395                     .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
396
397             String type = fullyQualifiedName;
398             String name = attributeIfc.getUpperCaseCammelCase();
399             Map<String, AttributeIfc> attrs = ((TOAttribute) attributeIfc)
400                     .getCapitalizedPropertiesToTypesMap();
401             // recursive processing
402             processAttributes(attrs, packageName);
403
404             tos.add(new TOInternal(type, name, attrs, packageName));
405         }
406
407         List<TOInternal> getTOs() {
408             return tos;
409         }
410
411         private static class TOInternal {
412             private final String type, name;
413             private List<Field> fields;
414             private List<MethodDefinition> methods;
415
416             public TOInternal(String type, String name,
417                     Map<String, AttributeIfc> attrs, String packageName) {
418                 super();
419                 this.type = type;
420                 this.name = name;
421                 processAttrs(attrs, packageName);
422             }
423
424             private void processAttrs(Map<String, AttributeIfc> attrs,
425                     String packageName) {
426                 fields = Lists.newArrayList();
427                 methods = Lists.newArrayList();
428
429                 for (Entry<String, AttributeIfc> attrEntry : attrs.entrySet()) {
430                     String innerName = attrEntry.getKey();
431                     String varName = BindingGeneratorUtil
432                             .parseToValidParamName(attrEntry.getKey());
433
434                     String fullyQualifiedName = null;
435                     if (attrEntry.getValue() instanceof TypedAttribute) {
436                         Type innerType = ((TypedAttribute) attrEntry.getValue())
437                                 .getType();
438                         fullyQualifiedName = innerType.getFullyQualifiedName();
439                     } else if (attrEntry.getValue() instanceof ListAttribute) {
440                         AttributeIfc innerAttr = ((ListAttribute) attrEntry
441                                 .getValue()).getInnerAttribute();
442
443                         String innerTpe = innerAttr instanceof TypedAttribute ? ((TypedAttribute) innerAttr)
444                                 .getType().getFullyQualifiedName()
445                                 : FullyQualifiedNameHelper
446                                         .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase());
447
448                         fullyQualifiedName = "java.util.List<" + innerTpe + ">";
449                     } else
450                         fullyQualifiedName = FullyQualifiedNameHelper
451                                 .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase());
452
453                     fields.add(new Field(fullyQualifiedName, varName));
454
455                     String getterName = "get" + innerName;
456                     MethodDefinition getter = new MethodDefinition(
457                             fullyQualifiedName, getterName,
458                             Collections.<Field> emptyList(), "return "
459                                     + varName + ";");
460
461                     String setterName = "set" + innerName;
462                     MethodDefinition setter = new MethodDefinition("void",
463                             setterName, Lists.newArrayList(new Field(
464                                     fullyQualifiedName, varName)), "this."
465                                     + varName + " = " + varName + ";");
466                     methods.add(getter);
467                     methods.add(setter);
468                 }
469
470             }
471
472             String getType() {
473                 return type;
474             }
475
476             String getName() {
477                 return name;
478             }
479
480             List<Field> getFields() {
481                 return fields;
482             }
483
484             List<MethodDefinition> getMethods() {
485                 return methods;
486             }
487         }
488     }
489
490     private static class MXBeanInterfaceAttributesProcessor {
491         private static final String STRING_FULLY_QUALIFIED_NAME = "java.util.List";
492         private final List<MethodDeclaration> methods = Lists.newArrayList();
493
494         void processAttributes(Map<String, AttributeIfc> attributes,
495                 String packageName) {
496             for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
497                 String returnType;
498                 AttributeIfc attributeIfc = attrEntry.getValue();
499
500                 if (attributeIfc instanceof TypedAttribute) {
501                     returnType = ((TypedAttribute) attributeIfc).getType()
502                             .getFullyQualifiedName();
503                 } else if (attributeIfc instanceof TOAttribute) {
504                     String fullyQualifiedName = FullyQualifiedNameHelper
505                             .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
506
507                     returnType = fullyQualifiedName;
508                 } else if (attributeIfc instanceof ListAttribute) {
509                     String fullyQualifiedName = null;
510
511                     AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
512                             .getInnerAttribute();
513                     if (innerAttr instanceof JavaAttribute) {
514                         fullyQualifiedName = ((JavaAttribute) innerAttr)
515                                 .getType().getFullyQualifiedName();
516                     } else if (innerAttr instanceof TOAttribute) {
517                         fullyQualifiedName = FullyQualifiedNameHelper
518                                 .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase());
519                     }
520
521                     returnType = STRING_FULLY_QUALIFIED_NAME.concat("<")
522                             .concat(fullyQualifiedName).concat(">");
523                 } else {
524                     throw new UnsupportedOperationException(
525                             "Attribute not supported: "
526                                     + attributeIfc.getClass());
527                 }
528
529                 String getterName = "get"
530                         + attributeIfc.getUpperCaseCammelCase();
531                 MethodDeclaration getter = new MethodDeclaration(returnType,
532                         getterName, Collections.<Field> emptyList());
533
534                 String varName = BindingGeneratorUtil
535                         .parseToValidParamName(attrEntry.getKey());
536                 String setterName = "set"
537                         + attributeIfc.getUpperCaseCammelCase();
538                 MethodDeclaration setter = new MethodDeclaration("void",
539                         setterName, Lists.newArrayList(new Field(returnType,
540                                 varName)));
541                 methods.add(getter);
542                 methods.add(setter);
543
544                 if (attributeIfc.getNullableDescription() != null) {
545                     setter.setJavadoc(attrEntry.getValue()
546                             .getNullableDescription());
547                 }
548             }
549         }
550
551         List<MethodDeclaration> getMethods() {
552             return methods;
553         }
554     }
555
556     private static class AbstractFactoryAttributesProcessor {
557
558         private final List<Field> fields = Lists.newArrayList();
559         private static final String STRING_FULLY_QUALIFIED_NAME = "java.util.List";
560
561         void processAttributes(Map<String, AttributeIfc> attributes,
562                 String packageName) {
563             for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
564                 String type;
565                 AttributeIfc attributeIfc = attrEntry.getValue();
566
567                 if (attributeIfc instanceof TypedAttribute) {
568                     type = ((TypedAttribute) attributeIfc).getType()
569                             .getFullyQualifiedName();
570                 } else if (attributeIfc instanceof TOAttribute) {
571                     String fullyQualifiedName = FullyQualifiedNameHelper
572                             .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
573
574                     type = fullyQualifiedName;
575                 } else if (attributeIfc instanceof ListAttribute) {
576                     String fullyQualifiedName = null;
577                     AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
578                             .getInnerAttribute();
579                     if (innerAttr instanceof JavaAttribute) {
580                         fullyQualifiedName = ((JavaAttribute) innerAttr)
581                                 .getType().getFullyQualifiedName();
582                     } else if (innerAttr instanceof TOAttribute) {
583                         fullyQualifiedName = FullyQualifiedNameHelper
584                                 .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase());
585                     }
586
587                     type = STRING_FULLY_QUALIFIED_NAME.concat("<")
588                             .concat(fullyQualifiedName).concat(">");
589
590                 } else {
591                     throw new UnsupportedOperationException(
592                             "Attribute not supported: "
593                                     + attributeIfc.getClass());
594                 }
595
596                 fields.add(new Field(type, attributeIfc
597                         .getUpperCaseCammelCase()));
598             }
599         }
600
601         List<Field> getFields() {
602             return fields;
603         }
604     }
605
606     private static class AbstractModuleAttributesProcessor {
607
608         private static final String STRING_FULLY_QUALIFIED_NAME = "java.util.List";
609
610         private final List<ModuleField> moduleFields = Lists.newArrayList();
611         private final List<MethodDefinition> methods = Lists.newArrayList();
612
613         void processAttributes(Map<String, AttributeIfc> attributes,
614                 String packageName) {
615             for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
616                 String type;
617                 AttributeIfc attributeIfc = attrEntry.getValue();
618
619                 if (attributeIfc instanceof TypedAttribute) {
620                     type = ((TypedAttribute) attributeIfc).getType()
621                             .getFullyQualifiedName();
622                 } else if (attributeIfc instanceof TOAttribute) {
623                     String fullyQualifiedName = FullyQualifiedNameHelper
624                             .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase());
625
626                     type = fullyQualifiedName;
627                 } else if (attributeIfc instanceof ListAttribute) {
628                     String fullyQualifiedName = null;
629                     AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
630                             .getInnerAttribute();
631                     if (innerAttr instanceof JavaAttribute) {
632                         fullyQualifiedName = ((JavaAttribute) innerAttr)
633                                 .getType().getFullyQualifiedName();
634                     } else if (innerAttr instanceof TOAttribute) {
635                         fullyQualifiedName = FullyQualifiedNameHelper
636                                 .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase());
637                     }
638
639                     type = STRING_FULLY_QUALIFIED_NAME.concat("<")
640                             .concat(fullyQualifiedName).concat(">");
641                 } else {
642                     throw new UnsupportedOperationException(
643                             "Attribute not supported: "
644                                     + attributeIfc.getClass());
645                 }
646
647                 boolean isDependency = false;
648                 Dependency dependency = null;
649                 Annotation overrideAnnotation = new Annotation("Override",
650                         Collections.<Parameter> emptyList());
651                 List<Annotation> annotations = Lists
652                         .newArrayList(overrideAnnotation);
653
654                 if (attributeIfc instanceof DependencyAttribute) {
655                     isDependency = true;
656                     dependency = ((DependencyAttribute) attributeIfc)
657                             .getDependency();
658                     annotations.add(Annotation
659                             .createRequireIfcAnnotation(dependency.getSie()));
660                 }
661
662                 String varName = BindingGeneratorUtil
663                         .parseToValidParamName(attrEntry.getKey());
664                 moduleFields.add(new ModuleField(type, varName, attributeIfc
665                         .getUpperCaseCammelCase(), attributeIfc
666                         .getNullableDefault(), isDependency, dependency));
667
668                 String getterName = "get"
669                         + attributeIfc.getUpperCaseCammelCase();
670                 MethodDefinition getter = new MethodDefinition(type,
671                         getterName, Collections.<Field> emptyList(),
672                         Lists.newArrayList(overrideAnnotation), "return "
673                                 + varName + ";");
674
675                 String setterName = "set"
676                         + attributeIfc.getUpperCaseCammelCase();
677
678                 if (attributeIfc.getNullableDescription() != null) {
679                     annotations.add(Annotation
680                             .createDescriptionAnnotation(attributeIfc.getNullableDescription()));
681                 }
682
683                 MethodDefinition setter = new MethodDefinition("void",
684                         setterName,
685                         Lists.newArrayList(new Field(type, varName)),
686                         annotations, "this." + varName + " = " + varName + ";");
687                 setter.setJavadoc(attributeIfc.getNullableDescription());
688
689                 methods.add(getter);
690                 methods.add(setter);
691             }
692         }
693
694         List<ModuleField> getModuleFields() {
695             return moduleFields;
696         }
697
698         List<MethodDefinition> getMethods() {
699             return methods;
700         }
701
702     }
703
704 }