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
8 package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl;
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.Lists;
12 import com.google.common.collect.Maps;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.List;
19 import java.util.Map.Entry;
20 import javax.management.openmbean.SimpleType;
21 import org.opendaylight.controller.config.api.DependencyResolver;
22 import org.opendaylight.controller.config.api.IdentityAttributeRef;
23 import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
24 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
25 import org.opendaylight.controller.config.api.runtime.RuntimeBean;
26 import org.opendaylight.controller.config.spi.AbstractModule;
27 import org.opendaylight.controller.config.yangjmxgenerator.AbstractEntry;
28 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
29 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
30 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
31 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
32 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
33 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
34 import org.opendaylight.controller.config.yangjmxgenerator.attribute.Dependency;
35 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
36 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
37 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
38 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
39 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute;
40 import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute;
41 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation;
42 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation.Parameter;
43 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Constructor;
44 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field;
45 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Header;
46 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField;
47 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDeclaration;
48 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition;
49 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField;
50 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper;
51 import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType;
52 import org.opendaylight.yangtools.sal.binding.model.api.Type;
53 import org.opendaylight.yangtools.yang.binding.BindingMapping;
55 public class TemplateFactory {
58 * Get map of file name as key, FtlFile instance representing runtime mx
59 * bean as value that should be persisted from this instance.
61 public static Map<String, FtlTemplate> getTOAndMXInterfaceFtlFiles(
62 final RuntimeBeanEntry entry) {
63 Map<String, FtlTemplate> result = new HashMap<>();
64 { // create GeneralInterfaceFtlFile for runtime MXBean. Attributes will
65 // be transformed to getter methods
66 String mxBeanTypeName = entry.getJavaNameOfRuntimeMXBean();
67 List<String> extendedInterfaces = Arrays.asList(RuntimeBean.class
69 List<MethodDeclaration> methods = new ArrayList<>();
71 // convert attributes to getters
72 for (AttributeIfc attributeIfc : entry.getAttributes()) {
74 returnType = getReturnType(attributeIfc);
75 String getterName = "get"
76 + attributeIfc.getUpperCaseCammelCase();
77 MethodDeclaration getter = new MethodDeclaration(returnType,
78 getterName, Collections.<Field> emptyList());
83 for (Rpc rpc : entry.getRpcs()) {
84 // convert JavaAttribute parameters into fields
85 List<Field> fields = new ArrayList<>();
86 for (JavaAttribute ja : rpc.getParameters()) {
87 Field field = new Field(Collections.<String> emptyList(),
88 ja.getType().getFullyQualifiedName(),
89 ja.getLowerCaseCammelCase(), ja.getNullableDefaultWrappedForCode());
92 MethodDeclaration operation = new MethodDeclaration(
93 getReturnType(rpc.getReturnType()), rpc.getName(), fields);
94 methods.add(operation);
98 GeneralInterfaceTemplate runtimeMxBeanIfc = new GeneralInterfaceTemplate(
99 null, entry.getPackageName(), mxBeanTypeName,
100 extendedInterfaces, methods);
102 result.put(runtimeMxBeanIfc.getTypeDeclaration().getName()
103 + ".java", runtimeMxBeanIfc);
106 result.putAll(TemplateFactory.tOsFromRbe(entry));
111 // FIXME: put into Type.toString
112 static String serializeType(final Type type, final boolean addWildcards) {
113 if (type instanceof ParameterizedType){
114 ParameterizedType parameterizedType = (ParameterizedType) type;
115 StringBuilder sb = new StringBuilder();
116 sb.append(parameterizedType.getRawType().getFullyQualifiedName());
117 sb.append(addWildcards ? "<? extends " : "<");
118 boolean first = true;
119 for(Type parameter: parameterizedType.getActualTypeArguments()) {
125 sb.append(serializeType(parameter));
128 return sb.toString();
130 return type.getFullyQualifiedName();
134 static String serializeType(final Type type) {
135 return serializeType(type, false);
138 private static String getReturnType(final AttributeIfc attributeIfc) {
140 if (attributeIfc instanceof TypedAttribute) {
141 Type type = ((TypedAttribute) attributeIfc).getType();
142 returnType = serializeType(type);
143 } else if (attributeIfc == VoidAttribute.getInstance()) {
146 throw new UnsupportedOperationException(
147 "Attribute not supported: "
148 + attributeIfc.getClass());
153 public static GeneralInterfaceTemplate serviceInterfaceFromSie(
154 final ServiceInterfaceEntry sie) {
156 List<String> extendedInterfaces = Lists
157 .newArrayList(AbstractServiceInterface.class.getCanonicalName());
158 if (sie.getBase().isPresent()) {
159 extendedInterfaces.add(sie.getBase().get().getFullyQualifiedName());
163 GeneralInterfaceTemplate sieTemplate = new GeneralInterfaceTemplate(
164 getHeaderFromEntry(sie), sie.getPackageName(),
165 sie.getTypeName(), extendedInterfaces,
166 Lists.<MethodDeclaration> newArrayList());
167 sieTemplate.setJavadoc(sie.getNullableDescription());
169 if (sie.getNullableDescription() != null) {
170 sieTemplate.getAnnotations().add(
171 Annotation.createDescriptionAnnotation(sie
172 .getNullableDescription()));
174 sieTemplate.getAnnotations().addAll(Annotation.createSieAnnotations(sie));
179 public static AbstractFactoryTemplate abstractFactoryTemplateFromMbe(
180 final ModuleMXBeanEntry mbe) {
181 AbstractFactoryAttributesProcessor attrProcessor = new AbstractFactoryAttributesProcessor();
182 attrProcessor.processAttributes(mbe.getAttributes(),
183 mbe.getPackageName());
187 return new AbstractFactoryTemplate(getHeaderFromEntry(mbe),
188 mbe.getPackageName(), mbe.getAbstractFactoryName(),
189 attrProcessor.getFields()
193 public static AbstractModuleTemplate abstractModuleTemplateFromMbe(
194 final ModuleMXBeanEntry mbe) {
195 AbstractModuleAttributesProcessor attrProcessor = new AbstractModuleAttributesProcessor(mbe.getAttributes());
197 List<ModuleField> moduleFields = attrProcessor.getModuleFields();
198 List<String> implementedIfcs = Lists.newArrayList(
199 mbe.getFullyQualifiedName(mbe.getMXBeanInterfaceName()));
201 for (String implementedService : mbe.getProvidedServices().keySet()) {
202 implementedIfcs.add(implementedService);
205 boolean generateRuntime = false;
206 String registratorFullyQualifiedName = null;
207 if (mbe.getRuntimeBeans() != null
208 && mbe.getRuntimeBeans().isEmpty() == false) {
209 generateRuntime = true;
210 RuntimeBeanEntry rootEntry = RuntimeRegistratorFtlTemplate
211 .findRoot(mbe.getRuntimeBeans());
212 registratorFullyQualifiedName = rootEntry
215 .concat(RuntimeRegistratorFtlTemplate.getJavaNameOfRuntimeRegistrator(rootEntry));
216 implementedIfcs.add(RuntimeBeanRegistratorAwareModule.class
217 .getCanonicalName());
220 List<String> extendedClasses = Collections.singletonList(AbstractModule.class.getCanonicalName() + "<" + mbe.getAbstractModuleName() + ">");
222 AbstractModuleTemplate abstractModuleTemplate = new AbstractModuleTemplate(
223 getHeaderFromEntry(mbe), mbe.getPackageName(),
224 mbe.getAbstractModuleName(), extendedClasses, implementedIfcs, moduleFields,
225 attrProcessor.getMethods(), generateRuntime,
226 registratorFullyQualifiedName);
228 if (mbe.getNullableDescription() != null) {
229 abstractModuleTemplate.getAnnotations().add(
230 Annotation.createDescriptionAnnotation(mbe
231 .getNullableDescription()));
233 return abstractModuleTemplate;
236 public static StubFactoryTemplate stubFactoryTemplateFromMbe(
237 final ModuleMXBeanEntry mbe) {
238 return new StubFactoryTemplate(getHeaderFromEntry(mbe),
239 mbe.getPackageName(), mbe.getStubFactoryName(),
240 mbe.getFullyQualifiedName(mbe.getAbstractFactoryName())
244 public static GeneralInterfaceTemplate mXBeanInterfaceTemplateFromMbe(
245 final ModuleMXBeanEntry mbe) {
246 MXBeanInterfaceAttributesProcessor attrProcessor = new MXBeanInterfaceAttributesProcessor();
247 attrProcessor.processAttributes(mbe.getAttributes());
248 GeneralInterfaceTemplate ifcTemplate = new GeneralInterfaceTemplate(
249 getHeaderFromEntry(mbe), mbe.getPackageName(),
250 mbe.getMXBeanInterfaceName(), Lists.<String> newArrayList(),
251 attrProcessor.getMethods());
252 ifcTemplate.setJavadoc(mbe.getNullableDescription());
256 public static Map<String, GeneralClassTemplate> tOsFromMbe(
257 final ModuleMXBeanEntry mbe) {
258 Map<String, GeneralClassTemplate> retVal = Maps.newHashMap();
259 TOAttributesProcessor processor = new TOAttributesProcessor();
260 processor.processAttributes(mbe.getAttributes());
261 for (org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor
263 List<Constructor> constructors = Lists.newArrayList();
264 constructors.add(new Constructor(to.getName(), "super();"));
266 Header header = getHeaderFromEntry(mbe);
269 new GeneralClassTemplate(header, mbe.getPackageName(), to
270 .getName(), Collections.<String> emptyList(),
271 Collections.<String> emptyList(), to.getFields(),
272 to.getMethods(), false, false, constructors));
277 public static Map<String, GeneralClassTemplate> tOsFromRbe(
278 final RuntimeBeanEntry rbe) {
279 Map<String, GeneralClassTemplate> retVal = Maps.newHashMap();
280 TOAttributesProcessor processor = new TOAttributesProcessor();
281 Map<String, AttributeIfc> yangPropertiesToTypesMap = Maps.newHashMap(rbe.getYangPropertiesToTypesMap());
283 // Add TOs from output parameters
284 for (Rpc rpc : rbe.getRpcs()) {
285 AttributeIfc returnType = rpc.getReturnType();
287 if (returnType == VoidAttribute.getInstance()) {
290 if (returnType instanceof JavaAttribute) {
293 if (returnType instanceof ListAttribute && returnType.getOpenType() instanceof SimpleType) {
297 Preconditions.checkState(yangPropertiesToTypesMap.containsKey(returnType.getAttributeYangName()) == false,
298 "Duplicate TO %s for %s", returnType.getAttributeYangName(), rbe);
299 yangPropertiesToTypesMap.put(returnType.getAttributeYangName(), returnType);
302 processor.processAttributes(yangPropertiesToTypesMap);
303 for (org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor
305 List<Constructor> constructors = Lists.newArrayList();
306 constructors.add(new Constructor(to.getName(), "super();"));
311 new GeneralClassTemplate(null, rbe.getPackageName(), to
312 .getName(), Collections.<String> emptyList(),
313 Collections.<String> emptyList(), to.getFields(),
314 to.getMethods(), false, false, constructors));
319 private static Header getHeaderFromEntry(final AbstractEntry mbe) {
320 return new Header(mbe.getYangModuleName(), mbe.getYangModuleLocalname());
323 // TODO refactor attribute processors
325 private static class TOAttributesProcessor {
327 private final List<TOInternal> tos = Lists.newArrayList();
329 void processAttributes(final Map<String, AttributeIfc> attributes) {
330 for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
331 AttributeIfc attributeIfc = attrEntry.getValue();
332 if (attributeIfc instanceof TOAttribute) {
333 createTOInternal((TOAttribute) attributeIfc);
335 if (attributeIfc instanceof ListAttribute) {
336 AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
337 .getInnerAttribute();
338 if (innerAttr instanceof TOAttribute) {
339 createTOInternal((TOAttribute) innerAttr);
345 private void createTOInternal(final TOAttribute toAttribute) {
347 Map<String, AttributeIfc> attrs = toAttribute.getCapitalizedPropertiesToTypesMap();
348 // recursive processing of TO's attributes
349 processAttributes(attrs);
351 tos.add(new TOInternal(toAttribute.getType(), attrs));
354 List<TOInternal> getTOs() {
358 private static class TOInternal {
359 private final String fullyQualifiedName, name;
360 private List<Field> fields;
361 private List<MethodDefinition> methods;
363 public TOInternal(final Type type, final Map<String, AttributeIfc> attrs) {
364 this(type.getFullyQualifiedName(), type.getName(), attrs, type.getPackageName());
367 public TOInternal(final String fullyQualifiedName, final String name,
368 final Map<String, AttributeIfc> attrs, final String packageName) {
369 this.fullyQualifiedName = fullyQualifiedName;
371 processAttrs(attrs, packageName);
374 private final static String dependencyResolverVarName = "dependencyResolver";
375 private final static String dependencyResolverInjectMethodName = "injectDependencyResolver";
377 private void processAttrs(final Map<String, AttributeIfc> attrs, final String packageName) {
378 fields = Lists.newArrayList();
379 methods = Lists.newArrayList();
381 // FIXME conflict if "dependencyResolver" field from yang
382 Field depRes = new Field(DependencyResolver.class.getName(), dependencyResolverVarName);
384 methods.add(new MethodDefinition("void", dependencyResolverInjectMethodName, Lists.newArrayList(depRes),
385 "this." + dependencyResolverVarName + " = " + dependencyResolverVarName + ";"));
387 for (Entry<String, AttributeIfc> attrEntry : attrs.entrySet()) {
388 String innerName = attrEntry.getKey();
389 String varName = BindingMapping.getPropertyName(attrEntry.getKey());
391 String fullyQualifiedName, nullableDefault = null;
392 if (attrEntry.getValue() instanceof TypedAttribute) {
393 Type type = ((TypedAttribute) attrEntry.getValue()).getType();
394 if(attrEntry.getValue() instanceof JavaAttribute) {
395 nullableDefault = ((JavaAttribute)attrEntry.getValue()).getNullableDefaultWrappedForCode();
396 if(((JavaAttribute)attrEntry.getValue()).isIdentityRef()) {
398 String fieldType = serializeType(type, true);
399 String innerType = getInnerTypeFromIdentity(type);
400 methods.add(new MethodDefinition(fieldType, "resolve" + attrEntry.getKey(), Collections.<Field>emptyList(),
401 "return " + varName + ".resolveIdentity(" + dependencyResolverVarName + "," + innerType + ".class);"));
402 type = identityRefType;
405 fullyQualifiedName = serializeType(type);
407 fullyQualifiedName = FullyQualifiedNameHelper
408 .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase());
410 fields.add(new Field(fullyQualifiedName, varName, nullableDefault, needsDepResolver(attrEntry.getValue())));
412 String getterName = "get" + innerName;
413 MethodDefinition getter = new MethodDefinition(
414 fullyQualifiedName, getterName,
415 Collections.<Field> emptyList(), "return "
418 String setterName = "set" + innerName;
419 MethodDefinition setter = new MethodDefinition("void",
420 setterName, Lists.newArrayList(new Field(
421 fullyQualifiedName, varName)), "this."
422 + varName + " = " + varName + ";");
428 final MethodDefinition hashCode = getHash(attrs);
429 methods.add(hashCode);
432 final MethodDefinition equals = getEquals(attrs);
436 private MethodDefinition getEquals(final Map<String, AttributeIfc> attrs) {
437 final StringBuilder equalsBodyBuilder = new StringBuilder(
438 " if (this == o) return true;\n" +
439 " if (o == null || getClass() != o.getClass()) return false;\n");
440 equalsBodyBuilder.append(String.format(
441 " final %s that = (%s) o;\n", name, name));
442 for (AttributeIfc s : attrs.values()) {
443 equalsBodyBuilder.append(String.format(
444 " if(java.util.Objects.equals(%1$s, that.%1$s) == false) {\n" +
446 " }\n\n", s.getLowerCaseCammelCase()));
448 equalsBodyBuilder.append(
450 return new MethodDefinition("boolean", "equals", Collections.singletonList(new Field("Object", "o")),
451 Collections.singletonList(new Annotation("Override", Collections.<Parameter>emptyList())), equalsBodyBuilder.toString());
454 private MethodDefinition getHash(final Map<String, AttributeIfc> attrs) {
455 final StringBuilder hashBodyBuilder = new StringBuilder(
456 " return java.util.Objects.hash(");
457 for (AttributeIfc s : attrs.values()) {
458 hashBodyBuilder.append(s.getLowerCaseCammelCase());
459 hashBodyBuilder.append(", ");
461 hashBodyBuilder.replace(hashBodyBuilder.length() - 2, hashBodyBuilder.length(), ");\n");
462 return new MethodDefinition("int", "hashCode", Collections.<Field>emptyList(),
463 Collections.singletonList(new Annotation("Override", Collections.<Parameter>emptyList())), hashBodyBuilder.toString());
467 return fullyQualifiedName;
474 List<Field> getFields() {
478 List<MethodDefinition> getMethods() {
485 private static class MXBeanInterfaceAttributesProcessor {
486 private final List<MethodDeclaration> methods = Lists.newArrayList();
488 void processAttributes(final Map<String, AttributeIfc> attributes) {
489 for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
491 AttributeIfc attributeIfc = attrEntry.getValue();
493 if (attributeIfc instanceof TypedAttribute) {
494 TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
495 returnType = serializeType(typedAttribute.getType());
497 if (attributeIfc instanceof JavaAttribute && ((JavaAttribute)attrEntry.getValue()).isIdentityRef()) {
498 returnType = serializeType(identityRefType);
502 throw new UnsupportedOperationException(
503 "Attribute not supported: "
504 + attributeIfc.getClass());
507 String getterName = "get"
508 + attributeIfc.getUpperCaseCammelCase();
509 MethodDeclaration getter = new MethodDeclaration(returnType,
510 getterName, Collections.<Field> emptyList());
512 String varName = BindingMapping.getPropertyName(attrEntry.getKey());
513 String setterName = "set"
514 + attributeIfc.getUpperCaseCammelCase();
515 MethodDeclaration setter = new MethodDeclaration("void",
516 setterName, Lists.newArrayList(new Field(returnType,
522 if (attributeIfc.getNullableDescription() != null) {
523 setter.setJavadoc(attrEntry.getValue()
524 .getNullableDescription());
529 List<MethodDeclaration> getMethods() {
534 private static final Type identityRefType = new Type() {
535 public final Class<IdentityAttributeRef> IDENTITY_ATTRIBUTE_REF_CLASS = IdentityAttributeRef.class;
538 public String getPackageName() {
539 return IDENTITY_ATTRIBUTE_REF_CLASS.getPackage().getName();
543 public String getName() {
544 return IDENTITY_ATTRIBUTE_REF_CLASS.getSimpleName();
548 public String getFullyQualifiedName() {
549 return IDENTITY_ATTRIBUTE_REF_CLASS.getName();
553 private static class AbstractFactoryAttributesProcessor {
555 private final List<Field> fields = Lists.newArrayList();
557 void processAttributes(final Map<String, AttributeIfc> attributes,
558 final String packageName) {
559 for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
561 String nullableDefaultWrapped = null;
562 AttributeIfc attributeIfc = attrEntry.getValue();
564 if (attributeIfc instanceof TypedAttribute) {
565 TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
566 type = serializeType(typedAttribute.getType());
568 throw new UnsupportedOperationException(
569 "Attribute not supported: "
570 + attributeIfc.getClass());
573 fields.add(new Field(type, attributeIfc
574 .getUpperCaseCammelCase(), nullableDefaultWrapped));
578 List<Field> getFields() {
583 private static class AbstractModuleAttributesProcessor {
584 private static class Holder {
585 private final List<ModuleField> moduleFields;
586 private final List<MethodDefinition> methods;
588 private Holder(final List<ModuleField> moduleFields, final List<MethodDefinition> methods) {
589 this.moduleFields = Collections.unmodifiableList(moduleFields);
590 this.methods = Collections.unmodifiableList(methods);
594 private final Holder holder;
597 private AbstractModuleAttributesProcessor(final Map<String, AttributeIfc> attributes) {
598 this.holder = processAttributes(attributes);
601 private static Holder processAttributes(final Map<String, AttributeIfc> attributes) {
602 List<ModuleField> moduleFields = new ArrayList<>();
603 List<MethodDefinition> methods = new ArrayList<>();
604 for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
605 String type, nullableDefaultWrapped = null;
606 AttributeIfc attributeIfc = attrEntry.getValue();
607 boolean isIdentity = false;
608 boolean needsDepResolver = needsDepResolver(attrEntry.getValue());
610 if (attributeIfc instanceof TypedAttribute) {
611 TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
612 type = serializeType(typedAttribute.getType());
613 if (attributeIfc instanceof JavaAttribute) {
614 nullableDefaultWrapped = ((JavaAttribute) attributeIfc).getNullableDefaultWrappedForCode();
615 if(((JavaAttribute)attrEntry.getValue()).isIdentityRef()) {
617 type = serializeType(typedAttribute.getType(), true);
621 throw new UnsupportedOperationException(
622 "Attribute not supported: "
623 + attributeIfc.getClass());
626 boolean isDependency = false;
627 boolean isListOfDependencies = false;
628 Dependency dependency = null;
629 Annotation overrideAnnotation = new Annotation("Override",
630 Collections.<Parameter> emptyList());
631 List<Annotation> annotations = Lists
632 .newArrayList(overrideAnnotation);
634 if (attributeIfc instanceof AbstractDependencyAttribute) {
636 dependency = ((AbstractDependencyAttribute) attributeIfc)
638 annotations.add(Annotation
639 .createRequireIfcAnnotation(dependency.getSie()));
640 if (attributeIfc instanceof ListDependenciesAttribute) {
641 isListOfDependencies = true;
645 String varName = BindingMapping.getPropertyName(attrEntry.getKey());
649 String identityBaseClass = getInnerTypeFromIdentity(((TypedAttribute) attributeIfc).getType());
650 IdentityRefModuleField identityField = new IdentityRefModuleField(type, varName,
651 attributeIfc.getUpperCaseCammelCase(), identityBaseClass);
653 String getterName = "get"
654 + attributeIfc.getUpperCaseCammelCase() + "Identity";
655 MethodDefinition additionalGetter = new MethodDefinition(type, getterName, Collections.<Field> emptyList(),
656 Collections.<Annotation> emptyList(), "return " + identityField.getIdentityClassName()
658 methods.add(additionalGetter);
660 String setterName = "set"
661 + attributeIfc.getUpperCaseCammelCase();
663 String setterBody = "this." + identityField.getIdentityClassName() + " = " + identityField.getIdentityClassName() + ";";
664 MethodDefinition additionalSetter = new MethodDefinition("void",
666 Lists.newArrayList(new Field(type, identityField.getIdentityClassName())),
667 Collections.<Annotation> emptyList(), setterBody);
668 additionalSetter.setJavadoc(attributeIfc.getNullableDescription());
670 methods.add(additionalSetter);
672 type = serializeType(identityRefType);
673 field = identityField;
675 field = new ModuleField(type, varName, attributeIfc.getUpperCaseCammelCase(),
676 nullableDefaultWrapped, isDependency, dependency, isListOfDependencies, needsDepResolver);
678 moduleFields.add(field);
681 String getterName = "get"
682 + attributeIfc.getUpperCaseCammelCase();
683 MethodDefinition getter = new MethodDefinition(type,
684 getterName, Collections.<Field> emptyList(),
685 Lists.newArrayList(overrideAnnotation), "return "
690 String setterName = "set"
691 + attributeIfc.getUpperCaseCammelCase();
693 if (attributeIfc.getNullableDescription() != null) {
694 annotations.add(Annotation
695 .createDescriptionAnnotation(attributeIfc.getNullableDescription()));
698 String setterBody = "this." + varName + " = " + varName + ";";
699 if (isListOfDependencies) {
700 String nullCheck = String.format("if (%s == null) throw new IllegalArgumentException(\"Null not supported\");%n",
702 setterBody = nullCheck + setterBody;
704 MethodDefinition setter = new MethodDefinition("void",
706 Lists.newArrayList(new Field(type, varName)),
707 annotations, setterBody);
708 setter.setJavadoc(attributeIfc.getNullableDescription());
712 return new Holder(moduleFields, methods);
715 List<ModuleField> getModuleFields() {
716 return holder.moduleFields;
719 List<MethodDefinition> getMethods() {
720 return holder.methods;
726 private static boolean needsDepResolver(final AttributeIfc value) {
727 if(value instanceof TOAttribute) {
730 if(value instanceof ListAttribute) {
731 AttributeIfc innerAttribute = ((ListAttribute) value).getInnerAttribute();
732 return needsDepResolver(innerAttribute);
738 private static String getInnerTypeFromIdentity(final Type type) {
739 Preconditions.checkArgument(type instanceof ParameterizedType);
740 Type[] args = ((ParameterizedType) type).getActualTypeArguments();
741 Preconditions.checkArgument(args.length ==1);
742 return serializeType(args[0]);