1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.nuiton.topia.generator;
25
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.commons.lang3.builder.ToStringBuilder;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.codehaus.plexus.component.annotations.Component;
31 import org.nuiton.eugene.EugeneCoreTagValues;
32 import org.nuiton.eugene.Template;
33 import org.nuiton.eugene.java.ObjectModelTransformerToJava;
34 import org.nuiton.eugene.models.object.ObjectModelAssociationClass;
35 import org.nuiton.eugene.models.object.ObjectModelAttribute;
36 import org.nuiton.eugene.models.object.ObjectModelClass;
37 import org.nuiton.eugene.models.object.ObjectModelClassifier;
38 import org.nuiton.eugene.models.object.ObjectModelInterface;
39 import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
40 import org.nuiton.eugene.models.object.ObjectModelModifier;
41 import org.nuiton.eugene.models.object.ObjectModelOperation;
42 import org.nuiton.eugene.models.object.ObjectModelParameter;
43 import org.nuiton.topia.TopiaException;
44 import org.nuiton.topia.framework.TopiaContextImplementor;
45 import org.nuiton.topia.persistence.EntityVisitor;
46 import org.nuiton.topia.persistence.TopiaEntity;
47 import org.nuiton.topia.persistence.TopiaEntityAbstract;
48 import org.nuiton.topia.persistence.TopiaEntityContextable;
49 import org.nuiton.topia.persistence.util.TopiaEntityHelper;
50
51 import java.util.ArrayList;
52 import java.util.Collection;
53 import java.util.LinkedList;
54 import java.util.List;
55 import java.util.Set;
56
57 import static org.nuiton.topia.generator.TopiaGeneratorUtil.hasUnidirectionalRelationOnAbstractType;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 @Component(role = Template.class, hint = "org.nuiton.topia.generator.EntityTransformer")
83 public class EntityTransformer extends ObjectModelTransformerToJava {
84
85
86 private static final Log log = LogFactory.getLog(EntityTransformer.class);
87
88 protected ObjectModelInterface outputInterface;
89
90 protected ObjectModelClass outputAbstract;
91
92 protected ObjectModelClass outputImpl;
93
94 private boolean associationClass;
95
96 protected boolean generateInterface;
97
98 protected boolean generateAbstract;
99
100 protected boolean generateImpl;
101
102 protected boolean generateBooleanGetMethods;
103
104 protected void clean() {
105 outputInterface = null;
106 outputAbstract = null;
107 outputImpl = null;
108 }
109
110 @Override
111 public void transformFromClass(ObjectModelClass input) {
112
113 if (!TopiaGeneratorUtil.isEntity(input)) {
114
115
116 return;
117 }
118
119 if (log.isDebugEnabled()) {
120 log.debug("for entity : " + input.getQualifiedName());
121 log.debug("Will use classLoader " + getClassLoader());
122 }
123
124
125 String prefix = getConstantPrefix(input);
126 if (StringUtils.isEmpty(prefix)) {
127
128
129 if (log.isWarnEnabled()) {
130 log.warn("[" + input.getName() + "] Will generate constants with NO prefix, not a good idea... \n" +
131 "Use '" + EugeneCoreTagValues.Store.constantPrefix +
132 "' tagvalue in your xmi properties. For example " +
133 "for all the model : model.tagvalue." + EugeneCoreTagValues.Store.constantPrefix + "=PROPERTY_");
134 }
135 }
136 setConstantPrefix(prefix);
137
138 generateInterface = isGenerateInterface(input);
139 generateAbstract = isGenerateAbstract(input);
140 generateImpl = isGenerateImpl(input);
141
142 generateBooleanGetMethods = eugeneTagValues.isGenerateBooleanGetMethods(input, null, model);
143
144 if (generateInterface) {
145
146
147 createEntityInterface(input);
148 }
149
150 if (generateAbstract) {
151
152
153 createEntityAbstractClass(input);
154 }
155
156
157 String i18nPrefix = eugeneTagValues.getI18nPrefixTagValue(input, null, model);
158 if (!StringUtils.isEmpty(i18nPrefix)) {
159 generateI18nBlock(input, outputAbstract, i18nPrefix);
160 }
161
162
163 createAcceptOperation();
164 createAcceptInternalOperation(input);
165
166
167 generateProperties(input.getAttributes());
168
169
170
171 if (input instanceof ObjectModelAssociationClass) {
172 ObjectModelAssociationClass association =
173 (ObjectModelAssociationClass)input;
174 associationClass = true;
175 generateProperties(association.getParticipantsAttributes());
176 associationClass = false;
177 }
178
179 closeAcceptInternalOperation();
180
181
182 generateExtraConstants(input);
183
184
185 generateExtraOperations(input);
186
187
188 generateAggregateOperation(input);
189 generateCompositeOperation(input);
190
191
192 if (TopiaGeneratorUtil.generateToString(input, model)) {
193 generateToStringOperation(input);
194 }
195
196
197 generateSerialVersionUID(input, outputAbstract);
198
199
200 if (generateImpl) {
201 generateImpl(input);
202 generateSerialVersionUID(input, outputImpl);
203 }
204
205
206
207
208 clean();
209 }
210
211 protected void generateSerialVersionUID(ObjectModelClass input,
212 ObjectModelClass ouput) {
213
214
215 String svUID = TopiaGeneratorUtil.findTagValue(TopiaGeneratorUtil.SERIAL_VERSION_UID,
216 input,
217 model
218 );
219 if (svUID == null) {
220
221
222 svUID = TopiaGeneratorUtil.generateSerialVersionUID(ouput) + "L";
223 }
224 addConstant(ouput, TopiaGeneratorUtil.SERIAL_VERSION_UID, long.class, svUID,
225 ObjectModelJavaModifier.PRIVATE);
226 }
227
228 protected void createEntityInterface(ObjectModelClass input) {
229
230 outputInterface = createInterface(input.getName(),
231 input.getPackageName());
232
233
234 if (TopiaGeneratorUtil.hasDocumentation(input)) {
235 setDocumentation(outputInterface, input.getDocumentation());
236 }
237
238 if (log.isTraceEnabled()) {
239 log.trace("Will add interfaces on " +
240 outputInterface.getQualifiedName());
241 }
242
243 List<String> interfaceAlreadyDone = new LinkedList<String> ();
244
245 for (ObjectModelClassifier parent : input.getInterfaces()) {
246 addInterface(interfaceAlreadyDone, outputInterface, parent);
247 }
248
249
250 boolean needTopiaEntity = true;
251 for (ObjectModelClassifier parent : input.getSuperclasses()) {
252 if (TopiaGeneratorUtil.isEntity(parent)) {
253 addInterface(interfaceAlreadyDone, outputInterface, parent);
254 needTopiaEntity = false;
255 }
256 }
257
258
259 if (needTopiaEntity) {
260
261 Class<?> interfaze = TopiaEntity.class;
262
263 if (TopiaGeneratorUtil.isContextable(input)) {
264 interfaze = TopiaEntityContextable.class;
265 }
266
267 addInterface(interfaceAlreadyDone,
268 outputInterface,
269 interfaze);
270 }
271 }
272
273 protected void createEntityAbstractClass(ObjectModelClass input) {
274
275 outputAbstract = createAbstractClass(input.getName() + "Abstract",
276 input.getPackageName());
277
278
279 StringBuilder doc = new StringBuilder();
280 doc.append("Implantation POJO pour l'entité {@link ");
281 doc.append(StringUtils.capitalize(outputInterface.getName()));
282 doc.append("}\n");
283
284 String dbName = TopiaGeneratorUtil.getDbName(input);
285 if (dbName != null) {
286 doc.append("<p>Nom de l'entité en BD : ");
287 doc.append(dbName);
288 doc.append(".</p>");
289 }
290
291 setDocumentation(outputAbstract, doc.toString());
292
293
294 addInterface(outputAbstract, outputInterface.getName());
295
296
297 for (ObjectModelClass parent : input.getSuperclasses()) {
298
299 String extendClass = TopiaGeneratorUtil.getDOType(parent, model);
300
301
302
303
304
305
306
307
308
309
310
311 setSuperClass(outputAbstract, extendClass);
312 }
313
314
315 if (outputAbstract.getSuperclasses().isEmpty()) {
316 setSuperClass(outputAbstract, TopiaEntityAbstract.class);
317 }
318
319 addContextableMethods(input, outputAbstract);
320 }
321
322
323
324
325
326
327
328 protected void addContextableMethods(ObjectModelClass input,
329 ObjectModelClass outputAbstract) {
330
331 if (TopiaGeneratorUtil.isContextable(input)) {
332
333 addImport(outputAbstract, TopiaContextImplementor.class);
334
335 ObjectModelOperation op = addOperation(outputAbstract, "update", "void",
336 ObjectModelJavaModifier.PUBLIC);
337 addException(op, TopiaException.class);
338
339 addAnnotation(outputAbstract, op, Override.class.getSimpleName());
340 setOperationBody(op, ""
341
342
343
344 );
345
346 op = addOperation(outputAbstract, "delete", "void", ObjectModelJavaModifier.PUBLIC);
347 addException(op, TopiaException.class);
348
349 addAnnotation(outputAbstract, op, Override.class.getSimpleName());
350 setOperationBody(op, ""
351
352
353
354 );
355 }
356 }
357
358 protected boolean isGenerateInterface(ObjectModelClass input) {
359
360 boolean alreadyInClassPath = !isInClassPath(input);
361 return alreadyInClassPath;
362 }
363
364 protected boolean isGenerateAbstract(ObjectModelClass input) {
365
366 String fqn = input.getQualifiedName() + " Abstract";
367 boolean alreadyInClassPath = !isInClassPath(fqn);
368 return alreadyInClassPath;
369 }
370
371 protected boolean isGenerateImpl(ObjectModelClass input) {
372
373 Collection<ObjectModelOperation> operations = input.getOperations();
374 String fqn = input.getQualifiedName() + "Impl";
375
376 boolean alreadyInClassPath = isInClassPath(fqn);
377 if (alreadyInClassPath) {
378
379 return false;
380 }
381
382
383 if (!operations.isEmpty()) {
384
385 log.info("Will not generate [" + fqn + "], there is some operations to manually implement");
386 return false;
387 }
388
389
390
391 for (ObjectModelOperation otherOp : input.getAllOtherOperations(false)) {
392 if (otherOp.isAbstract()) {
393 log.info("Will not generate [" + fqn + "], there is an abstract operation [" + otherOp.getName() + "] in allOtherOperations.");
394 return false;
395 }
396 }
397
398 return true;
399 }
400
401 protected void generateImpl(ObjectModelClass input) {
402
403 String implName = input.getName() + "Impl";
404 String packageName = input.getPackageName();
405 if (isVerbose()) {
406 log.info("Will generate [" + implName + "]");
407 }
408
409 if (isAbstract(input)) {
410 outputImpl = createAbstractClass(implName, packageName);
411 } else {
412 outputImpl = createClass(implName, packageName);
413 }
414
415 setDocumentation(outputImpl, "Implantation des operations pour l'entité " +
416 input.getName() + ".");
417 setSuperClass(outputImpl, input.getQualifiedName() + "Abstract");
418 }
419
420
421
422
423
424
425
426 protected void generateExtraConstants(ObjectModelClass input) {
427 Set<String> constants = addConstantsFromDependency(input, outputInterface);
428
429 if (log.isDebugEnabled()) {
430 log.debug("Add constants from dependency : " + constants);
431 }
432 }
433
434 protected void generateExtraOperations(ObjectModelClass input) {
435 for (ObjectModelOperation operation : input.getOperations()) {
436
437 String opName = operation.getName();
438 String opType = operation.getReturnType();
439 ObjectModelModifier visibility =
440 ObjectModelJavaModifier.fromVisibility(operation.getVisibility());
441
442 if (log.isDebugEnabled()) {
443 log.debug("Extra operation for : " + input.getQualifiedName() +
444 " - method : " + opName +
445 " - returnType : " + opType +
446 " - visibility : " + visibility);
447 }
448
449
450
451 if (TopiaGeneratorUtil.hasDaoStereotype(operation)) {
452 return;
453
454
455
456 } else if (!visibility.equals(ObjectModelJavaModifier.PUBLIC)) {
457 addOperation(outputAbstract, opName, opType, visibility,
458 ObjectModelJavaModifier.ABSTRACT);
459
460
461
462 } else {
463 cloneOperationSignature(operation, outputInterface, true);
464 }
465 }
466 }
467
468
469
470
471
472
473
474 protected void generateProperties(Collection<ObjectModelAttribute> attributes) {
475 for (ObjectModelAttribute attribute : attributes) {
476
477 if (!associationClass) {
478
479
480 if (!attribute.isNavigable() && attribute.hasAssociationClass()) {
481 generatePropertyConstant(attribute);
482
483 generatePropertyAttribute(attribute);
484
485
486
487
488 }
489
490 if (!attribute.isNavigable() &&
491 !TopiaGeneratorUtil.hasUnidirectionalRelationOnAbstractType(
492 attribute.getReverseAttribute(), model)) {
493 continue;
494 }
495 }
496
497
498 generatePropertyConstant(attribute);
499
500
501 generatePropertyAttribute(attribute);
502
503
504 generatePropertyOperations(attribute);
505
506
507 updateAcceptOperation(attribute);
508 }
509 }
510
511
512
513
514
515
516
517
518
519
520
521 protected void generatePropertyConstant(ObjectModelAttribute attribute) {
522 String attrName = getPropertyName(attribute);
523
524 if (log.isDebugEnabled()) {
525 log.debug("Generate constant for property : " + attrName);
526 }
527
528 addAttribute(outputInterface, getConstantName(attrName), String.class,
529 "\"" + attrName + "\"");
530 }
531
532 protected void generatePropertyAttribute(ObjectModelAttribute attribute) {
533
534 String attrName = getPropertyName(attribute);
535 String attrType = getPropertyType(attribute);
536 String collectionType = getCollectionType(attribute);
537
538 if (collectionType != null) {
539 attrType = collectionType + "<" + attrType + ">";
540 }
541
542
543
544
545 ObjectModelAttribute property =
546 addAttribute(outputAbstract, attrName, attrType, null,
547
548 ObjectModelJavaModifier.PROTECTED
549 );
550
551
552 StringBuilder buffer = new StringBuilder();
553 if (TopiaGeneratorUtil.hasDocumentation(attribute)) {
554 String attrDocumentation = attribute.getDocumentation();
555 buffer.append(attrDocumentation).append('\n');
556 }
557
558 String dbName = TopiaGeneratorUtil.getDbName(attribute);
559 if (!StringUtils.isEmpty(dbName)) {
560 buffer.append("Nom de l'attribut en BD : ").append(dbName).append('\n');
561 }
562 setDocumentation(property, buffer.toString());
563
564
565 String annotation = TopiaGeneratorUtil.getAnnotationTagValue(attribute);
566 if (!StringUtils.isEmpty(annotation)) {
567
568
569 addAnnotation(outputAbstract, property, annotation);
570 }
571 }
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594 protected void generatePropertyOperations(ObjectModelAttribute attribute) {
595
596 if (attribute.getMaxMultiplicity() == 1 || associationClass) {
597
598
599 addSingleSetOperation(attribute);
600
601 boolean booleanProperty =
602 TopiaGeneratorUtil.isBooleanPrimitive(attribute);
603
604 String attrType = getPropertyType(attribute);
605
606 if (booleanProperty) {
607
608
609 addSingleGetOperation(
610 attribute,
611 attrType,
612 TopiaGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX);
613 }
614
615 if (!booleanProperty || generateBooleanGetMethods) {
616
617
618 addSingleGetOperation(
619 attribute,
620 attrType,
621 TopiaGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX);
622 }
623
624 } else {
625
626
627 String collectionInterface =
628 TopiaGeneratorUtil.getNMultiplicityInterfaceType(attribute);
629 String collectionImpl =
630 TopiaGeneratorUtil.getNMultiplicityObjectType(attribute);
631
632 addImport(outputInterface, collectionInterface);
633 addImport(outputAbstract, collectionInterface);
634 addImport(outputAbstract, collectionImpl);
635
636 collectionInterface =
637 TopiaGeneratorUtil.getSimpleName(collectionInterface);
638 collectionImpl =
639 TopiaGeneratorUtil.getSimpleName(collectionImpl);
640
641
642 addMultipleAddOperation(attribute, collectionImpl);
643
644
645 addMultipleAddAllOperation(attribute, collectionInterface);
646
647
648 addMultipleSetOperation(attribute, collectionInterface, collectionImpl);
649
650
651 addMultipleRemoveOperation(attribute);
652
653
654 addMultipleClearOperation(attribute, collectionInterface, collectionImpl);
655
656
657 addMultipleGetOperation(attribute, collectionInterface);
658
659 if (TopiaGeneratorUtil.isEntity(attribute, model)) {
660
661
662 addMultipleGetTopiaIdOperation(attribute);
663 }
664
665 if (attribute.hasAssociationClass()) {
666
667 addMultipleGetOperationFromEntity(attribute);
668 }
669
670
671 addMultipleSizeOperation(attribute);
672
673
674 addMultipleIsEmptyOperation(attribute);
675 }
676 }
677
678 protected void addSingleSetOperation(ObjectModelAttribute attribute) {
679
680 String attrName = getPropertyName(attribute);
681 String attrType = getPropertyType(attribute);
682
683 if (log.isDebugEnabled()) {
684 log.debug("Generate single 'set' operation for property : " + attrName +
685 " [" + attrType + "]");
686 }
687
688
689 ObjectModelOperation interfaceOperation =
690 createPropertySetterSignature(outputInterface, attrType, attrName,
691 "");
692
693
694 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
695
696 attrType = TopiaGeneratorUtil.getSimpleName(attrType);
697
698 String constantName = getConstantName(attrName);
699
700 setOperationBody(implOperation, ""
701
702
703
704
705
706
707 );
708 }
709
710
711
712
713
714
715
716
717
718
719
720
721 protected void addSingleGetOperation(ObjectModelAttribute attribute,
722 String attrType,
723 String operationPrefix) {
724
725 String attrName = getPropertyName(attribute);
726
727 if (log.isDebugEnabled()) {
728 log.debug("Generate single '" + operationPrefix + "' operation for property : "
729 + attrName + " [" + attrType + "]");
730 }
731
732 String constantName = getConstantName(attrName);
733
734
735 ObjectModelOperation interfaceOperation =
736 addOperation(outputInterface, getJavaBeanMethodName(operationPrefix, attrName),
737 attrType, ObjectModelJavaModifier.PACKAGE);
738
739 boolean generateReadListeners = !TopiaGeneratorUtil.isDoNotGenerateReadListeners(attribute, model);
740
741
742 ObjectModelOperation implOperation =
743 createImplOperation(interfaceOperation);
744
745 attrType = TopiaGeneratorUtil.getSimpleName(attrType);
746
747 StringBuilder body = new StringBuilder();
748 if (generateReadListeners) {
749 body.append(""
750
751
752 );
753 }
754
755 body.append(""
756
757
758 );
759
760 if (generateReadListeners) {
761 body.append(""
762
763
764 );
765 }
766
767 body.append(""
768
769
770 );
771 setOperationBody(implOperation, body.toString());
772 }
773
774 protected void addMultipleAddOperation(ObjectModelAttribute attribute,
775 String collectionImpl) {
776
777 String attrName = getPropertyName(attribute);
778 String attrType = getPropertyType(attribute);
779 ObjectModelAttribute reverse = attribute.getReverseAttribute();
780
781 if (log.isDebugEnabled()) {
782 log.debug("Generate multiple 'add' operation for property : " + attrName +
783 " [" + attrType + "]");
784 }
785
786 String constantName = getConstantName(attrName);
787
788
789 ObjectModelOperation interfaceOperation =
790 addOperation(outputInterface, getJavaBeanMethodName("add", attrName),
791 void.class, ObjectModelJavaModifier.PACKAGE);
792 ObjectModelParameter param =
793 addParameter(interfaceOperation, attrType, attrName);
794
795
796 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
797
798 attrType = TopiaGeneratorUtil.getSimpleName(attrType);
799
800 StringBuilder body = new StringBuilder();
801
802 body.append(""
803
804
805
806
807
808
809 );
810
811 if (reverse != null && (reverse.isNavigable() ||
812 hasUnidirectionalRelationOnAbstractType(attribute, model))) {
813 String getterName = getJavaBeanMethodName("get", reverse.getName());
814 String setterName = getJavaBeanMethodName("set", reverse.getName());
815
816 String reverseAttrType = TopiaGeneratorUtil.getSimpleName(reverse.getType());
817
818 if (!TopiaGeneratorUtil.isNMultiplicity(reverse)) {
819 body.append(""
820
821
822
823 );
824
825 } else if (!attribute.hasAssociationClass()) {
826 body.append(""
827
828
829
830
831
832
833 );
834 }
835 }
836 body.append(""
837
838
839
840
841 );
842 setOperationBody(implOperation, body.toString());
843 }
844
845 protected void addMultipleAddAllOperation(ObjectModelAttribute attribute,
846 String collectionInterface) {
847
848 String attrName = getPropertyName(attribute);
849 String attrType = getPropertyType(attribute);
850
851 if (log.isDebugEnabled()) {
852 log.debug("Generate multiple 'addAll' operation for property : " + attrName +
853 " [" + attrType + "]");
854 }
855
856
857 ObjectModelOperation interfaceOperation =
858 addOperation(outputInterface, getJavaBeanMethodName("addAll", attrName),
859 void.class, ObjectModelJavaModifier.PACKAGE);
860 ObjectModelParameter param =
861 addParameter(interfaceOperation, collectionInterface + "<" + attrType + ">", attrName);
862
863
864 ObjectModelOperation implOperation =
865 createImplOperation(interfaceOperation);
866
867 attrType = TopiaGeneratorUtil.getSimpleName(attrType);
868 String addMethodName = getJavaBeanMethodName("add", attrName);
869 setOperationBody(implOperation, ""
870
871
872
873
874
875
876
877
878 );
879 }
880
881 protected void addMultipleSetOperation(ObjectModelAttribute attribute,
882 String collectionInterface,
883 String collectionImpl) {
884
885 String attrName = getPropertyName(attribute);
886 String referenceType = getPropertyType(attribute);
887 String attrType = collectionInterface + "<" + referenceType + ">";
888 String constantName = getConstantName(attrName);
889
890 if (log.isDebugEnabled()) {
891 log.debug("Generate multiple 'set' operation for property : " + attrName +
892 " [" + attrType + "]");
893 }
894
895
896 ObjectModelOperation interfaceOperation =
897 createPropertySetterSignature(outputInterface, attrType, attrName,
898 "");
899
900 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
901
902 attrType = TopiaGeneratorUtil.getSimpleName(attrType);
903 referenceType = TopiaGeneratorUtil.getSimpleName(referenceType);
904
905
906 setOperationBody(implOperation, ""
907
908
909
910
911
912
913
914 );
915 }
916
917 protected void addMultipleRemoveOperation(ObjectModelAttribute attribute) {
918
919 String attrName = getPropertyName(attribute);
920 String attrType = getPropertyType(attribute);
921 ObjectModelAttribute reverse = attribute.getReverseAttribute();
922 String constantName = getConstantName(attrName);
923
924 if (log.isDebugEnabled()) {
925 log.debug("Generate 'remove' operation for property : " + attrName +
926 " [" + attrType + "]");
927 }
928
929
930 ObjectModelOperation interfaceOperation =
931 addOperation(outputInterface, getJavaBeanMethodName("remove" , attrName),
932 void.class, ObjectModelJavaModifier.PACKAGE);
933 ObjectModelParameter param =
934 addParameter(interfaceOperation, attrType, attrName);
935
936
937 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
938
939 attrType = TopiaGeneratorUtil.getSimpleName(attrType);
940
941 StringBuilder body = new StringBuilder();
942
943 body.append(""
944
945
946
947
948
949
950 );
951
952 if (reverse != null && (reverse.isNavigable() ||
953 hasUnidirectionalRelationOnAbstractType(attribute, model))) {
954 String getterName = getJavaBeanMethodName("get", reverse.getName());
955 String setterName = getJavaBeanMethodName("set", reverse.getName());
956 if (!TopiaGeneratorUtil.isNMultiplicity(reverse)) {
957 body.append(""
958
959
960
961 );
962
963 } else if (!attribute.hasAssociationClass()) {
964 body.append(""
965
966
967
968 );
969 }
970 }
971 body.append(""
972
973
974
975 );
976 setOperationBody(implOperation, body.toString());
977 }
978
979 protected void addMultipleClearOperation(ObjectModelAttribute attribute,
980 String collectionInterface,
981 String collectionImpl) {
982
983 String attrName = getPropertyName(attribute);
984 String attrType = getPropertyType(attribute);
985 ObjectModelAttribute reverse = attribute.getReverseAttribute();
986 String constantName = getConstantName(attrName);
987
988 if (log.isDebugEnabled()) {
989 log.debug("Generate multiple 'clear' operation for property : " + attrName +
990 " [" + attrType + "]");
991 }
992
993
994 ObjectModelOperation interfaceOperation =
995 addOperation(outputInterface, getJavaBeanMethodName("clear" , attrName),
996 void.class, ObjectModelJavaModifier.PACKAGE);
997
998
999 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
1000
1001 attrType = TopiaGeneratorUtil.getSimpleName(attrType);
1002
1003 StringBuilder body = new StringBuilder(""
1004
1005
1006
1007
1008
1009 );
1010
1011 if (reverse != null && (reverse.isNavigable() ||
1012 hasUnidirectionalRelationOnAbstractType(attribute, model))) {
1013 String getterName = getJavaBeanMethodName("get", reverse.getName());
1014 String setterName = getJavaBeanMethodName("set", reverse.getName());
1015 body.append(""
1016
1017
1018 );
1019 if (!TopiaGeneratorUtil.isNMultiplicity(reverse)) {
1020 body.append(""
1021
1022
1023 );
1024
1025 } else if (!attribute.hasAssociationClass()) {
1026 body.append(""
1027
1028
1029 );
1030 }
1031 body.append(""
1032
1033
1034 );
1035 }
1036 body.append(""
1037
1038
1039
1040
1041
1042 );
1043 setOperationBody(implOperation, body.toString());
1044 }
1045
1046 protected void addMultipleGetOperation(ObjectModelAttribute attribute,
1047 String collectionInterface) {
1048
1049 String attrName = getPropertyName(attribute);
1050 String attrType = collectionInterface + "<" + getPropertyType(attribute) + ">";
1051
1052 if (log.isDebugEnabled()) {
1053 log.debug("Generate multiple 'get' operation for property : " + attrName +
1054 " [" + attrType + "]");
1055 }
1056
1057
1058 ObjectModelOperation interfaceOperation =
1059 addOperation(outputInterface, getJavaBeanMethodName("get" , attrName),
1060 attrType, ObjectModelJavaModifier.PACKAGE);
1061
1062
1063 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
1064
1065 setOperationBody(implOperation, ""
1066
1067
1068
1069 );
1070 }
1071
1072 protected void addMultipleGetTopiaIdOperation(ObjectModelAttribute attribute) {
1073
1074 String attrName = getPropertyName(attribute);
1075 String attrType = getPropertyType(attribute);
1076
1077 if (log.isDebugEnabled()) {
1078 log.debug("Generate multiple 'getByTopiaId' operation for property : " + attrName +
1079 " [" + attrType + "]");
1080 }
1081
1082
1083 ObjectModelOperation interfaceOperation =
1084 addOperation(outputInterface, getJavaBeanMethodName("get", attrName) + "ByTopiaId",
1085 attrType, ObjectModelJavaModifier.PACKAGE);
1086 ObjectModelParameter param =
1087 addParameter(interfaceOperation, String.class, "topiaId");
1088
1089
1090 ObjectModelOperation implOperation =
1091 createImplOperation(interfaceOperation);
1092
1093 addImport(outputAbstract, TopiaEntityHelper.class);
1094
1095 setOperationBody(implOperation, ""
1096
1097
1098
1099 );
1100 }
1101
1102 protected void addMultipleGetOperationFromEntity(ObjectModelAttribute attribute) {
1103
1104
1105 String referenceName = attribute.getName();
1106 String referenceType = attribute.getType();
1107
1108 String referenceGetterName = getJavaBeanMethodName("get", referenceName);
1109
1110 String attrName = getPropertyName(attribute);
1111 String attrType = getPropertyType(attribute);
1112
1113 if (log.isDebugEnabled()) {
1114 log.debug("Generate multiple 'getFromEntity' operation for property : " + attrName +
1115 " [" + attrType + "]");
1116 }
1117
1118
1119 ObjectModelOperation interfaceOperation =
1120 addOperation(outputInterface,
1121 getJavaBeanMethodName("get", attrName), attrType);
1122
1123 addParameter(interfaceOperation, referenceType, referenceName);
1124
1125
1126 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
1127
1128 attrType = TopiaGeneratorUtil.getSimpleName(attrType);
1129
1130 setOperationBody(implOperation, ""
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142 );
1143 }
1144
1145 protected void addMultipleSizeOperation(ObjectModelAttribute attribute) {
1146
1147 String attrName = getPropertyName(attribute);
1148
1149 if (log.isDebugEnabled()) {
1150 log.debug("Generate multiple 'size' operation for property : " + attrName);
1151 }
1152
1153
1154 ObjectModelOperation interfaceOperation =
1155 addOperation(outputInterface, getJavaBeanMethodName("size", attrName),
1156 int.class, ObjectModelJavaModifier.PACKAGE);
1157
1158
1159 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
1160
1161 setOperationBody(implOperation, ""
1162
1163
1164
1165
1166
1167
1168 );
1169 }
1170
1171 protected void addMultipleIsEmptyOperation(ObjectModelAttribute attribute) {
1172
1173 String attrName = getPropertyName(attribute);
1174
1175 if (log.isDebugEnabled()) {
1176 log.debug("Generate multiple 'isEmpty' operation for property : " + attrName);
1177 }
1178
1179 String sizeMethodName = getJavaBeanMethodName("size", attrName);
1180
1181 ObjectModelOperation interfaceOperation =
1182 addOperation(outputInterface, getJavaBeanMethodName("is", attrName)+ "Empty",
1183 boolean.class, ObjectModelJavaModifier.PACKAGE);
1184
1185
1186 ObjectModelOperation implOperation = createImplOperation(interfaceOperation);
1187
1188 setOperationBody(implOperation, ""
1189
1190
1191
1192
1193 );
1194 }
1195
1196
1197
1198
1199
1200 private ObjectModelOperation internalAcceptOperation;
1201
1202 private StringBuilder internalAcceptOperationBody;
1203
1204 protected void createAcceptOperation() {
1205
1206 ObjectModelOperation acceptOperation = addOperation(outputAbstract, "accept", void.class);
1207 addAnnotation(outputAbstract, acceptOperation , Override.class);
1208 addParameter(acceptOperation, EntityVisitor.class, "visitor");
1209
1210 addException(acceptOperation, TopiaException.class);
1211
1212 setOperationBody(acceptOperation,""
1213
1214
1215
1216
1217
1218 );
1219 }
1220
1221 protected void createAcceptInternalOperation(ObjectModelClass input) {
1222
1223 boolean withSuperEntity = false;
1224 for (ObjectModelClassifier parent : input.getSuperclasses()) {
1225 if (TopiaGeneratorUtil.isEntity(parent)) {
1226 withSuperEntity= true;
1227 break;
1228 }
1229 }
1230
1231 internalAcceptOperation = addOperation(outputAbstract, "accept0", void.class, ObjectModelJavaModifier.PROTECTED);
1232 addParameter(internalAcceptOperation, EntityVisitor.class, "visitor");
1233 addException(internalAcceptOperation, TopiaException.class);
1234
1235 if (withSuperEntity) {
1236 addAnnotation(outputAbstract, internalAcceptOperation, Override.class);
1237 internalAcceptOperationBody = new StringBuilder(""
1238
1239
1240
1241 );
1242 } else {
1243 internalAcceptOperationBody= new StringBuilder(""
1244
1245
1246 );
1247 }
1248 }
1249
1250 protected void updateAcceptOperation(ObjectModelAttribute attribute) {
1251 String attrName =
1252 TopiaGeneratorUtil.getSimpleName(getPropertyName(attribute));
1253 String attrType =
1254 TopiaGeneratorUtil.getSimpleName(getPropertyType(attribute));
1255 String collectionType = getCollectionType(attribute);
1256 String constantName = getConstantName(attrName);
1257 if (collectionType != null) {
1258 collectionType = TopiaGeneratorUtil.getSimpleName(collectionType);
1259 internalAcceptOperationBody.append(""
1260
1261
1262 );
1263 } else {
1264 internalAcceptOperationBody.append(""
1265
1266
1267 );
1268 }
1269 }
1270
1271 protected void closeAcceptInternalOperation() {
1272
1273 setOperationBody(internalAcceptOperation, internalAcceptOperationBody.toString() + ""
1274
1275 );
1276 }
1277
1278 protected void generateToStringOperation(ObjectModelClass input) {
1279
1280 if (log.isDebugEnabled()) {
1281 log.debug("generate toString method for entity " +
1282 outputInterface.getQualifiedName());
1283 }
1284 ObjectModelOperation operation =
1285 addOperation(outputAbstract, "toString", String.class);
1286
1287 addAnnotation(outputAbstract, operation, Override.class.getSimpleName());
1288
1289 addImport(outputAbstract, ToStringBuilder.class);
1290
1291 StringBuilder body = new StringBuilder(""
1292
1293
1294
1295 );
1296 for (ObjectModelAttribute attr : input.getAttributes()) {
1297
1298
1299
1300 ObjectModelClass attrEntity = null;
1301
1302 if (model.hasClass(attr.getType())) {
1303 attrEntity = model.getClass(attr.getType());
1304 }
1305
1306 boolean isEntity = attrEntity != null &&
1307 TopiaGeneratorUtil.isEntity(attrEntity);
1308
1309 ObjectModelAttribute reverse = attr.getReverseAttribute();
1310 if (isEntity && (reverse == null || !reverse.isNavigable())
1311 && !attr.hasAssociationClass() || !isEntity) {
1312 String attrName = attr.getName();
1313 String constantName = getConstantName(attrName);
1314 body.append(""
1315
1316
1317 );
1318 }
1319 }
1320 body.append(""
1321
1322
1323
1324 );
1325 setOperationBody(operation, body.length() == 0 ? " " : body.toString());
1326
1327 }
1328
1329 protected void generateCompositeOperation(ObjectModelClass input) {
1330
1331 ObjectModelOperation operation =
1332 addOperation(outputAbstract, "getComposite",
1333 List.class.getName() + '<' + TopiaEntity.class.getName() + '>');
1334
1335 addException(operation, TopiaException.class);
1336 addAnnotation(outputAbstract, operation, Override.class.getSimpleName());
1337
1338 addImport(outputAbstract, ArrayList.class);
1339 addImport(outputAbstract, List.class);
1340
1341 StringBuilder body = new StringBuilder(""
1342
1343
1344
1345
1346
1347
1348 );
1349 for (ObjectModelAttribute attr : input.getAttributes()) {
1350
1351 if (attr.referenceClassifier() &&
1352 TopiaGeneratorUtil.isEntity(attr.getClassifier())) {
1353
1354 if (attr.isComposite()) {
1355 String attrName = attr.getName();
1356 String getterName = getJavaBeanMethodName("get", attrName);
1357 if (TopiaGeneratorUtil.isNMultiplicity(attr)) {
1358 body.append(""
1359
1360
1361
1362
1363 );
1364 } else {
1365 body.append(""
1366
1367
1368 );
1369 }
1370 } else if (attr.hasAssociationClass()) {
1371 String assocAttrName = TopiaGeneratorUtil.getAssocAttrName(
1372 attr);
1373 String assocClassFQN = TopiaGeneratorUtil.getSimpleName(
1374 attr.getAssociationClass().getQualifiedName());
1375 String ref = "this." + TopiaGeneratorUtil.toLowerCaseFirstLetter(
1376 assocAttrName);
1377 if (!TopiaGeneratorUtil.isNMultiplicity(attr)) {
1378 body.append(""
1379
1380
1381
1382
1383
1384 );
1385 } else {
1386 ObjectModelAttribute reverse = attr.getReverseAttribute();
1387 String reverseAttrName = reverse.getName();
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399 addImport(outputAbstract, TopiaContextImplementor.class);
1400 body.append(""
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410 );
1411 }
1412 }
1413 }
1414 }
1415 body.append(""
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428 );
1429
1430 setOperationBody(operation, body.length() == 0 ? " " : body.toString());
1431 }
1432
1433 protected void generateAggregateOperation(ObjectModelClass input) {
1434
1435 ObjectModelOperation operation =
1436 addOperation(outputAbstract, "getAggregate",
1437 List.class.getName() + '<' + TopiaEntity.class.getName() + '>');
1438
1439 addException(operation, TopiaException.class);
1440 addAnnotation(outputAbstract, operation, Override.class.getSimpleName());
1441
1442 addImport(outputAbstract, ArrayList.class);
1443 addImport(outputAbstract, List.class);
1444
1445 StringBuilder body = new StringBuilder(""
1446
1447
1448
1449
1450
1451
1452 );
1453 for (ObjectModelAttribute attr : input.getAttributes()) {
1454
1455 if (attr.referenceClassifier() &&
1456 TopiaGeneratorUtil.isEntity(attr.getClassifier()) &&
1457 attr.isAggregate()) {
1458
1459 String attrName = attr.getName();
1460 String getterName = getJavaBeanMethodName("get", attrName);
1461 if (TopiaGeneratorUtil.isNMultiplicity(attr)) {
1462 body.append(""
1463
1464
1465 );
1466 } else {
1467 body.append(""
1468
1469
1470 );
1471 }
1472 }
1473 }
1474 body.append(""
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485 );
1486
1487 setOperationBody(operation, body.length() == 0 ? " " : body.toString());
1488 }
1489
1490
1491
1492
1493
1494 protected boolean isAbstract(ObjectModelClass clazz) {
1495 if (clazz.isAbstract()) {
1496 return true;
1497 }
1498
1499
1500
1501 Collection<ObjectModelOperation> allInterfaceOperations =
1502 clazz.getAllInterfaceOperations(true);
1503 allInterfaceOperations.removeAll(clazz.getAllOtherOperations(true));
1504 for (ObjectModelOperation op : allInterfaceOperations) {
1505 boolean implementationFound = false;
1506 for (ObjectModelClass superClazz : clazz.getSuperclasses()) {
1507 for (ObjectModelOperation matchingOp :
1508 superClazz.getOperations(op.getName())) {
1509 implementationFound = op.equals(matchingOp) &&
1510 !matchingOp.isAbstract();
1511 if (implementationFound) {
1512 break;
1513 }
1514 }
1515 if (implementationFound) {
1516 break;
1517 }
1518 }
1519 if (!implementationFound) {
1520 if (log.isDebugEnabled()) {
1521 log.debug(clazz.getName() + " : abstract operation " + op);
1522 }
1523 return true;
1524 }
1525 }
1526 return false;
1527 }
1528
1529 protected String getCollectionType(ObjectModelAttribute attribute) {
1530 String result = null;
1531 if (!associationClass && TopiaGeneratorUtil.isNMultiplicity(attribute)) {
1532 result = TopiaGeneratorUtil.getNMultiplicityInterfaceType(attribute);
1533 }
1534 return result;
1535 }
1536
1537 protected String getPropertyName(ObjectModelAttribute attribute) {
1538 String propertyName = attribute.getName();
1539 if (!associationClass && attribute.hasAssociationClass()) {
1540 propertyName = TopiaGeneratorUtil.getAssocAttrName(attribute);
1541 }
1542 return propertyName;
1543 }
1544
1545 protected String getPropertyType(ObjectModelAttribute attribute) {
1546 String propertyType = attribute.getType();
1547 if (!associationClass && attribute.hasAssociationClass()) {
1548 propertyType = attribute.getAssociationClass().getQualifiedName();
1549 }
1550 return propertyType;
1551 }
1552
1553 protected ObjectModelOperation createImplOperation(ObjectModelOperation interfaceOperation) {
1554 ObjectModelOperation implOperation =
1555 cloneOperationSignature(interfaceOperation, outputAbstract, false);
1556 addAnnotation(outputAbstract, implOperation, Override.class.getSimpleName());
1557 return implOperation;
1558 }
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575 protected ObjectModelOperation createPropertySetterSignature(ObjectModelClassifier classifier,
1576 String propertyType,
1577 String propertyName,
1578 String operationDocumentation) {
1579
1580 ObjectModelOperation operation =
1581 addOperation(classifier,
1582 getJavaBeanMethodName("set", propertyName), void.class);
1583
1584 ObjectModelParameter param =
1585 addParameter(operation, propertyType, propertyName);
1586
1587
1588 if (StringUtils.isNotEmpty(operationDocumentation)) {
1589 setDocumentation(operation, operationDocumentation);
1590 setDocumentation(param, "La valeur de l'attribut à positionner.");
1591 }
1592
1593 return operation;
1594 }
1595
1596 protected void addInterface(List<String> interfaceAlreadyDone,
1597 ObjectModelClassifier output,
1598 ObjectModelClassifier interfaze) {
1599 String qualifiedName = interfaze.getQualifiedName();
1600 if (!interfaceAlreadyDone.contains(qualifiedName)) {
1601
1602 interfaceAlreadyDone.add(qualifiedName);
1603
1604 if (output != null) {
1605
1606
1607 addInterface(output, qualifiedName);
1608
1609 if (log.isTraceEnabled()) {
1610 log.trace("Add interface " + qualifiedName + " on " +
1611 output.getQualifiedName());
1612 }
1613 } else {
1614 if (log.isTraceEnabled()) {
1615 log.trace("Skip included interface " + qualifiedName);
1616 }
1617 }
1618
1619
1620 for (ObjectModelClassifier parent : interfaze.getInterfaces()) {
1621 addInterface(interfaceAlreadyDone, null, parent);
1622 }
1623 }
1624 }
1625
1626 protected void addInterface(List<String> interfaceAlreadyDone,
1627 ObjectModelClassifier output,
1628 Class<?> clazz) {
1629 String qualifiedName = clazz.getName();
1630 if (!interfaceAlreadyDone.contains(qualifiedName)) {
1631
1632
1633 addInterface(output, qualifiedName);
1634
1635 }
1636 }
1637 }