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.Collections;
15 import java.util.HashMap;
16 import java.util.List;
18 import java.util.Map.Entry;
19 import javax.management.openmbean.SimpleType;
20 import org.opendaylight.controller.config.api.DependencyResolver;
21 import org.opendaylight.controller.config.api.IdentityAttributeRef;
22 import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule;
23 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
24 import org.opendaylight.controller.config.api.runtime.RuntimeBean;
25 import org.opendaylight.controller.config.spi.AbstractModule;
26 import org.opendaylight.controller.config.yangjmxgenerator.AbstractEntry;
27 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
28 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
29 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
30 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
31 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute;
32 import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc;
33 import org.opendaylight.controller.config.yangjmxgenerator.attribute.Dependency;
34 import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute;
35 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute;
36 import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
37 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
38 import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute;
39 import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute;
40 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation;
41 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation.Parameter;
42 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Constructor;
43 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field;
44 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Header;
45 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField;
46 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDeclaration;
47 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition;
48 import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField;
49 import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper;
50 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
51 import org.opendaylight.mdsal.binding.model.api.ParameterizedType;
52 import org.opendaylight.mdsal.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 final Map<String, FtlTemplate> result = new HashMap<>();
64 { // create GeneralInterfaceFtlFile for runtime MXBean. Attributes will
65 // be transformed to getter methods
66 final String mxBeanTypeName = entry.getJavaNameOfRuntimeMXBean();
67 final List<String> extendedInterfaces = Collections.singletonList(RuntimeBean.class
69 final List<MethodDeclaration> methods = new ArrayList<>();
71 // convert attributes to getters
72 for (final AttributeIfc attributeIfc : entry.getAttributes()) {
74 returnType = getReturnType(attributeIfc);
75 final String getterName = "get"
76 + attributeIfc.getUpperCaseCammelCase();
77 final MethodDeclaration getter = new MethodDeclaration(returnType,
78 getterName, Collections.<Field> emptyList());
83 for (final Rpc rpc : entry.getRpcs()) {
84 // convert JavaAttribute parameters into fields
85 final List<Field> fields = new ArrayList<>();
86 for (final JavaAttribute ja : rpc.getParameters()) {
87 final Field field = new Field(Collections.emptyList(),
88 ja.getType().getFullyQualifiedName(),
89 ja.getLowerCaseCammelCase(), ja.getNullableDefaultWrappedForCode());
92 final MethodDeclaration operation = new MethodDeclaration(
93 getReturnType(rpc.getReturnType()), rpc.getName(), fields);
94 methods.add(operation);
98 final 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 final ParameterizedType parameterizedType = (ParameterizedType) type;
115 final StringBuilder sb = new StringBuilder();
116 sb.append(parameterizedType.getRawType().getFullyQualifiedName());
117 sb.append(addWildcards ? "<? extends " : "<");
118 boolean first = true;
119 for(final 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 final 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 final List<String> extendedInterfaces = Lists
157 .newArrayList(AbstractServiceInterface.class.getCanonicalName());
158 if (sie.getBase().isPresent()) {
159 extendedInterfaces.add(sie.getBase().get().getFullyQualifiedName());
163 final 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 final AbstractFactoryAttributesProcessor attrProcessor = new AbstractFactoryAttributesProcessor();
182 attrProcessor.processAttributes(mbe.getAttributes());
186 return new AbstractFactoryTemplate(getHeaderFromEntry(mbe),
187 mbe.getPackageName(), mbe.getAbstractFactoryName(),
188 attrProcessor.getFields()
192 public static AbstractModuleTemplate abstractModuleTemplateFromMbe(
193 final ModuleMXBeanEntry mbe) {
194 final AbstractModuleAttributesProcessor attrProcessor = new AbstractModuleAttributesProcessor(mbe.getAttributes());
196 final List<ModuleField> moduleFields = attrProcessor.getModuleFields();
197 final List<String> implementedIfcs = Lists.newArrayList(
198 mbe.getFullyQualifiedName(mbe.getMXBeanInterfaceName()));
200 for (final String implementedService : mbe.getProvidedServices().keySet()) {
201 implementedIfcs.add(implementedService);
204 boolean generateRuntime = false;
205 String registratorFullyQualifiedName = null;
206 if (mbe.getRuntimeBeans() != null
207 && !mbe.getRuntimeBeans().isEmpty()) {
208 generateRuntime = true;
209 final RuntimeBeanEntry rootEntry = RuntimeRegistratorFtlTemplate
210 .findRoot(mbe.getRuntimeBeans());
211 registratorFullyQualifiedName = rootEntry
214 .concat(RuntimeRegistratorFtlTemplate.getJavaNameOfRuntimeRegistrator(rootEntry));
215 implementedIfcs.add(RuntimeBeanRegistratorAwareModule.class
216 .getCanonicalName());
219 final List<String> extendedClasses = Collections.singletonList(AbstractModule.class.getCanonicalName() + "<" + mbe.getAbstractModuleName() + ">");
221 final AbstractModuleTemplate abstractModuleTemplate = new AbstractModuleTemplate(
222 getHeaderFromEntry(mbe), mbe.getPackageName(),
223 mbe.getAbstractModuleName(), extendedClasses, implementedIfcs, moduleFields,
224 attrProcessor.getMethods(), generateRuntime,
225 registratorFullyQualifiedName);
227 if (mbe.getNullableDescription() != null) {
228 abstractModuleTemplate.getAnnotations().add(
229 Annotation.createDescriptionAnnotation(mbe
230 .getNullableDescription()));
232 return abstractModuleTemplate;
235 public static StubFactoryTemplate stubFactoryTemplateFromMbe(
236 final ModuleMXBeanEntry mbe) {
237 return new StubFactoryTemplate(getHeaderFromEntry(mbe),
238 mbe.getPackageName(), mbe.getStubFactoryName(),
239 mbe.getFullyQualifiedName(mbe.getAbstractFactoryName())
243 public static GeneralInterfaceTemplate mXBeanInterfaceTemplateFromMbe(
244 final ModuleMXBeanEntry mbe) {
245 final MXBeanInterfaceAttributesProcessor attrProcessor = new MXBeanInterfaceAttributesProcessor();
246 attrProcessor.processAttributes(mbe.getAttributes());
247 final GeneralInterfaceTemplate ifcTemplate = new GeneralInterfaceTemplate(
248 getHeaderFromEntry(mbe), mbe.getPackageName(),
249 mbe.getMXBeanInterfaceName(), Lists.<String> newArrayList(),
250 attrProcessor.getMethods());
251 ifcTemplate.setJavadoc(mbe.getNullableDescription());
255 public static Map<String, GeneralClassTemplate> tOsFromMbe(
256 final ModuleMXBeanEntry mbe) {
257 final Map<String, GeneralClassTemplate> retVal = Maps.newHashMap();
258 final TOAttributesProcessor processor = new TOAttributesProcessor();
259 processor.processAttributes(mbe.getAttributes());
260 for (final org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor
262 final List<Constructor> constructors = Lists.newArrayList();
263 constructors.add(new Constructor(to.getName(), "super();"));
265 final Header header = getHeaderFromEntry(mbe);
268 new GeneralClassTemplate(header, mbe.getPackageName(), to
269 .getName(), Collections.<String> emptyList(),
270 Collections.<String> emptyList(), to.getFields(),
271 to.getMethods(), false, false, constructors));
276 public static Map<String, GeneralClassTemplate> tOsFromRbe(
277 final RuntimeBeanEntry rbe) {
278 final Map<String, GeneralClassTemplate> retVal = Maps.newHashMap();
279 final TOAttributesProcessor processor = new TOAttributesProcessor();
280 final Map<String, AttributeIfc> yangPropertiesToTypesMap = Maps.newHashMap(rbe.getYangPropertiesToTypesMap());
282 // Add TOs from output parameters
283 for (final Rpc rpc : rbe.getRpcs()) {
284 final AttributeIfc returnType = rpc.getReturnType();
286 if (returnType == VoidAttribute.getInstance()) {
289 if (returnType instanceof JavaAttribute) {
292 if (returnType instanceof ListAttribute && returnType.getOpenType() instanceof SimpleType) {
296 Preconditions.checkState(!yangPropertiesToTypesMap.containsKey(returnType.getAttributeYangName()),
297 "Duplicate TO %s for %s", returnType.getAttributeYangName(), rbe);
298 yangPropertiesToTypesMap.put(returnType.getAttributeYangName(), returnType);
301 processor.processAttributes(yangPropertiesToTypesMap);
302 for (final org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor
304 final List<Constructor> constructors = Lists.newArrayList();
305 constructors.add(new Constructor(to.getName(), "super();"));
310 new GeneralClassTemplate(null, rbe.getPackageName(), to
311 .getName(), Collections.<String> emptyList(),
312 Collections.<String> emptyList(), to.getFields(),
313 to.getMethods(), false, false, constructors));
318 private static Header getHeaderFromEntry(final AbstractEntry mbe) {
319 return new Header(mbe.getYangModuleName(), mbe.getYangModuleLocalname());
322 // TODO refactor attribute processors
324 private static class TOAttributesProcessor {
326 private final List<TOInternal> tos = Lists.newArrayList();
328 void processAttributes(final Map<String, AttributeIfc> attributes) {
329 for (final Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
330 final AttributeIfc attributeIfc = attrEntry.getValue();
331 if (attributeIfc instanceof TOAttribute) {
332 createTOInternal((TOAttribute) attributeIfc);
334 if (attributeIfc instanceof ListAttribute) {
335 final AttributeIfc innerAttr = ((ListAttribute) attributeIfc)
336 .getInnerAttribute();
337 if (innerAttr instanceof TOAttribute) {
338 createTOInternal((TOAttribute) innerAttr);
344 private void createTOInternal(final TOAttribute toAttribute) {
346 final Map<String, AttributeIfc> attrs = toAttribute.getCapitalizedPropertiesToTypesMap();
347 // recursive processing of TO's attributes
348 processAttributes(attrs);
350 this.tos.add(new TOInternal(toAttribute.getType(), attrs));
353 List<TOInternal> getTOs() {
357 private static class TOInternal {
358 private final String fullyQualifiedName, name;
359 private List<Field> fields;
360 private List<MethodDefinition> methods;
362 public TOInternal(final Type type, final Map<String, AttributeIfc> attrs) {
363 this(type.getFullyQualifiedName(), type.getName(), attrs, type.getPackageName());
366 public TOInternal(final String fullyQualifiedName, final String name,
367 final Map<String, AttributeIfc> attrs, final String packageName) {
368 this.fullyQualifiedName = fullyQualifiedName;
370 processAttrs(attrs, packageName);
373 private final static String dependencyResolverVarName = "dependencyResolver";
374 private final static String dependencyResolverInjectMethodName = "injectDependencyResolver";
376 private void processAttrs(final Map<String, AttributeIfc> attrs, final String packageName) {
377 this.fields = Lists.newArrayList();
378 this.methods = Lists.newArrayList();
380 // FIXME conflict if "dependencyResolver" field from yang
381 final Field depRes = new Field(DependencyResolver.class.getName(), dependencyResolverVarName);
382 this.fields.add(depRes);
383 this.methods.add(new MethodDefinition("void", dependencyResolverInjectMethodName, Lists.newArrayList(depRes),
384 "this." + dependencyResolverVarName + " = " + dependencyResolverVarName + ";"));
386 for (final Entry<String, AttributeIfc> attrEntry : attrs.entrySet()) {
387 final String innerName = attrEntry.getKey();
388 final String varName = BindingMapping.getPropertyName(attrEntry.getKey());
390 String fullyQualifiedName, nullableDefault = null;
391 if (attrEntry.getValue() instanceof TypedAttribute) {
392 Type type = ((TypedAttribute) attrEntry.getValue()).getType();
393 if(attrEntry.getValue() instanceof JavaAttribute) {
394 nullableDefault = ((JavaAttribute)attrEntry.getValue()).getNullableDefaultWrappedForCode();
395 if(((JavaAttribute)attrEntry.getValue()).isIdentityRef()) {
397 final String fieldType = serializeType(type, true);
398 final String innerType = getInnerTypeFromIdentity(type);
399 this.methods.add(new MethodDefinition(fieldType, "resolve" + attrEntry.getKey(), Collections.<Field>emptyList(),
400 "return " + varName + ".resolveIdentity(" + dependencyResolverVarName + "," + innerType + ".class);"));
401 type = identityRefType;
404 fullyQualifiedName = serializeType(type);
406 fullyQualifiedName = FullyQualifiedNameHelper
407 .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase());
409 this.fields.add(new Field(fullyQualifiedName, varName, nullableDefault, needsDepResolver(attrEntry.getValue())));
411 final String getterName = "get" + innerName;
412 final MethodDefinition getter = new MethodDefinition(
413 fullyQualifiedName, getterName,
414 Collections.<Field> emptyList(), "return "
417 final String setterName = "set" + innerName;
418 final MethodDefinition setter = new MethodDefinition("void",
419 setterName, Lists.newArrayList(new Field(
420 fullyQualifiedName, varName)), "this."
421 + varName + " = " + varName + ";");
422 this.methods.add(getter);
423 this.methods.add(setter);
427 final MethodDefinition hashCode = getHash(attrs);
428 this.methods.add(hashCode);
431 final MethodDefinition equals = getEquals(attrs);
432 this.methods.add(equals);
435 private MethodDefinition getEquals(final Map<String, AttributeIfc> attrs) {
436 final StringBuilder equalsBodyBuilder = new StringBuilder(
437 " if (this == o) { return true; }\n" +
438 " if (o == null || getClass() != o.getClass()) { return false; }\n");
439 equalsBodyBuilder.append(String.format(
440 " final %s that = (%s) o;\n", this.name, this.name));
441 for (final AttributeIfc s : attrs.values()) {
442 equalsBodyBuilder.append(String.format(
443 " if (!java.util.Objects.equals(%1$s, that.%1$s)) {\n" +
445 " }\n\n", s.getLowerCaseCammelCase()));
447 equalsBodyBuilder.append(
449 return new MethodDefinition("boolean", "equals", Collections.singletonList(new Field("Object", "o")),
450 Collections.singletonList(new Annotation("Override", Collections.<Parameter>emptyList())), equalsBodyBuilder.toString());
453 private static MethodDefinition getHash(final Map<String, AttributeIfc> attrs) {
454 final StringBuilder hashBodyBuilder = new StringBuilder(
455 " return java.util.Objects.hash(");
456 for (final AttributeIfc s : attrs.values()) {
457 hashBodyBuilder.append(s.getLowerCaseCammelCase());
458 hashBodyBuilder.append(", ");
460 hashBodyBuilder.replace(hashBodyBuilder.length() - 2, hashBodyBuilder.length(), ");\n");
461 return new MethodDefinition("int", "hashCode", Collections.<Field>emptyList(),
462 Collections.singletonList(new Annotation("Override", Collections.<Parameter>emptyList())), hashBodyBuilder.toString());
466 return this.fullyQualifiedName;
473 List<Field> getFields() {
477 List<MethodDefinition> getMethods() {
484 private static class MXBeanInterfaceAttributesProcessor {
485 private final List<MethodDeclaration> methods = Lists.newArrayList();
487 void processAttributes(final Map<String, AttributeIfc> attributes) {
488 for (final Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
490 final AttributeIfc attributeIfc = attrEntry.getValue();
492 if (attributeIfc instanceof TypedAttribute) {
493 final TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
494 returnType = serializeType(typedAttribute.getType());
496 if (attributeIfc instanceof JavaAttribute && ((JavaAttribute)attrEntry.getValue()).isIdentityRef()) {
497 returnType = serializeType(identityRefType);
501 throw new UnsupportedOperationException(
502 "Attribute not supported: "
503 + attributeIfc.getClass());
506 final String getterName = "get"
507 + attributeIfc.getUpperCaseCammelCase();
508 final MethodDeclaration getter = new MethodDeclaration(returnType,
509 getterName, Collections.<Field> emptyList());
511 final String varName = BindingMapping.getPropertyName(attrEntry.getKey());
512 final String setterName = "set"
513 + attributeIfc.getUpperCaseCammelCase();
514 final MethodDeclaration setter = new MethodDeclaration("void",
515 setterName, Lists.newArrayList(new Field(returnType,
518 this.methods.add(getter);
519 this.methods.add(setter);
521 if (attributeIfc.getNullableDescription() != null) {
522 setter.setJavadoc(attrEntry.getValue()
523 .getNullableDescription());
528 List<MethodDeclaration> getMethods() {
533 private static final Type identityRefType = new Type() {
534 public final Class<IdentityAttributeRef> IDENTITY_ATTRIBUTE_REF_CLASS = IdentityAttributeRef.class;
535 private final JavaTypeName identifier = JavaTypeName.create(IDENTITY_ATTRIBUTE_REF_CLASS);
538 public JavaTypeName getIdentifier() {
543 private static class AbstractFactoryAttributesProcessor {
545 private final List<Field> fields = Lists.newArrayList();
547 void processAttributes(final Map<String, AttributeIfc> attributes) {
548 for (final AttributeIfc attributeIfc : attributes.values()) {
549 if (attributeIfc instanceof TypedAttribute) {
550 final TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
551 final String type = serializeType(typedAttribute.getType());
553 this.fields.add(new Field(type, attributeIfc
554 .getUpperCaseCammelCase(), null));
556 throw new UnsupportedOperationException(
557 "Attribute not supported: "
558 + attributeIfc.getClass());
563 List<Field> getFields() {
568 private static class AbstractModuleAttributesProcessor {
569 private static class Holder {
570 private final List<ModuleField> moduleFields;
571 private final List<MethodDefinition> methods;
573 private Holder(final List<ModuleField> moduleFields, final List<MethodDefinition> methods) {
574 this.moduleFields = Collections.unmodifiableList(moduleFields);
575 this.methods = Collections.unmodifiableList(methods);
579 private final Holder holder;
582 private AbstractModuleAttributesProcessor(final Map<String, AttributeIfc> attributes) {
583 this.holder = processAttributes(attributes);
586 private static Holder processAttributes(final Map<String, AttributeIfc> attributes) {
587 final List<ModuleField> moduleFields = new ArrayList<>();
588 final List<MethodDefinition> methods = new ArrayList<>();
589 for (final Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
590 String type, nullableDefaultWrapped = null;
591 final AttributeIfc attributeIfc = attrEntry.getValue();
592 boolean isIdentity = false;
593 final boolean needsDepResolver = needsDepResolver(attrEntry.getValue());
595 if (attributeIfc instanceof TypedAttribute) {
596 final TypedAttribute typedAttribute = (TypedAttribute) attributeIfc;
597 type = serializeType(typedAttribute.getType());
598 if (attributeIfc instanceof JavaAttribute) {
599 nullableDefaultWrapped = ((JavaAttribute) attributeIfc).getNullableDefaultWrappedForCode();
600 if(((JavaAttribute)attrEntry.getValue()).isIdentityRef()) {
602 type = serializeType(typedAttribute.getType(), true);
606 throw new UnsupportedOperationException(
607 "Attribute not supported: "
608 + attributeIfc.getClass());
611 boolean isDependency = false;
612 boolean isListOfDependencies = false;
613 Dependency dependency = null;
614 final Annotation overrideAnnotation = new Annotation("Override",
615 Collections.<Parameter> emptyList());
616 final List<Annotation> annotations = Lists
617 .newArrayList(overrideAnnotation);
619 if (attributeIfc instanceof AbstractDependencyAttribute) {
621 dependency = ((AbstractDependencyAttribute) attributeIfc)
623 annotations.add(Annotation
624 .createRequireIfcAnnotation(dependency.getSie()));
625 if (attributeIfc instanceof ListDependenciesAttribute) {
626 isListOfDependencies = true;
630 final String varName = BindingMapping.getPropertyName(attrEntry.getKey());
634 final String identityBaseClass = getInnerTypeFromIdentity(((TypedAttribute) attributeIfc).getType());
635 final IdentityRefModuleField identityField = new IdentityRefModuleField(type, varName,
636 attributeIfc.getUpperCaseCammelCase(), identityBaseClass);
638 final String getterName = "get"
639 + attributeIfc.getUpperCaseCammelCase() + "Identity";
640 final MethodDefinition additionalGetter = new MethodDefinition(type, getterName, Collections.<Field> emptyList(),
641 Collections.<Annotation> emptyList(), "return " + identityField.getIdentityClassName()
643 methods.add(additionalGetter);
645 final String setterName = "set"
646 + attributeIfc.getUpperCaseCammelCase();
648 final String setterBody = "this." + identityField.getIdentityClassName() + " = " + identityField.getIdentityClassName() + ";";
649 final MethodDefinition additionalSetter = new MethodDefinition("void",
651 Lists.newArrayList(new Field(type, identityField.getIdentityClassName())),
652 Collections.<Annotation> emptyList(), setterBody);
653 additionalSetter.setJavadoc(attributeIfc.getNullableDescription());
655 methods.add(additionalSetter);
657 type = serializeType(identityRefType);
658 field = identityField;
660 field = new ModuleField(type, varName, attributeIfc.getUpperCaseCammelCase(),
661 nullableDefaultWrapped, isDependency, dependency, isListOfDependencies, needsDepResolver);
663 moduleFields.add(field);
666 final String getterName = "get"
667 + attributeIfc.getUpperCaseCammelCase();
668 final MethodDefinition getter = new MethodDefinition(type,
669 getterName, Collections.<Field> emptyList(),
670 Lists.newArrayList(overrideAnnotation), "return "
675 final String setterName = "set"
676 + attributeIfc.getUpperCaseCammelCase();
678 if (attributeIfc.getNullableDescription() != null) {
679 annotations.add(Annotation
680 .createDescriptionAnnotation(attributeIfc.getNullableDescription()));
683 String setterBody = "this." + varName + " = " + varName + ";";
684 if (isListOfDependencies) {
685 final String nullCheck = String.format("if (%s == null) {\n%s = new java.util.ArrayList<>(); \n}%n",
687 setterBody = nullCheck + setterBody;
689 final MethodDefinition setter = new MethodDefinition("void",
691 Lists.newArrayList(new Field(type, varName)),
692 annotations, setterBody);
693 setter.setJavadoc(attributeIfc.getNullableDescription());
697 return new Holder(moduleFields, methods);
700 List<ModuleField> getModuleFields() {
701 return this.holder.moduleFields;
704 List<MethodDefinition> getMethods() {
705 return this.holder.methods;
711 private static boolean needsDepResolver(final AttributeIfc value) {
712 if(value instanceof TOAttribute) {
715 if(value instanceof ListAttribute) {
716 final AttributeIfc innerAttribute = ((ListAttribute) value).getInnerAttribute();
717 return needsDepResolver(innerAttribute);
723 private static String getInnerTypeFromIdentity(final Type type) {
724 Preconditions.checkArgument(type instanceof ParameterizedType);
725 final Type[] args = ((ParameterizedType) type).getActualTypeArguments();
726 Preconditions.checkArgument(args.length ==1);
727 return serializeType(args[0]);