1 package org.andromda.cartridges.hibernate.metafacades;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5
6 import org.andromda.cartridges.hibernate.HibernateProfile;
7 import org.andromda.cartridges.hibernate.HibernateUtils;
8 import org.andromda.metafacades.uml.ClassifierFacade;
9 import org.andromda.metafacades.uml.EntityAssociationEnd;
10 import org.andromda.metafacades.uml.EntityMetafacadeUtils;
11 import org.andromda.metafacades.uml.ModelElementFacade;
12 import org.andromda.metafacades.uml.NameMasker;
13 import org.andromda.metafacades.uml.TypeMappings;
14 import org.andromda.metafacades.uml.UMLMetafacadeProperties;
15 import org.andromda.metafacades.uml.UMLProfile;
16 import org.andromda.utils.JavaTypeConverter;
17 import org.apache.commons.lang.BooleanUtils;
18 import org.apache.commons.lang.ObjectUtils;
19 import org.apache.commons.lang.StringUtils;
20
21
22
23
24
25
26
27 public class HibernateAssociationEndLogicImpl
28 extends HibernateAssociationEndLogic
29 {
30 private static final long serialVersionUID = 34L;
31
32
33
34
35 public HibernateAssociationEndLogicImpl(
36 Object metaObject,
37 String context)
38 {
39 super(metaObject, context);
40 }
41
42
43
44
45 private static final String COLLECTION_TYPE_SET = "set";
46
47
48
49
50 private static final String COLLECTION_TYPE_MAP = "map";
51
52
53
54
55 private static final String COLLECTION_TYPE_BAG = "bag";
56
57
58
59
60 private static final String COLLECTION_TYPE_LIST = "list";
61
62
63
64
65 private static final String COLLECTION_TYPE_COLLECTION = "collection";
66
67
68
69
70 private static final Collection<String> collectionTypes = new ArrayList<String>();
71
72 static
73 {
74 collectionTypes.add(COLLECTION_TYPE_SET);
75 collectionTypes.add(COLLECTION_TYPE_MAP);
76 collectionTypes.add(COLLECTION_TYPE_BAG);
77 collectionTypes.add(COLLECTION_TYPE_LIST);
78 collectionTypes.add(COLLECTION_TYPE_COLLECTION);
79 }
80
81
82
83
84
85 private static final String COMPOSITION_DEFINES_EAGER_LOADING = "compositionDefinesEagerLoading";
86
87
88
89
90 private static final String PROPERTY_ASSOCIATION_END_OUTERJOIN = "hibernateAssociationEndOuterJoin";
91
92
93
94
95 private static final String COLLECTION_INDEX_NAME = "associationEndCollectionIndexName";
96
97
98
99
100 private static final String COLLECTION_INDEX_TYPE = "associationEndCollectionIndexType";
101
102
103
104
105 private static final String HIBERNATE_AGGREGATION_CASCADE = "hibernateAggregationCascade";
106
107
108
109
110 private static final String HIBERNATE_COMPOSITION_CASCADE = "hibernateCompositionCascade";
111
112
113
114
115
116 @Override
117 protected boolean handleIsOne2OnePrimary()
118 {
119 boolean primary = !BooleanUtils.toBoolean(
120 ObjectUtils.toString(this.getOtherEnd().findTaggedValue(
121 HibernateProfile.TAGGEDVALUE_PERSISTENCE_ASSOCIATION_END_PRIMARY)));
122 if (primary)
123 {
124 primary = (this.isOne2One() && (this.isAggregation() || this.isComposition()) ||
125 BooleanUtils.toBoolean(ObjectUtils.toString(
126 this.findTaggedValue(HibernateProfile.TAGGEDVALUE_PERSISTENCE_ASSOCIATION_END_PRIMARY))));
127 }
128 return primary;
129 }
130
131
132
133
134 public String getGetterSetterTypeName()
135 {
136 String getterSetterTypeName = null;
137
138 if (this.isMany())
139 {
140 final boolean specificInterfaces =
141 Boolean.valueOf(
142 ObjectUtils.toString(this.getConfiguredProperty(HibernateGlobals.SPECIFIC_COLLECTION_INTERFACES)))
143 .booleanValue();
144
145 final TypeMappings mappings = this.getLanguageMappings();
146 if (mappings != null)
147 {
148 if (this.isMap())
149 {
150 getterSetterTypeName = mappings.getTo(UMLProfile.MAP_TYPE_NAME);
151 }
152 else if (specificInterfaces)
153 {
154 if (this.isSet())
155 {
156 getterSetterTypeName = mappings.getTo(UMLProfile.SET_TYPE_NAME);
157 }
158 else if (this.isList())
159 {
160 getterSetterTypeName = mappings.getTo(UMLProfile.LIST_TYPE_NAME);
161 }
162 }
163 else
164 {
165 getterSetterTypeName =
166 ObjectUtils.toString(this.getConfiguredProperty(HibernateGlobals.DEFAULT_COLLECTION_INTERFACE));
167 }
168 }
169 else
170 {
171 getterSetterTypeName =
172 ObjectUtils.toString(this.getConfiguredProperty(HibernateGlobals.DEFAULT_COLLECTION_INTERFACE));
173 }
174 }
175 else
176 {
177 final ClassifierFacade type = this.getType();
178
179 if (type instanceof HibernateEntity)
180 {
181 final String typeName = ((HibernateEntity)type).getFullyQualifiedEntityName();
182
183 if (StringUtils.isNotBlank(typeName))
184 {
185 getterSetterTypeName = typeName;
186 }
187 }
188 }
189
190 if (StringUtils.isBlank(getterSetterTypeName))
191 {
192 getterSetterTypeName = super.getGetterSetterTypeName();
193 }
194 else if (this.isMany())
195 {
196
197 if (Boolean.valueOf(String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.ENABLE_TEMPLATING)))
198 .booleanValue())
199 {
200 final StringBuilder lBuffer = new StringBuilder();
201 lBuffer.append(getterSetterTypeName);
202 lBuffer.append('<');
203 if (this.isMap())
204 {
205 lBuffer.append(this.getCollectionIndexType());
206 lBuffer.append(", ");
207 }
208 lBuffer.append(this.getType().getFullyQualifiedName());
209 lBuffer.append('>');
210 getterSetterTypeName = lBuffer.toString();
211 }
212 }
213
214 return getterSetterTypeName;
215 }
216
217
218
219
220 @Override
221 protected boolean handleIsLazy()
222 {
223 String lazyString = (String)findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_LAZY);
224 boolean lazy = true;
225
226 if (StringUtils.isBlank(lazyString))
227 {
228
229
230 boolean compositionDefinesEagerLoading =
231 Boolean.valueOf(String.valueOf(this.getConfiguredProperty(COMPOSITION_DEFINES_EAGER_LOADING)))
232 .booleanValue();
233
234 if (compositionDefinesEagerLoading)
235 {
236 lazy = !this.getOtherEnd().isComposition();
237 }
238 }
239 else
240 {
241 lazy = Boolean.valueOf(lazyString).booleanValue();
242 }
243
244 return lazy;
245 }
246
247
248
249
250
251
252
253 protected String handleGetHibernateCascade()
254 {
255 String cascade = null;
256 final String individualCascade = (String)findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_CASCADE);
257
258 if ((individualCascade != null) && (individualCascade.length() > 0))
259 {
260 cascade = individualCascade;
261 }
262 else if (this.isChild())
263 {
264 if (StringUtils.isBlank(this.getHibernateCompositionCascade()))
265 {
266 cascade = HibernateGlobals.HIBERNATE_CASCADE_DELETE;
267
268 final Object type = this.getType();
269
270 if (type != null && type instanceof HibernateEntity)
271 {
272 HibernateEntity entity = (HibernateEntity)type;
273 final String defaultCascade = entity.getHibernateDefaultCascade();
274
275 if (defaultCascade.equalsIgnoreCase(HibernateGlobals.HIBERNATE_CASCADE_SAVE_UPDATE) ||
276 defaultCascade.equalsIgnoreCase(HibernateGlobals.HIBERNATE_CASCADE_ALL))
277 {
278 if (this.isMany())
279 {
280 cascade = HibernateGlobals.HIBERNATE_CASCADE_ALL_DELETE_ORPHAN;
281 }
282 else
283 {
284 cascade = HibernateGlobals.HIBERNATE_CASCADE_ALL;
285 }
286 }
287 }
288 }
289 else
290 {
291 cascade = this.getHibernateCompositionCascade();
292 }
293 }
294 else if (this.isComposition())
295 {
296
297
298 cascade = HibernateGlobals.HIBERNATE_CASCADE_NONE;
299 }
300 else if (StringUtils.isNotBlank(this.getHibernateAggregationCascade()))
301 {
302
303
304 if (this.isAggregation())
305 {
306 cascade = HibernateGlobals.HIBERNATE_CASCADE_NONE;
307 }
308 else if (this.getOtherEnd() != null && this.getOtherEnd().isAggregation())
309 {
310 cascade = this.getHibernateAggregationCascade();
311 }
312 }
313 return cascade;
314 }
315
316
317
318
319 @Override
320 protected boolean handleIsHibernateInverse()
321 {
322
323 boolean inverse = this.isNavigable() && this.getOtherEnd().isNavigable();
324
325 if (inverse)
326 {
327 inverse = this.isMany2One();
328
329
330
331 if (this.isMany2Many() && !inverse)
332 {
333 if (this.getOtherEnd().isAggregation() || this.getOtherEnd().isComposition())
334 {
335 inverse = true;
336 }
337 else
338 {
339 inverse=false;
340 }
341 if (inverse && this.isBidirectionalOrderedListChild() && (this.isVersion3() || this.isVersion4()))
342 {
343
344
345 inverse = false;
346 }
347 }
348 }
349
350 return inverse;
351 }
352
353
354
355
356 private static final String HIBERNATE_OUTER_JOIN_YES = "yes";
357
358
359
360
361 private static final String HIBERNATE_OUTER_JOIN_AUTO = "auto";
362
363
364
365
366 @Override
367 protected String handleGetOuterJoin()
368 {
369 Object value = this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_OUTER_JOIN);
370
371 if (value == null)
372 {
373 value = this.getConfiguredProperty(PROPERTY_ASSOCIATION_END_OUTERJOIN);
374 }
375 String outerValue = StringUtils.trimToEmpty(String.valueOf(value));
376 String version = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION);
377
378 if (StringUtils.isBlank(version) || version.startsWith(HibernateGlobals.HIBERNATE_VERSION_3)
379 || version.startsWith(HibernateGlobals.HIBERNATE_VERSION_4))
380 {
381 outerValue =
382 (outerValue.equals(HIBERNATE_OUTER_JOIN_AUTO) || outerValue.equals(HIBERNATE_OUTER_JOIN_YES))
383 ? "select" : "join";
384 }
385 return outerValue;
386 }
387
388
389
390
391
392
393 public boolean isRequired()
394 {
395 boolean required = super.isRequired();
396 Object type = this.getOtherEnd().getType();
397
398 if ((type != null) && HibernateEntity.class.isAssignableFrom(type.getClass()))
399 {
400 HibernateEntity entity = (HibernateEntity)type;
401
402 if (entity.isHibernateInheritanceClass() && (entity.getGeneralization() != null))
403 {
404 required = false;
405 }
406 }
407
408 return required;
409 }
410
411
412
413
414 @Override
415 protected String handleGetCollectionType()
416 {
417 String collectionType = this.getSpecificCollectionType();
418
419 if (!collectionTypes.contains(collectionType))
420 {
421 if (this.isOrdered())
422 {
423 collectionType = COLLECTION_TYPE_LIST;
424 }
425 else
426 {
427 collectionType =
428 (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_ASSOCIATION_COLLECTION_TYPE);
429 }
430 }
431
432 return collectionType;
433 }
434
435
436
437
438
439
440 private String getSpecificCollectionType()
441 {
442 return ObjectUtils.toString(
443 this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ASSOCIATION_COLLECTION_TYPE));
444 }
445
446
447
448
449 @Override
450 protected String handleGetSortType()
451 {
452 return ObjectUtils.toString(this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ASSOCIATION_SORT_TYPE));
453 }
454
455
456
457
458 @Override
459 protected String handleGetOrderByColumns()
460 {
461 String orderColumns =
462 (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ASSOCIATION_ORDER_BY_COLUMNS);
463
464 if (StringUtils.isBlank(orderColumns))
465 {
466 orderColumns = ((EntityAssociationEnd)this.getOtherEnd()).getColumnName();
467 }
468
469 return orderColumns;
470 }
471
472
473
474
475 @Override
476 protected String handleGetWhereClause()
477 {
478 return (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ASSOCIATION_WHERE_CLAUSE);
479 }
480
481
482
483
484 @Override
485 protected boolean handleIsIndexedCollection()
486 {
487 boolean indexed = false;
488
489 if (this.isOrdered())
490 {
491 if ((
492 this.getCollectionType().equals(COLLECTION_TYPE_LIST) ||
493 this.getCollectionType().equals(COLLECTION_TYPE_MAP)
494 ) && StringUtils.isNotBlank(this.getCollectionIndexName()))
495 {
496 indexed = true;
497 }
498 }
499
500 return indexed;
501 }
502
503
504
505
506 @Override
507 protected String handleGetCollectionIndexName()
508 {
509 Object value = this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ASSOCIATION_INDEX);
510
511 if ((value == null) && this.isConfiguredProperty(COLLECTION_INDEX_NAME))
512 {
513 value = this.getConfiguredProperty(COLLECTION_INDEX_NAME);
514
515 if (StringUtils.isBlank(ObjectUtils.toString(value)))
516 {
517 value = null;
518 }
519 }
520
521 if (value != null)
522 {
523 return ObjectUtils.toString(value);
524 }
525 final String otherEntityName = ((HibernateEntity)this.getOtherEnd().getType()).getEntityName();
526 final Object separator = this.getConfiguredProperty(UMLMetafacadeProperties.SQL_NAME_SEPARATOR);
527 return EntityMetafacadeUtils.toSqlName(
528 otherEntityName,
529 separator) + separator + EntityMetafacadeUtils.toSqlName(
530 this.getName(),
531 separator) + separator + "IDX";
532 }
533
534
535
536
537 @Override
538 protected String handleGetCollectionIndexType()
539 {
540 Object value = this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_ASSOCIATION_INDEX_TYPE);
541
542 if (value == null)
543 {
544 value = this.getConfiguredProperty(COLLECTION_INDEX_TYPE);
545
546 if (StringUtils.isBlank(ObjectUtils.toString(value)))
547 {
548 value = null;
549 }
550 }
551
552 if (value != null)
553 {
554 if (value instanceof String)
555 {
556 ModelElementFacade element = this.getRootPackage().findModelElement((String)value);
557 if (element!=null)
558 {
559 value = element.getFullyQualifiedName();
560 }
561
562
563 value = JavaTypeConverter.getJavaLangTypeName((String)value);
564 }
565 if (value instanceof HibernateType)
566 {
567 value = ((HibernateType)value).getFullyQualifiedHibernateType();
568 }
569 }
570
571 return (value != null) ? ObjectUtils.toString(value) : null;
572 }
573
574
575
576
577 @Override
578 protected boolean handleIsMap()
579 {
580 boolean isMap = this.getCollectionType().equalsIgnoreCase(COLLECTION_TYPE_MAP);
581
582 if (isMap && StringUtils.isBlank(this.getSpecificCollectionType()))
583 {
584 isMap = !this.isOrdered();
585 }
586
587 return isMap;
588 }
589
590
591
592
593 @Override
594 protected boolean handleIsList()
595 {
596 boolean isList = this.getCollectionType().equalsIgnoreCase(COLLECTION_TYPE_LIST);
597
598 if (!isList && StringUtils.isBlank(this.getSpecificCollectionType()))
599 {
600 isList = this.isOrdered();
601 }
602
603 return isList;
604 }
605
606
607
608
609 @Override
610 protected boolean handleIsSet()
611 {
612 boolean isSet = this.getCollectionType().equalsIgnoreCase(COLLECTION_TYPE_SET);
613
614 if (isSet && StringUtils.isBlank(this.getSpecificCollectionType()))
615 {
616 isSet = !this.isOrdered();
617 }
618
619 return isSet;
620 }
621
622
623
624
625 @Override
626 protected boolean handleIsBag()
627 {
628 return this.getCollectionType().equalsIgnoreCase(COLLECTION_TYPE_BAG);
629 }
630
631
632
633
634 @Override
635 protected String handleGetCollectionTypeImplementation()
636 {
637 StringBuilder implementation = new StringBuilder();
638
639 if (this.isMany())
640 {
641 implementation.append("new ");
642
643 if (this.isSet())
644 {
645 implementation.append(this.getConfiguredProperty(HibernateGlobals.SET_TYPE_IMPLEMENTATION));
646 }
647 else if (this.isMap())
648 {
649 implementation.append(this.getConfiguredProperty(HibernateGlobals.MAP_TYPE_IMPLEMENTATION));
650 }
651 else if (this.isBag())
652 {
653 implementation.append(this.getConfiguredProperty(HibernateGlobals.BAG_TYPE_IMPLEMENTATION));
654 }
655 else if (this.isList())
656 {
657 implementation.append(this.getConfiguredProperty(HibernateGlobals.LIST_TYPE_IMPLEMENTATION));
658 }
659
660
661 if (Boolean.valueOf(String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.ENABLE_TEMPLATING)))
662 .booleanValue())
663 {
664 implementation.append('<');
665 if (this.isMap())
666 {
667 implementation.append(this.getCollectionIndexType());
668 implementation.append(", ");
669 }
670 implementation.append(this.getType().getFullyQualifiedName());
671 implementation.append('>');
672 }
673
674 implementation.append("()");
675 }
676
677 return implementation.toString();
678 }
679
680
681
682
683 @Override
684 protected String handleGetHibernateAggregationCascade()
685 {
686 return StringUtils.trimToEmpty(ObjectUtils.toString(this.getConfiguredProperty(HIBERNATE_AGGREGATION_CASCADE)));
687 }
688
689
690
691
692 @Override
693 protected String handleGetHibernateCompositionCascade()
694 {
695 return StringUtils.trimToEmpty(ObjectUtils.toString(this.getConfiguredProperty(HIBERNATE_COMPOSITION_CASCADE)));
696 }
697
698
699
700
701 @Override
702 protected boolean handleIsBidirectionalOrderedListParent()
703 {
704 boolean isBidirectionalOrderedListParent = false;
705 boolean biDirectional = this.isNavigable() && this.getOtherEnd().isNavigable();
706
707 if (biDirectional && this.isOne2Many() && (this.getOtherEnd() instanceof HibernateAssociationEnd))
708 {
709 HibernateAssociationEnd otherEnd = (HibernateAssociationEnd)this.getOtherEnd();
710
711 isBidirectionalOrderedListParent =
712 otherEnd.getCollectionType().equals(COLLECTION_TYPE_LIST) && otherEnd.isIndexedCollection();
713 }
714
715 return isBidirectionalOrderedListParent;
716 }
717
718
719
720
721 @Override
722 protected boolean handleIsBidirectionalOrderedListChild()
723 {
724 boolean biDirectional = false;
725 if (this.getOtherEnd() instanceof HibernateAssociationEnd)
726 {
727 HibernateAssociationEnd otherEnd = (HibernateAssociationEnd)this.getOtherEnd();
728 biDirectional = otherEnd.isBidirectionalOrderedListParent();
729 }
730 return biDirectional;
731 }
732
733
734
735
736
737 protected boolean handleIsUsingHibernate3()
738 {
739 boolean usingHibernate3 = false;
740 String property = (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION);
741 if (property != null)
742 {
743 usingHibernate3 = property.startsWith(HibernateGlobals.HIBERNATE_VERSION_3);
744 }
745 return usingHibernate3;
746 }
747
748
749
750
751
752 protected String handleGetCollectionIndexNameGetter()
753 {
754 return "get" + NameMasker.mask(
755 this.getCollectionIndexName(),
756 NameMasker.UPPERCAMELCASE);
757 }
758
759
760
761
762
763 protected String handleGetCollectionIndexNameSetter()
764 {
765 return "set" + NameMasker.mask(
766 this.getCollectionIndexName(),
767 NameMasker.UPPERCAMELCASE);
768 }
769
770 private boolean isVersion3()
771 {
772 return HibernateUtils.isVersion3((String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION));
773 }
774
775 private boolean isVersion4()
776 {
777 return HibernateUtils.isVersion4((String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION));
778 }
779
780 private boolean isXMLPersistenceActive()
781 {
782 return HibernateUtils.isXmlPersistenceActive(
783 (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_VERSION),
784 (String)this.getConfiguredProperty(HibernateGlobals.HIBERNATE_XML_PERSISTENCE));
785 }
786
787
788
789
790 @Override
791 protected String handleGetEmbedXML()
792 {
793 String embedVal = null;
794
795 if (isXMLPersistenceActive())
796 {
797 embedVal = (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_XML_EMBED);
798
799 if (StringUtils.isBlank(embedVal))
800 {
801 boolean isBiDirectional = this.isNavigable() && this.getOtherEnd().isNavigable();
802 if (isBiDirectional && this.isMany())
803 {
804 embedVal = "false";
805 }
806 else
807 {
808 embedVal = "true";
809 }
810 }
811 }
812 return (StringUtils.isBlank(embedVal)) ? null : embedVal;
813 }
814
815
816
817
818 @Override
819 protected String handleGetXmlTagName()
820 {
821 String tagName = null;
822
823 if (isXMLPersistenceActive())
824 {
825 tagName = (String)this.findTaggedValue(HibernateProfile.TAGGEDVALUE_HIBERNATE_XML_TAG_NAME);
826
827 if (StringUtils.isBlank(tagName))
828 {
829 tagName = this.getName();
830 }
831 }
832 return (StringUtils.isBlank(tagName)) ? null : tagName;
833 }
834
835
836
837
838 @Override
839 protected boolean handleIsOwning()
840 {
841 boolean owning = false;
842 if (this.isAggregation() || this.isComposition())
843 {
844 owning = true;
845 }
846 else if (!this.isNavigable())
847 {
848 owning = true;
849 }
850 return owning;
851 }
852 }