1 package org.nuiton.eugene.java;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 import com.google.common.base.Function;
29 import com.google.common.collect.ImmutableMap;
30 import com.google.common.collect.ImmutableSet;
31 import com.google.common.collect.Lists;
32 import com.google.common.collect.Maps;
33 import org.apache.commons.collections4.CollectionUtils;
34 import org.apache.commons.lang3.StringUtils;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.codehaus.plexus.component.annotations.Component;
38 import org.nuiton.eugene.GeneratorUtil;
39 import org.nuiton.eugene.Template;
40 import org.nuiton.eugene.models.extension.tagvalue.provider.TagValueMetadatasProvider;
41 import org.nuiton.eugene.models.object.ObjectModel;
42 import org.nuiton.eugene.models.object.ObjectModelAttribute;
43 import org.nuiton.eugene.models.object.ObjectModelClass;
44 import org.nuiton.eugene.models.object.ObjectModelClassifier;
45 import org.nuiton.eugene.models.object.ObjectModelInterface;
46 import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
47 import org.nuiton.eugene.models.object.ObjectModelOperation;
48 import org.nuiton.eugene.models.object.ObjectModelPackage;
49 import org.nuiton.util.beans.Binder;
50 import org.nuiton.util.beans.BinderFactory;
51
52 import java.beans.PropertyChangeListener;
53 import java.beans.PropertyChangeSupport;
54 import java.io.Serializable;
55 import java.util.ArrayList;
56 import java.util.Collection;
57 import java.util.Collections;
58 import java.util.HashSet;
59 import java.util.List;
60 import java.util.Set;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 @Component(role = Template.class, hint = "org.nuiton.eugene.java.BeanTransformer")
79 public class BeanTransformer extends ObjectModelTransformerToJava {
80
81
82 private static final Log log = LogFactory.getLog(BeanTransformer.class);
83
84 ImmutableMap<ObjectModelClass, String> classesNameTranslation;
85
86 ImmutableMap<ObjectModelClass, String> helpersNameTranslation;
87 ImmutableSet<ObjectModelClass> classes;
88
89 ImmutableSet<ObjectModelClass> helpers;
90 protected boolean useJava8;
91
92 protected final EugeneJavaTagValues javaTemplatesTagValues;
93 protected final BeanTransformerTagValues beanTagValues;
94
95 public BeanTransformer() {
96 javaTemplatesTagValues = new EugeneJavaTagValues();
97 beanTagValues = new BeanTransformerTagValues();
98 }
99
100 @Override
101 public void transformFromModel(ObjectModel model) {
102 super.transformFromModel(model);
103
104 useJava8 = javaTemplatesTagValues.isUseJava8(model);
105 ImmutableMap.Builder<ObjectModelClass, String> classesNameTranslationBuilder = new ImmutableMap.Builder<>();
106 ImmutableMap.Builder<ObjectModelClass, String> helpersNameTranslationBuilder = new ImmutableMap.Builder<>();
107 ImmutableSet.Builder<ObjectModelClass> classesBuilder = new ImmutableSet.Builder<>();
108 ImmutableSet.Builder<ObjectModelClass> helpersBuilder = new ImmutableSet.Builder<>();
109
110 for (ObjectModelClass aClass : model.getClasses()) {
111
112 ObjectModelPackage aPackage = model.getPackage(aClass.getPackageName());
113 if (javaTemplatesTagValues.isBean(aClass, aPackage)) {
114
115 classesBuilder.add(aClass);
116
117 String classNamePrefix = beanTagValues.getClassNamePrefixTagValue(aClass, aPackage, model);
118 String classNameSuffix = beanTagValues.getClassNameSuffixTagValue(aClass, aPackage, model);
119
120 String generateName = generateName(classNamePrefix, aClass.getName(), classNameSuffix);
121 classesNameTranslationBuilder.put(aClass, generateName);
122
123 boolean canGenerateHelper = beanTagValues.isGenerateHelper(aClass, aPackage, model);
124
125 if (canGenerateHelper) {
126
127 helpersBuilder.add(aClass);
128
129 String helperNamePrefix = beanTagValues.getHelperClassNamePrefixTagValue(aClass, aPackage, model);
130 String helperNameSuffix = beanTagValues.getHelperClassNameSuffixTagValue(aClass, aPackage, model);
131
132 String generateHelperName = generateName(helperNamePrefix, aClass.getName(), helperNameSuffix);
133 helpersNameTranslationBuilder.put(aClass, generateHelperName);
134
135 }
136
137 }
138 }
139
140 classes = classesBuilder.build();
141 helpers = helpersBuilder.build();
142 classesNameTranslation = classesNameTranslationBuilder.build();
143 helpersNameTranslation = helpersNameTranslationBuilder.build();
144
145 ImmutableMap<String, ObjectModelClass> beanClassesByFqn = Maps.uniqueIndex(classes, new Function<ObjectModelClass, String>() {
146
147 @Override
148 public String apply(ObjectModelClass input) {
149 return input.getQualifiedName();
150 }
151 });
152 List<String> beanClassesFqn = new ArrayList<>(beanClassesByFqn.keySet());
153 Collections.sort(beanClassesFqn);
154
155 String defaultPackageName = getDefaultPackageName();
156
157 String modelBeanInitializeClassName = model.getName() + "ModelInitializer";
158 boolean generateModelInitializer = !getResourcesHelper().isJavaFileInClassPath(defaultPackageName + "." + modelBeanInitializeClassName);
159 if (generateModelInitializer) {
160
161 ObjectModelInterface anInterface = createInterface(modelBeanInitializeClassName, defaultPackageName);
162
163 addOperation(anInterface, "start", "void");
164 addOperation(anInterface, "end", "void");
165
166 for (String fqn : beanClassesFqn) {
167 ObjectModelClass beanClass = beanClassesByFqn.get(fqn);
168 String beanName = classesNameTranslation.get(beanClass);
169 addImport(anInterface, beanName);
170 addOperation(anInterface, "init" + beanName, "void");
171
172 }
173 }
174
175 String modelInitializerRunnerClassName = model.getName() + "ModelInitializerRunner";
176 boolean generateInitializerRunnerClassName = !getResourcesHelper().isJavaFileInClassPath(defaultPackageName + "." + modelInitializerRunnerClassName);
177 if (generateInitializerRunnerClassName) {
178
179 ObjectModelClass aClass = createClass(modelInitializerRunnerClassName, defaultPackageName);
180
181 StringBuilder bodyBuilder = new StringBuilder();
182 bodyBuilder.append(""
183
184
185 );
186 for (String fqn : beanClassesFqn) {
187 ObjectModelClass beanClass = beanClassesByFqn.get(fqn);
188 String beanName = classesNameTranslation.get(beanClass);
189 addImport(aClass, beanName);
190 bodyBuilder.append(""
191
192
193 );
194
195 }
196
197 bodyBuilder.append(""
198
199
200 );
201 ObjectModelOperation operation = addOperation(aClass, "init", "void", ObjectModelJavaModifier.STATIC);
202 addParameter(operation, modelBeanInitializeClassName, "initializer");
203 setOperationBody(operation, bodyBuilder.toString());
204 }
205
206 }
207
208 @Override
209 public void transformFromClass(ObjectModelClass input) {
210
211 ObjectModelPackage aPackage = getPackage(input);
212
213 if (classes.contains(input)) {
214
215 String prefix = getConstantPrefix(input);
216 setConstantPrefix(prefix);
217
218 String className = classesNameTranslation.get(input);
219 String generatedClassName = "Generated" + className;
220
221 boolean generateClass = notFoundInClassPath(input, className);
222 if (generateClass) {
223 generateClass(input, className, generatedClassName);
224 }
225
226 boolean generateGeneratedClass = canGenerateAbstractClass(input, generatedClassName);
227 if (generateGeneratedClass) {
228 generateGeneratedClass(aPackage, input, generatedClassName);
229 }
230
231 boolean generateHelper = helpers.contains(input);
232 if (generateHelper) {
233
234 String helperClassName = helpersNameTranslation.get(input);
235 String generatedHelperClassName = "Generated" + helperClassName;
236
237 if (notFoundInClassPath(input, helperClassName)) {
238
239 generateHelper(input, generatedHelperClassName, helperClassName);
240 }
241
242 if (canGenerateAbstractClass(input, generatedHelperClassName)) {
243
244 generateGeneratedHelper(aPackage, input, className, generatedHelperClassName);
245 }
246
247 }
248
249 }
250
251 }
252
253 protected ObjectModelClass generateClass(ObjectModelClass input,
254 String className,
255 String abstractClassName) {
256
257 ObjectModelClass output;
258
259 if (input.isAbstract()) {
260 output = createAbstractClass(className, input.getPackageName());
261 } else {
262 output = createClass(className, input.getPackageName());
263 }
264
265 setSuperClass(output, abstractClassName);
266
267 if (log.isDebugEnabled()) {
268 log.debug("will generate " + output.getQualifiedName());
269 }
270
271 addSerializable(input, output, true);
272
273 return output;
274 }
275
276 protected ObjectModelClass generateGeneratedClass(ObjectModelPackage aPackage,
277 ObjectModelClass input,
278 String className) {
279
280 String superClass = null;
281
282
283 boolean superClassIsBean = false;
284 Collection<ObjectModelClass> superclasses = input.getSuperclasses();
285 if (CollectionUtils.isNotEmpty(superclasses)) {
286 for (ObjectModelClass superclass : superclasses) {
287 superClassIsBean = classes.contains(superclass);
288 if (superClassIsBean) {
289 superClass = superclass.getPackageName() + "." + classesNameTranslation.get(superclass);
290 break;
291 }
292 superClass = superclass.getQualifiedName();
293 }
294 }
295
296 if (!superClassIsBean) {
297
298
299 superClass = beanTagValues.getSuperClassTagValue(input, aPackage, model);
300 if (superClass != null) {
301
302
303 superClassIsBean = true;
304 }
305 }
306
307 ObjectModelClass output;
308
309 output = createAbstractClass(className, input.getPackageName());
310
311 if (superClass != null) {
312 setSuperClass(output, superClass);
313 }
314 if (log.isDebugEnabled()) {
315 log.debug("will generate " + output.getQualifiedName());
316 }
317
318 boolean serializableFound;
319
320 serializableFound = addInterfaces(input, output, null);
321
322 generateI18nBlockAndConstants(aPackage, input, output);
323
324 addSerializable(input, output, serializableFound || superClassIsBean);
325
326
327 List<ObjectModelAttribute> properties = getProperties(input);
328
329 boolean usePCS = beanTagValues.isGeneratePropertyChangeSupport(input, aPackage, model);
330 boolean generateBooleanGetMethods = eugeneTagValues.isGenerateBooleanGetMethods(input, aPackage, model);
331 boolean generateNotEmptyCollections = beanTagValues.isGenerateNotEmptyCollections(input, aPackage, model);
332
333
334 for (ObjectModelAttribute attr : properties) {
335
336 createProperty(output,
337 attr,
338 usePCS,
339 generateBooleanGetMethods,
340 generateNotEmptyCollections);
341 }
342
343 if (!superClassIsBean) {
344 addDefaultMethodForNoneBeanSuperClass(output, usePCS, properties);
345 }
346 return output;
347 }
348
349 protected void generateHelper(ObjectModelClass aClass, String abstractClassName, String defaultClassName) {
350
351 String packageName = aClass.getPackageName();
352
353 ObjectModelClass output = createClass(defaultClassName, packageName);
354 setSuperClass(output, packageName + "." + abstractClassName);
355 if (log.isDebugEnabled()) {
356 log.debug("will generate " + output.getQualifiedName());
357 }
358
359 }
360
361 protected void generateGeneratedHelper(ObjectModelPackage aPackage,
362 ObjectModelClass aClass,
363 String typeName,
364 String abstractClassName) {
365
366 ObjectModelClass output = createAbstractClass(abstractClassName, aPackage.getName());
367 String superClassName = getGeneratedHelperSuperClassName(aPackage, aClass);
368
369 if (StringUtils.isNotBlank(superClassName)) {
370 setSuperClass(output, superClassName);
371 }
372
373 if (log.isDebugEnabled()) {
374 log.debug("will generate " + output.getQualifiedName());
375 }
376
377 addImport(output, Binder.class);
378 addImport(output, BinderFactory.class);
379
380 ObjectModelOperation operation = addOperation(
381 output,
382 "typeOf" + typeName,
383 "<BeanType extends " + typeName + "> Class<BeanType>",
384 ObjectModelJavaModifier.STATIC,
385 ObjectModelJavaModifier.PUBLIC
386 );
387 setOperationBody(operation, ""
388
389
390
391 );
392
393 boolean generateConstructors = beanTagValues.isGenerateHelperConstructors(aClass, aPackage, model) && !aClass.isAbstract();
394 if (generateConstructors) {
395 generateGeneratedHelperConstructors(output, typeName);
396 }
397
398 generateGeneratedHelperCopyMethods(output, typeName);
399
400 boolean generatePredicates = beanTagValues.isGenerateHelperPredicates(aClass, aPackage, model);
401 if (generatePredicates) {
402 generateGeneratedHelperPredicates(aClass, output, typeName);
403 }
404
405 boolean generateFunctions = beanTagValues.isGenerateHelperFunctions(aClass, aPackage, model);
406 if (generateFunctions) {
407 generateGeneratedHelperFunctions(aClass, output, typeName);
408 }
409
410 }
411
412 protected void generateGeneratedHelperConstructors(ObjectModelClass output, String typeName) {
413
414 ObjectModelOperation operation = addOperation(
415 output,
416 "new" + typeName,
417 typeName,
418 ObjectModelJavaModifier.STATIC,
419 ObjectModelJavaModifier.PUBLIC
420 );
421 setOperationBody(operation, ""
422
423
424
425 );
426
427 operation = addOperation(
428 output,
429 "new" + typeName,
430 "<BeanType extends " + typeName + "> BeanType",
431 ObjectModelJavaModifier.STATIC,
432 ObjectModelJavaModifier.PUBLIC
433 );
434 addParameter(operation, "BeanType", "source");
435 setOperationBody(operation, ""
436
437
438
439
440
441
442 );
443
444 operation = addOperation(
445 output,
446 "new" + typeName,
447 "<BeanType extends " + typeName + "> BeanType",
448 ObjectModelJavaModifier.STATIC,
449 ObjectModelJavaModifier.PUBLIC
450 );
451 addParameter(operation, "BeanType", "source");
452 addParameter(operation, "Binder<BeanType, BeanType>", "binder");
453 setOperationBody(operation, ""
454
455
456
457
458
459 );
460
461 }
462
463 protected void generateGeneratedHelperCopyMethods(ObjectModelClass output, String typeName) {
464
465 ObjectModelOperation operation = addOperation(
466 output,
467 "copy" + typeName,
468 "<BeanType extends " + typeName + "> void",
469 ObjectModelJavaModifier.STATIC,
470 ObjectModelJavaModifier.PUBLIC
471 );
472 addParameter(operation, "BeanType", "source");
473 addParameter(operation, "BeanType", "target");
474 setOperationBody(operation, ""
475
476
477
478
479
480 );
481
482 operation = addOperation(
483 output,
484 "copy" + typeName,
485 "<BeanType extends " + typeName + "> void",
486 ObjectModelJavaModifier.STATIC,
487 ObjectModelJavaModifier.PUBLIC
488 );
489 addParameter(operation, "BeanType", "source");
490 addParameter(operation, "BeanType", "target");
491 addParameter(operation, "Binder<BeanType, BeanType>", "binder");
492 setOperationBody(operation, ""
493
494
495
496 );
497
498 }
499
500 protected void generateGeneratedHelperPredicates(ObjectModelClass input, ObjectModelClass output, String typeName) {
501
502 boolean atLeastOnePropertyFound = false;
503 for (ObjectModelAttribute attribute : getProperties(input)) {
504
505 boolean multiple = JavaGeneratorUtil.isNMultiplicity(attribute);
506
507 if (multiple) {
508 continue;
509 }
510
511 atLeastOnePropertyFound = true;
512 String attrName = getAttributeName(attribute);
513 String attrType = getAttributeTypeWithGeneric(attribute);
514 addImport(output, attrType);
515
516 String simpleType = JavaGeneratorUtil.getSimpleName(attrType);
517
518 String capitalizeAttrName = JavaGeneratorUtil.capitalizeJavaBeanPropertyName(attrName);
519 String newPreficateMethodName = "new" + capitalizeAttrName + "Predicate";
520
521 ObjectModelOperation operation;
522
523
524 operation = addOperation(
525 output,
526 newPreficateMethodName,
527 "<BeanType extends " + typeName + "> Predicate<BeanType>",
528 ObjectModelJavaModifier.STATIC,
529 ObjectModelJavaModifier.PUBLIC
530 );
531 addParameter(operation, simpleType, attrName);
532 String getterName = getGetterName(attribute, attrName);
533
534 if (useJava8) {
535 setOperationBody(operation, ""
536
537
538
539
540 );
541 } else {
542 setOperationBody(operation, ""
543
544
545
546
547
548
549
550
551
552
553
554 );
555 }
556
557 operation = addOperation(
558 output,
559 "filterBy" + capitalizeAttrName,
560 "<BeanType extends " + typeName + "> List<BeanType>",
561 ObjectModelJavaModifier.STATIC,
562 ObjectModelJavaModifier.PUBLIC
563 );
564 addParameter(operation, "Collection<BeanType>", "$source");
565 addParameter(operation, simpleType, attrName);
566
567 if (useJava8) {
568 setOperationBody(operation, ""
569
570
571
572 );
573 } else {
574 addImport(output, Collection.class);
575 addImport(output, List.class);
576 addImport(output, Lists.class);
577 setOperationBody(operation, ""
578
579
580
581 );
582 }
583 }
584
585 if (atLeastOnePropertyFound) {
586 if (useJava8) {
587
588 addImport(output, Collection.class);
589 addImport(output, List.class);
590 addImport(output, "java.util.Objects");
591 addImport(output, "java.util.function.Predicate");
592 addImport(output, "java.util.stream.Collectors");
593 } else {
594 addImport(output, com.google.common.base.Objects.class);
595 addImport(output, com.google.common.base.Predicate.class);
596 addImport(output, com.google.common.collect.Iterables.class);
597 }
598 addImport(output, Iterable.class);
599 }
600
601 }
602
603 protected void generateGeneratedHelperFunctions(ObjectModelClass input, ObjectModelClass output, String typeName) {
604
605 boolean atLeastOnePropertyFound = false;
606 for (ObjectModelAttribute attribute : getProperties(input)) {
607
608 boolean multiple = JavaGeneratorUtil.isNMultiplicity(attribute);
609
610 if (multiple) {
611 continue;
612 }
613
614 atLeastOnePropertyFound = true;
615
616 String attrName = getAttributeName(attribute);
617 String attrType = getAttributeTypeWithGeneric(attribute);
618 addImport(output, attrType);
619
620 String simpleType = JavaGeneratorUtil.getSimpleName(attrType);
621 simpleType = wrapPrimitiveType(simpleType);
622 String capitalizeAttrName = JavaGeneratorUtil.capitalizeJavaBeanPropertyName(attrName);
623 String getterName = getGetterName(attribute, attrName);
624
625 String newFunctionMethodName = "new" + capitalizeAttrName + "Function";
626 String getFunctionMethodName = "get" + capitalizeAttrName + "Function";
627 String functionTypeName = "Function<BeanType, " + simpleType + ">";
628
629 String functionFieldName = JavaGeneratorUtil.convertVariableNameToConstantName(capitalizeAttrName + "Function");
630 addAttribute(
631 output,
632 functionFieldName,
633 "Function<" + typeName + ", " + simpleType + ">",
634 useJava8 ? typeName + "::" + getterName : newFunctionMethodName + "()",
635 ObjectModelJavaModifier.FINAL,
636 ObjectModelJavaModifier.STATIC,
637 useJava8 ? ObjectModelJavaModifier.PUBLIC : ObjectModelJavaModifier.PROTECTED
638 );
639
640 if (!useJava8) {
641 ObjectModelOperation operation = addOperation(
642 output,
643 getFunctionMethodName,
644 "<BeanType extends " + typeName + "> " + functionTypeName,
645 ObjectModelJavaModifier.STATIC,
646 ObjectModelJavaModifier.PUBLIC
647 );
648
649
650 setOperationBody(operation, ""
651
652
653
654
655 );
656
657 operation = addOperation(
658 output,
659 newFunctionMethodName,
660 "<BeanType extends " + typeName + "> " + functionTypeName,
661 ObjectModelJavaModifier.STATIC,
662 ObjectModelJavaModifier.PUBLIC
663 );
664
665 setOperationBody(operation, ""
666
667
668
669
670
671
672
673
674
675
676 );
677 }
678
679 ObjectModelOperation operation = addOperation(
680 output,
681 "uniqueIndexBy" + capitalizeAttrName,
682 "<BeanType extends " + typeName + "> ImmutableMap<" + simpleType + ", BeanType>",
683 ObjectModelJavaModifier.STATIC,
684 ObjectModelJavaModifier.PUBLIC
685 );
686 addParameter(operation, "Iterable<BeanType>", "$source");
687 if (useJava8) {
688 setOperationBody(operation, ""
689
690
691
692 );
693 } else {
694 setOperationBody(operation, ""
695
696
697
698 );
699 }
700 }
701
702 if (atLeastOnePropertyFound) {
703 if (useJava8) {
704 addImport(output, "java.util.function.Function");
705 addImport(output, "java.util.Objects");
706 } else {
707 addImport(output, Function.class);
708 addImport(output, com.google.common.collect.Iterables.class);
709 addImport(output, com.google.common.base.Objects.class);
710 }
711
712 addImport(output, ImmutableMap.class);
713 addImport(output, Iterable.class);
714 addImport(output, Maps.class);
715 }
716
717 }
718
719 protected String getGeneratedHelperSuperClassName(ObjectModelPackage aPackage, ObjectModelClass aClass) {
720 String superClassName = null;
721
722
723 boolean superClassIsBean = false;
724 Collection<ObjectModelClass> superclasses = aClass.getSuperclasses();
725 if (CollectionUtils.isNotEmpty(superclasses)) {
726 for (ObjectModelClass superclass : superclasses) {
727 superClassIsBean = helpers.contains(superclass);
728 if (superClassIsBean) {
729 superClassName = superclass.getPackageName() + "." + helpersNameTranslation.get(superclass);
730 break;
731 }
732 superClassName = superclass.getQualifiedName();
733 }
734 }
735
736 if (!superClassIsBean) {
737
738
739 superClassName = beanTagValues.getHelperSuperClassTagValue(aClass, aPackage, model);
740
741 }
742 return superClassName;
743 }
744
745 protected String getAttributeType(ObjectModelAttribute attr) {
746 String attrType = attr.getType();
747 if (attr.hasAssociationClass()) {
748 attrType = attr.getAssociationClass().getName();
749 }
750 return getAttributeType(attrType);
751 }
752
753 protected String getAttributeType(String attrType) {
754 if (!JavaGeneratorUtil.isPrimitiveType(attrType)) {
755 boolean hasClass = model.hasClass(attrType);
756 if (hasClass) {
757 ObjectModelClass attributeClass = model.getClass(attrType);
758 String attributeType = classesNameTranslation.get(attributeClass);
759 if (attributeType != null) {
760 attrType = attributeClass.getPackageName() + "." + attributeType;
761 }
762 }
763 }
764 return attrType;
765 }
766
767 protected boolean notFoundInClassPath(ObjectModelClass input, String className) {
768 String fqn = input.getPackageName() + "." + className;
769 boolean inClassPath = getResourcesHelper().isJavaFileInClassPath(fqn);
770 return !inClassPath;
771 }
772
773 protected void createProperty(ObjectModelClass output,
774 ObjectModelAttribute attr,
775 boolean usePCS,
776 boolean generateBooleanGetMethods,
777 boolean generateNotEmptyCollections) {
778
779 String attrName = getAttributeName(attr);
780 String attrType = getAttributeTypeWithGeneric(attr);
781
782 boolean multiple = JavaGeneratorUtil.isNMultiplicity(attr);
783
784 String constantName = getConstantName(attrName);
785 String simpleType = JavaGeneratorUtil.getSimpleName(attrType);
786
787 if (multiple) {
788
789 createGetChildMethod(output,
790 attrName,
791 attrType,
792 simpleType
793 );
794
795 createIsEmptyMethod(output, attrName);
796
797 createSizeMethod(output, attrName);
798
799 createAddChildMethod(output,
800 attrName,
801 attrType,
802 constantName,
803 usePCS
804 );
805
806 createAddAllChildrenMethod(output,
807 attrName,
808 attrType,
809 constantName,
810 usePCS
811 );
812
813 createRemoveChildMethod(output,
814 attrName,
815 attrType,
816 constantName,
817 usePCS
818 );
819
820 createRemoveAllChildrenMethod(output,
821 attrName,
822 attrType,
823 constantName,
824 usePCS
825 );
826
827 createContainsChildMethod(output,
828 attrName,
829 attrType,
830 constantName,
831 usePCS
832 );
833
834 createContainsAllChildrenMethod(output,
835 attrName,
836 attrType,
837 constantName
838 );
839
840
841 attrType = JavaGeneratorUtil.getAttributeInterfaceType(attr, getAttributeTypeWithGeneric(attr), true);
842 simpleType = JavaGeneratorUtil.getSimpleName(attrType);
843 }
844
845 boolean booleanProperty = JavaGeneratorUtil.isBooleanPrimitive(attr);
846
847 if (multiple) {
848
849 String collectionImplementationType = JavaGeneratorUtil.getAttributeImplementationType(attr, getAttributeTypeWithGeneric(attr), true);
850
851
852 createGetMethod(output,
853 attrName,
854 attrType,
855 JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX,
856 generateNotEmptyCollections,
857 collectionImplementationType
858 );
859
860 } else {
861
862 if (booleanProperty) {
863
864
865 createGetMethod(output,
866 attrName,
867 attrType,
868 JavaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX
869 );
870 }
871
872 if (!booleanProperty || generateBooleanGetMethods) {
873
874
875 createGetMethod(output,
876 attrName,
877 attrType,
878 JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX
879 );
880
881 }
882
883
884 }
885
886 createSetMethod(output,
887 attrName,
888 attrType,
889 simpleType,
890 constantName,
891 usePCS
892 );
893
894
895 addAttribute(output,
896 attrName,
897 attrType,
898 "",
899 ObjectModelJavaModifier.PROTECTED
900 );
901
902 }
903
904 protected List<ObjectModelAttribute> getProperties(ObjectModelClass input) {
905 List<ObjectModelAttribute> attributes =
906 (List<ObjectModelAttribute>) input.getAttributes();
907
908 List<ObjectModelAttribute> attrs =
909 new ArrayList<>();
910 for (ObjectModelAttribute attr : attributes) {
911 if (attr.isNavigable()) {
912
913
914 attrs.add(attr);
915 }
916 }
917 return attrs;
918 }
919
920 protected void createGetMethod(ObjectModelClass output,
921 String attrName,
922 String attrType,
923 String methodPrefix,
924 boolean generateLayzCode,
925 String collectionImplementationType) {
926
927 ObjectModelOperation operation = addOperation(
928 output,
929 getJavaBeanMethodName(methodPrefix, attrName),
930 attrType,
931 ObjectModelJavaModifier.PUBLIC
932 );
933 if (generateLayzCode) {
934 addImport(output, collectionImplementationType);
935 String implementationSimpleType = JavaGeneratorUtil.getSimpleName(collectionImplementationType);
936 setOperationBody(operation, ""
937
938
939
940
941
942
943 );
944 } else {
945 setOperationBody(operation, ""
946
947
948
949 );
950 }
951
952 }
953
954 protected void createGetMethod(ObjectModelClass output,
955 String attrName,
956 String attrType,
957 String methodPrefix) {
958
959 ObjectModelOperation operation = addOperation(
960 output,
961 getJavaBeanMethodName(methodPrefix, attrName),
962 attrType,
963 ObjectModelJavaModifier.PUBLIC
964 );
965 setOperationBody(operation, ""
966
967
968
969 );
970 }
971
972 protected void createGetChildMethod(ObjectModelClass output,
973 String attrName,
974 String attrType,
975 String simpleType) {
976 ObjectModelOperation operation = addOperation(
977 output,
978 getJavaBeanMethodName("get", attrName),
979 attrType,
980 ObjectModelJavaModifier.PUBLIC
981 );
982 addParameter(operation, "int", "index");
983 setOperationBody(operation, ""
984
985
986
987
988 );
989 }
990
991 protected void createIsEmptyMethod(ObjectModelClass output,
992 String attrName) {
993 ObjectModelOperation operation = addOperation(
994 output,
995 getJavaBeanMethodName("is", attrName) + "Empty",
996 boolean.class,
997 ObjectModelJavaModifier.PUBLIC
998 );
999 setOperationBody(operation, ""
1000
1001
1002
1003 );
1004 }
1005
1006 protected void createSizeMethod(ObjectModelClass output,
1007 String attrName) {
1008 ObjectModelOperation operation = addOperation(
1009 output,
1010 getJavaBeanMethodName("size", attrName),
1011 int.class,
1012 ObjectModelJavaModifier.PUBLIC
1013 );
1014 setOperationBody(operation, ""
1015
1016
1017
1018 );
1019 }
1020
1021 protected void createAddChildMethod(ObjectModelClass output,
1022 String attrName,
1023 String attrType,
1024 String constantName,
1025 boolean usePCS) {
1026 ObjectModelOperation operation = addOperation(
1027 output,
1028 getJavaBeanMethodName("add", attrName),
1029 "void",
1030 ObjectModelJavaModifier.PUBLIC
1031 );
1032 addParameter(operation, attrType, attrName);
1033
1034 String methodName = getJavaBeanMethodName("get", attrName);
1035 StringBuilder buffer = new StringBuilder(""
1036
1037
1038
1039 );
1040 if (usePCS) {
1041 buffer.append(""
1042
1043
1044 );
1045 }
1046 setOperationBody(operation, buffer.toString());
1047 }
1048
1049 protected void createAddAllChildrenMethod(ObjectModelClass output,
1050 String attrName,
1051 String attrType,
1052 String constantName,
1053 boolean usePCS) {
1054 ObjectModelOperation operation = addOperation(
1055 output,
1056 getJavaBeanMethodName("addAll", attrName),
1057 "void",
1058 ObjectModelJavaModifier.PUBLIC
1059 );
1060 addParameter(operation, "java.util.Collection<" + attrType + ">", attrName);
1061
1062 String methodName = getJavaBeanMethodName("get", attrName);
1063 StringBuilder buffer = new StringBuilder(""
1064
1065
1066
1067 );
1068 if (usePCS) {
1069 buffer.append(""
1070
1071
1072 );
1073 }
1074 setOperationBody(operation, buffer.toString());
1075 }
1076
1077 protected void createRemoveChildMethod(ObjectModelClass output,
1078 String attrName,
1079 String attrType,
1080 String constantName,
1081 boolean usePCS) {
1082 ObjectModelOperation operation = addOperation(
1083 output,
1084 getJavaBeanMethodName("remove", attrName),
1085 "boolean",
1086 ObjectModelJavaModifier.PUBLIC
1087 );
1088 addParameter(operation, attrType, attrName);
1089 String methodName = getJavaBeanMethodName("get", attrName);
1090 StringBuilder buffer = new StringBuilder();
1091 buffer.append(""
1092
1093
1094 );
1095
1096 if (usePCS) {
1097 buffer.append(""
1098
1099
1100
1101
1102 );
1103 }
1104 buffer.append(""
1105
1106
1107
1108 );
1109 setOperationBody(operation, buffer.toString());
1110 }
1111
1112 protected void createRemoveAllChildrenMethod(ObjectModelClass output,
1113 String attrName,
1114 String attrType,
1115 String constantName,
1116 boolean usePCS) {
1117
1118 ObjectModelOperation operation = addOperation(
1119 output,
1120 getJavaBeanMethodName("removeAll", attrName),
1121 "boolean",
1122 ObjectModelJavaModifier.PUBLIC
1123 );
1124 addParameter(operation, "java.util.Collection<" + attrType + ">", attrName);
1125 StringBuilder buffer = new StringBuilder();
1126 String methodName = getJavaBeanMethodName("get", attrName);
1127 buffer.append(""
1128
1129
1130 );
1131
1132 if (usePCS) {
1133 buffer.append(""
1134
1135
1136
1137
1138 );
1139 }
1140 buffer.append(""
1141
1142
1143
1144 );
1145 setOperationBody(operation, buffer.toString());
1146 }
1147
1148 protected void createContainsChildMethod(ObjectModelClass output,
1149 String attrName,
1150 String attrType,
1151 String constantName,
1152 boolean usePCS) {
1153
1154 ObjectModelOperation operation = addOperation(
1155 output,
1156 getJavaBeanMethodName("contains", attrName),
1157 "boolean",
1158 ObjectModelJavaModifier.PUBLIC
1159 );
1160 addParameter(operation, attrType, attrName);
1161 StringBuilder buffer = new StringBuilder();
1162 String methodName = getJavaBeanMethodName("get", attrName);
1163 buffer.append(""
1164
1165
1166
1167
1168 );
1169 setOperationBody(operation, buffer.toString());
1170 }
1171
1172 protected void createContainsAllChildrenMethod(ObjectModelClass output,
1173 String attrName,
1174 String attrType,
1175 String constantName) {
1176
1177 ObjectModelOperation operation = addOperation(
1178 output,
1179 getJavaBeanMethodName("containsAll", attrName),
1180 "boolean",
1181 ObjectModelJavaModifier.PUBLIC
1182 );
1183 addParameter(operation, "java.util.Collection<" + attrType + ">", attrName);
1184 StringBuilder buffer = new StringBuilder();
1185 String methodName = getJavaBeanMethodName("get", attrName);
1186 buffer.append(""
1187
1188
1189
1190
1191 );
1192 setOperationBody(operation, buffer.toString());
1193 }
1194
1195 protected void createSetMethod(ObjectModelClass output,
1196 String attrName,
1197 String attrType,
1198 String simpleType,
1199 String constantName,
1200 boolean usePCS) {
1201 boolean booleanProperty = GeneratorUtil.isBooleanPrimitive(simpleType);
1202 ObjectModelOperation operation = addOperation(
1203 output,
1204 getJavaBeanMethodName("set", attrName),
1205 "void",
1206 ObjectModelJavaModifier.PUBLIC
1207 );
1208 addParameter(operation, attrType, attrName);
1209
1210 if (usePCS) {
1211 String methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX;
1212 if (booleanProperty) {
1213 methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX;
1214 }
1215 String methodName = getJavaBeanMethodName(methodPrefix, attrName);
1216 setOperationBody(operation, ""
1217
1218
1219
1220
1221
1222 );
1223 } else {
1224 setOperationBody(operation, ""
1225
1226
1227
1228 );
1229 }
1230 }
1231
1232 protected void addSerializable(ObjectModelClass input,
1233 ObjectModelClass output,
1234 boolean interfaceFound) {
1235 if (!interfaceFound) {
1236 addInterface(output, Serializable.class);
1237 }
1238
1239
1240 long serialVersionUID = JavaGeneratorUtil.generateSerialVersionUID(input);
1241
1242 addConstant(output,
1243 JavaGeneratorUtil.SERIAL_VERSION_UID,
1244 "long",
1245 serialVersionUID + "L",
1246 ObjectModelJavaModifier.PRIVATE
1247 );
1248 }
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259 protected boolean addInterfaces(ObjectModelClass input,
1260 ObjectModelClassifier output,
1261 String extraInterfaceName) {
1262 boolean foundSerializable = false;
1263 Set<String> added = new HashSet<>();
1264 for (ObjectModelInterface parentInterface : input.getInterfaces()) {
1265 String fqn = parentInterface.getQualifiedName();
1266 added.add(fqn);
1267 addInterface(output, fqn);
1268 if (Serializable.class.getName().equals(fqn)) {
1269 foundSerializable = true;
1270 }
1271 }
1272 if (extraInterfaceName != null && !added.contains(extraInterfaceName)) {
1273 addInterface(output, extraInterfaceName);
1274 }
1275 return foundSerializable;
1276 }
1277
1278 protected void createPropertyChangeSupport(ObjectModelClass output) {
1279
1280 addAttribute(output,
1281 "pcs",
1282 PropertyChangeSupport.class,
1283 "new PropertyChangeSupport(this)",
1284 ObjectModelJavaModifier.PROTECTED,
1285 ObjectModelJavaModifier.FINAL,
1286 ObjectModelJavaModifier.TRANSIENT
1287 );
1288
1289
1290
1291 ObjectModelOperation operation;
1292
1293 operation = addOperation(output,
1294 "addPropertyChangeListener",
1295 "void",
1296 ObjectModelJavaModifier.PUBLIC
1297 );
1298 addParameter(operation, PropertyChangeListener.class, "listener");
1299 setOperationBody(operation, ""
1300
1301
1302
1303 );
1304
1305 operation = addOperation(output,
1306 "addPropertyChangeListener",
1307 "void",
1308 ObjectModelJavaModifier.PUBLIC
1309 );
1310 addParameter(operation, String.class, "propertyName");
1311 addParameter(operation, PropertyChangeListener.class, "listener");
1312 setOperationBody(operation, ""
1313
1314
1315
1316 );
1317
1318 operation = addOperation(output,
1319 "removePropertyChangeListener",
1320 "void",
1321 ObjectModelJavaModifier.PUBLIC
1322 );
1323 addParameter(operation, PropertyChangeListener.class, "listener");
1324 setOperationBody(operation, ""
1325
1326
1327
1328 );
1329
1330 operation = addOperation(output,
1331 "removePropertyChangeListener",
1332 "void",
1333 ObjectModelJavaModifier.PUBLIC
1334 );
1335 addParameter(operation, String.class, "propertyName");
1336 addParameter(operation, PropertyChangeListener.class, "listener");
1337 setOperationBody(operation, ""
1338
1339
1340
1341 );
1342
1343 operation = addOperation(output,
1344 "firePropertyChange",
1345 "void",
1346 ObjectModelJavaModifier.PROTECTED
1347 );
1348 addParameter(operation, String.class, "propertyName");
1349 addParameter(operation, Object.class, "oldValue");
1350 addParameter(operation, Object.class, "newValue");
1351 setOperationBody(operation, ""
1352
1353
1354
1355 );
1356
1357 operation = addOperation(output,
1358 "firePropertyChange",
1359 "void",
1360 ObjectModelJavaModifier.PROTECTED
1361 );
1362 addParameter(operation, String.class, "propertyName");
1363 addParameter(operation, Object.class, "newValue");
1364 setOperationBody(operation, ""
1365
1366
1367
1368 );
1369 }
1370
1371 protected void createGetChildMethod(ObjectModelClass output) {
1372 ObjectModelOperation getChild = addOperation(
1373 output,
1374 "getChild", "<T> T",
1375 ObjectModelJavaModifier.PROTECTED
1376 );
1377 addImport(output, List.class);
1378
1379 addParameter(getChild, "java.util.Collection<T>", "childs");
1380 addParameter(getChild, "int", "index");
1381 setOperationBody(getChild, ""
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402 );
1403 }
1404
1405 protected void generateI18nBlockAndConstants(ObjectModelPackage aPackage,
1406 ObjectModelClass input,
1407 ObjectModelClassifier output) {
1408
1409 String i18nPrefix = eugeneTagValues.getI18nPrefixTagValue(input,
1410 aPackage,
1411 model);
1412 if (!StringUtils.isEmpty(i18nPrefix)) {
1413 generateI18nBlock(input, output, i18nPrefix);
1414 }
1415
1416 String prefix = getConstantPrefix(input);
1417
1418 setConstantPrefix(prefix);
1419
1420 Set<String> constantNames = addConstantsFromDependency(input, output);
1421
1422
1423 for (ObjectModelAttribute attr : getProperties(input)) {
1424
1425 createPropertyConstant(output, attr, prefix, constantNames);
1426 }
1427 }
1428
1429 protected void addDefaultMethodForNoneBeanSuperClass(ObjectModelClass output,
1430 boolean usePCS,
1431 List<ObjectModelAttribute> properties) {
1432
1433
1434 if (usePCS) {
1435
1436
1437 createPropertyChangeSupport(output);
1438 }
1439
1440 boolean hasAMultipleProperty = containsMultiple(properties);
1441
1442
1443 if (hasAMultipleProperty) {
1444
1445
1446 createGetChildMethod(output);
1447 }
1448 }
1449
1450 protected String wrapPrimitiveType(String attrType) {
1451 if (JavaGeneratorUtil.isPrimitiveType(attrType)) {
1452 attrType = JavaGeneratorUtil.getPrimitiveWrapType(attrType);
1453 }
1454 return attrType;
1455 }
1456
1457 protected String getGetterName(ObjectModelAttribute attribute, String attrName) {
1458 boolean booleanProperty = JavaGeneratorUtil.isBooleanPrimitive(attribute);
1459 String methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX;
1460 if (booleanProperty) {
1461 methodPrefix = JavaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX;
1462 }
1463 return getJavaBeanMethodName(methodPrefix, attrName);
1464 }
1465
1466 protected String generateName(String prefix, String name, String suffix) {
1467 StringBuilder sb = new StringBuilder();
1468 if (StringUtils.isNotEmpty(prefix)) {
1469 sb.append(prefix);
1470 }
1471 sb.append(name);
1472 if (StringUtils.isNotEmpty(suffix)) {
1473 sb.append(suffix);
1474 }
1475 return sb.toString();
1476 }
1477
1478 protected boolean canGenerateAbstractClass(ObjectModelClass aClass, String abstractClassName) {
1479
1480 boolean inClassPath = !notFoundInClassPath(aClass, abstractClassName);
1481
1482 if (inClassPath) {
1483 throw new IllegalStateException(String.format("Can't generate %s, already found in class-path, this is a generated class, you should not ovveride it.\n\nPlease remove it from class path and use the %s class instead.", aClass.getPackageName() + "." + abstractClassName, aClass));
1484 }
1485
1486 return true;
1487
1488 }
1489
1490 protected void createPropertyConstant(ObjectModelClassifier output,
1491 ObjectModelAttribute attr,
1492 String prefix,
1493 Set<String> constantNames) {
1494
1495 String attrName = getAttributeName(attr);
1496
1497 String constantName = prefix + builder.getConstantName(attrName);
1498
1499 if (!constantNames.contains(constantName)) {
1500
1501 addConstant(output,
1502 constantName,
1503 String.class,
1504 "\"" + attrName + "\"",
1505 ObjectModelJavaModifier.PUBLIC
1506 );
1507 }
1508 }
1509
1510 protected String getAttributeName(ObjectModelAttribute attr) {
1511 String attrName = attr.getName();
1512 if (attr.hasAssociationClass()) {
1513 String assocAttrName = JavaGeneratorUtil.getAssocAttrName(attr);
1514 attrName = JavaGeneratorUtil.toLowerCaseFirstLetter(assocAttrName);
1515 }
1516 return attrName;
1517 }
1518
1519 protected String getAttributeTypeWithGeneric(ObjectModelAttribute attr) {
1520 String attrType = getAttributeType(attr);
1521 String generic = eugeneTagValues.getAttributeGenericTagValue(attr);
1522 if (generic != null) {
1523 attrType += "<" + getAttributeType(generic) + ">";
1524 }
1525 return attrType;
1526 }
1527
1528 protected boolean containsMultiple(List<ObjectModelAttribute> attributes) {
1529
1530 boolean result = false;
1531
1532 for (ObjectModelAttribute attr : attributes) {
1533
1534 if (JavaGeneratorUtil.isNMultiplicity(attr)) {
1535 result = true;
1536
1537 break;
1538 }
1539
1540 }
1541 return result;
1542 }
1543
1544
1545 }