1 package xuml.tools.model.compiler;
2
3 import static com.google.common.collect.Collections2.transform;
4 import static com.google.common.collect.HashMultimap.create;
5 import static com.google.common.collect.Lists.newArrayList;
6 import static com.google.common.collect.Sets.newHashSet;
7
8 import java.math.BigDecimal;
9 import java.math.BigInteger;
10 import java.util.Collection;
11 import java.util.Collections;
12 import java.util.Date;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16 import java.util.TreeSet;
17 import java.util.stream.Collectors;
18
19 import org.w3c.dom.Node;
20
21 import com.google.common.base.Function;
22 import com.google.common.base.Optional;
23 import com.google.common.collect.HashMultimap;
24 import com.google.common.collect.Lists;
25 import com.google.common.collect.Maps;
26 import com.google.common.collect.Sets;
27
28 import jakarta.xml.bind.JAXBElement;
29 import jakarta.xml.bind.JAXBException;
30 import xuml.tools.miuml.metamodel.extensions.jaxb.Documentation;
31 import xuml.tools.miuml.metamodel.extensions.jaxb.Find;
32 import xuml.tools.miuml.metamodel.extensions.jaxb.Generation;
33 import xuml.tools.miuml.metamodel.extensions.jaxb.Marshaller;
34 import xuml.tools.miuml.metamodel.jaxb.ActivePerspective;
35 import xuml.tools.miuml.metamodel.jaxb.Association;
36 import xuml.tools.miuml.metamodel.jaxb.AssociativeReference;
37 import xuml.tools.miuml.metamodel.jaxb.AsymmetricPerspective;
38 import xuml.tools.miuml.metamodel.jaxb.AtomicType;
39 import xuml.tools.miuml.metamodel.jaxb.Attribute;
40 import xuml.tools.miuml.metamodel.jaxb.BinaryAssociation;
41 import xuml.tools.miuml.metamodel.jaxb.BooleanType;
42 import xuml.tools.miuml.metamodel.jaxb.Class;
43 import xuml.tools.miuml.metamodel.jaxb.CreationEvent;
44 import xuml.tools.miuml.metamodel.jaxb.EnumeratedType;
45 import xuml.tools.miuml.metamodel.jaxb.Event;
46 import xuml.tools.miuml.metamodel.jaxb.Extension;
47 import xuml.tools.miuml.metamodel.jaxb.Generalization;
48 import xuml.tools.miuml.metamodel.jaxb.IdentifierAttribute;
49 import xuml.tools.miuml.metamodel.jaxb.IndependentAttribute;
50 import xuml.tools.miuml.metamodel.jaxb.IntegerType;
51 import xuml.tools.miuml.metamodel.jaxb.Named;
52 import xuml.tools.miuml.metamodel.jaxb.NativeAttribute;
53 import xuml.tools.miuml.metamodel.jaxb.PassivePerspective;
54 import xuml.tools.miuml.metamodel.jaxb.Perspective;
55 import xuml.tools.miuml.metamodel.jaxb.RealType;
56 import xuml.tools.miuml.metamodel.jaxb.Reference;
57 import xuml.tools.miuml.metamodel.jaxb.ReferentialAttribute;
58 import xuml.tools.miuml.metamodel.jaxb.Relationship;
59 import xuml.tools.miuml.metamodel.jaxb.SpecializationReference;
60 import xuml.tools.miuml.metamodel.jaxb.State;
61 import xuml.tools.miuml.metamodel.jaxb.StateModelParameter;
62 import xuml.tools.miuml.metamodel.jaxb.StateModelSignature;
63 import xuml.tools.miuml.metamodel.jaxb.SymbolicType;
64 import xuml.tools.miuml.metamodel.jaxb.SymmetricPerspective;
65 import xuml.tools.miuml.metamodel.jaxb.Transition;
66 import xuml.tools.miuml.metamodel.jaxb.UnaryAssociation;
67 import xuml.tools.model.compiler.info.ClassExtensions;
68 import xuml.tools.model.compiler.info.Mult;
69 import xuml.tools.model.compiler.info.MyAttributeExtensions;
70 import xuml.tools.model.compiler.info.MyEvent;
71 import xuml.tools.model.compiler.info.MyFind;
72 import xuml.tools.model.compiler.info.MyIdAttribute;
73 import xuml.tools.model.compiler.info.MyIndependentAttribute;
74 import xuml.tools.model.compiler.info.MyJoinColumn;
75 import xuml.tools.model.compiler.info.MyJoinTable;
76 import xuml.tools.model.compiler.info.MyParameter;
77 import xuml.tools.model.compiler.info.MyReferenceMember;
78 import xuml.tools.model.compiler.info.MySpecializations;
79 import xuml.tools.model.compiler.info.MySubclassRole;
80 import xuml.tools.model.compiler.info.MyTransition;
81 import xuml.tools.model.compiler.info.MyType;
82 import xuml.tools.model.compiler.info.MyTypeDefinition;
83
84
85
86
87
88
89
90 public class ClassInfo {
91
92 private final Class cls;
93 private final String packageName;
94 private final String schema;
95 private final TypeRegistertml#TypeRegister">TypeRegister typeRegister = new TypeRegister();
96 private final Lookups lookups;
97 private final static Marshallershaller.html#Marshaller">Marshaller extensionsMarshaller = new Marshaller();
98 private final NameManager nameManager;
99
100
101
102
103
104
105
106
107
108
109
110 public ClassInfo(NameManager nameManager, Class cls, String packageName, String schema,
111 Lookups lookups) {
112 this.nameManager = nameManager;
113 this.cls = cls;
114 this.packageName = packageName;
115 this.schema = schema;
116 this.lookups = lookups;
117 }
118
119
120
121
122
123
124 String getPackage() {
125 return packageName;
126 }
127
128
129
130
131
132
133 String getClassDescription() {
134 ClassExtensions x = getClassExtensions();
135 if (x.getDocumentationContent().isPresent())
136 return x.getDocumentationContent().get();
137 else
138 return "";
139 }
140
141
142
143
144
145
146 List<List<String>> getUniqueConstraintColumnNames() {
147 HashMultimap<BigInteger, String> map = getIdentifierAttributeNames();
148 List<List<String>> list = newArrayList();
149 for (BigInteger i : map.keySet()) {
150 if (!i.equals(BigInteger.ONE)) {
151 List<String> cols = newArrayList();
152 for (String attribute : map.get(i))
153 cols.add(nameManager.toColumnName(cls.getName(), attribute));
154 list.add(cols);
155 }
156 }
157 return list;
158 }
159
160
161
162
163
164
165 public String getName() {
166 return cls.getName();
167 }
168
169
170
171
172
173
174
175 private HashMultimap<BigInteger, String> getIdentifierAttributeNames() {
176 HashMultimap<BigInteger, Attribute> map = getIdentifierAttributes();
177 HashMultimap<BigInteger, String> m = create();
178 for (BigInteger i : map.keySet()) {
179 m.putAll(i, getNames(map.get(i)));
180 }
181 return m;
182 }
183
184 private static Function<Attribute, String> attributeName = new Function<Attribute, String>() {
185 @Override
186 public String apply(Attribute a) {
187 return a.getName();
188 }
189 };
190
191 private Set<String> getNames(Set<Attribute> attributes) {
192 return newHashSet(transform(attributes, attributeName));
193 }
194
195 private MyAttributeExtensions getAttributeExtensions(Attribute a) {
196 String documentationMimeType = null;
197 String documentationContent = null;
198 boolean generated = false;
199 boolean optional = false;
200 for (Extension ext : a.getExtension()) {
201 for (Object any : ext.getAny()) {
202 Object e = getJaxbElementValue(any);
203 if (e instanceof Documentation) {
204 Documentation doco = (Documentation) e;
205 documentationMimeType = doco.getMimeType();
206 documentationContent = doco.getContent();
207 } else if (e instanceof Generation) {
208 Generation"../../../../xuml/tools/miuml/metamodel/extensions/jaxb/Generation.html#Generation">Generation g = (Generation) e;
209 generated = g.isGenerated();
210 } else if (e instanceof Optional) {
211 xuml.tools.miuml.metamodel.extensions.jaxb.Optional o = (xuml.tools.miuml.metamodel.extensions.jaxb.Optional) e;
212 optional = o.isOptional();
213 }
214 }
215 }
216 return new MyAttributeExtensions(generated, documentationMimeType, documentationContent,
217 optional);
218 }
219
220 public ClassExtensions getClassExtensions() {
221 String documentationContent = null;
222 String documentationMimeType = null;
223 for (Extension ext : cls.getExtension()) {
224 for (Object any : ext.getAny()) {
225 Object e = getJaxbElementValue(any);
226 if (e instanceof Documentation) {
227 Documentation doco = (Documentation) e;
228 documentationMimeType = doco.getMimeType();
229 documentationContent = doco.getContent();
230 }
231 }
232 }
233 return new ClassExtensions(Optional.fromNullable(documentationContent),
234 Optional.fromNullable(documentationMimeType));
235 }
236
237 private Object getJaxbElementValue(Object any) {
238 Object e;
239 try {
240 Object element = extensionsMarshaller.unmarshal((Node) any);
241 e = ((JAXBElement<?>) element).getValue();
242 } catch (JAXBException ex) {
243
244 e = null;
245 }
246 return e;
247 }
248
249 private HashMultimap<BigInteger, Attribute> getIdentifierAttributes() {
250 HashMultimap<BigInteger, Attribute> map = HashMultimap.create();
251 for (JAXBElement<? extends Attribute> element : cls.getAttribute()) {
252 Attribute attribute = element.getValue();
253 for (IdentifierAttribute id : attribute.getIdentifier()) {
254 map.put(id.getNumber(), attribute);
255 }
256 }
257 return map;
258 }
259
260 String getSchema() {
261 return schema;
262 }
263
264 String getTable() {
265 return nameManager.toTableName(schema, cls.getName());
266 }
267
268 String getJavaClassSimpleName() {
269 return Util.toClassSimpleName(cls.getName());
270 }
271
272 List<MyIdAttribute> getPrimaryIdAttributeMembers() {
273 Set<Attribute> list = getIdentifierAttributes().get(BigInteger.ONE);
274 return getMyIdAttributes(list);
275 }
276
277 private List<MyIdAttribute> getMyIdAttributes(Set<Attribute> list) {
278 List<MyIdAttribute> result = newArrayList();
279 for (Attribute attribute : list) {
280 MyIdAttribute id;
281 if (attribute instanceof NativeAttribute) {
282 NativeAttribute a = (NativeAttribute) attribute;
283 id = createMyIdAttribute(a);
284 } else {
285 ReferentialAttribute a = (ReferentialAttribute) attribute;
286 id = createMyIdAttribute(a);
287 }
288 result.add(id);
289 }
290 return result;
291 }
292
293 private MyIdAttribute createMyIdAttribute(ReferentialAttribute a) {
294 Reference ref = a.getReference().getValue();
295 Relationship rel = lookups.getRelationship(ref.getRelationship());
296 String otherClassName = getOtherClassName(rel);
297 return getPrimaryIdAttribute(a, ref, otherClassName);
298 }
299
300 private String getOtherClassName(Relationship rel) {
301 String otherClassName;
302 if (rel instanceof BinaryAssociation) {
303 BinaryAssociation b = (BinaryAssociation) rel;
304 otherClassName = getOtherClassName(b);
305 } else if (rel instanceof UnaryAssociation) {
306
307 throw new RuntimeException("not sure how to do this one yet");
308 } else if (rel instanceof Generalization) {
309 Generalization g = (Generalization) rel;
310 otherClassName = getOtherClassName(g);
311 } else
312 throw new RuntimeException(
313 "this relationship type not implemented: " + rel.getClass().getName());
314 return otherClassName;
315 }
316
317 private String getOtherClassName(Generalization g) {
318 if (cls.getName().equals(g.getSuperclass()))
319 throw new RuntimeException(
320 "cannot use an id from a specialization as primary id member: " + g.getRnum());
321 else
322 return g.getSuperclass();
323 }
324
325 private String getOtherClassName(BinaryAssociation b) {
326 String otherClassName;
327 if (isActiveSide(b))
328 otherClassName = b.getPassivePerspective().getViewedClass();
329 else
330 otherClassName = b.getActivePerspective().getViewedClass();
331 return otherClassName;
332 }
333
334 private MyIdAttribute getPrimaryIdAttribute(ReferentialAttribute a, Reference ref,
335 String otherClassName) {
336 MyIdAttribute p = getOtherPrimaryIdAttribute(a, ref, otherClassName);
337 if (p != null)
338 return new MyIdAttribute(a.getName(),
339 nameManager.toFieldName(cls.getName(), a.getName()),
340 nameManager.toColumnName(cls.getName(), a.getName()), otherClassName,
341 nameManager.toColumnName(otherClassName, p.getAttributeName()), p.getType(),
342 getAttributeExtensions(a));
343 else
344 throw new RuntimeException("attribute not found!");
345 }
346
347 private MyIdAttribute getOtherPrimaryIdAttribute(ReferentialAttribute a, Reference ref,
348 String otherClassName) {
349 ClassInfo otherInfo = getClassInfo(otherClassName);
350
351 String otherAttributeName;
352 if (ref.getAttribute() == null)
353 otherAttributeName = a.getName();
354 else
355 otherAttributeName = ref.getAttribute();
356 List<MyIdAttribute> members = otherInfo.getPrimaryIdAttributeMembers();
357 for (MyIdAttribute p : members) {
358 if (otherAttributeName.equals(p.getAttributeName())) {
359 return p;
360 }
361 }
362
363 throw new RuntimeException(
364 "could not find attribute <" + ref.getAttribute() + " in class " + otherClassName);
365
366 }
367
368 private ClassInfo getClassInfo(String otherClassName) {
369 ClassInfoo.html#ClassInfo">ClassInfo otherInfo = new ClassInfo(nameManager, lookups.getClassByName(otherClassName),
370 packageName, schema, lookups);
371 return otherInfo;
372 }
373
374 private boolean isActiveSide(BinaryAssociation b) {
375 return b.getActivePerspective().getViewedClass().equals(cls.getName());
376 }
377
378 public boolean hasCompositeId() {
379 return getIdentifierAttributes().get(BigInteger.ONE).size() > 1;
380 }
381
382 private String getFieldName(String attribute) {
383 HashMultimap<BigInteger, Attribute> map = getIdentifierAttributes();
384 Set<Attribute> idAttributes = map.get(BigInteger.ONE);
385 if (idAttributes.size() > 1 || idAttributes.size() == 0)
386 return Util.toJavaIdentifier(attribute);
387 else {
388 if (idAttributes.iterator().next().getName().equals(attribute))
389 return "id";
390 else
391 return Util.toJavaIdentifier(attribute);
392 }
393 }
394
395 private MyIdAttribute createMyIdAttribute(NativeAttribute a) {
396 return new MyIdAttribute(a.getName(), getFieldName(a.getName()),
397 Util.toColumnName(a.getName()), getTypeDefinition(a.getType()),
398 getAttributeExtensions(a));
399 }
400
401 private MyIndependentAttribute createMyIndependentAttribute(NativeAttribute a) {
402
403 boolean inIdentifier = false;
404 for (Attribute attribute : getIdentifierAttributes().values()) {
405 if (a.getName().equals(attribute.getName()))
406 inIdentifier = true;
407 }
408 MyAttributeExtensions extensions = getAttributeExtensions(a);
409 final boolean isNullable;
410 if (inIdentifier)
411 isNullable = false;
412 else
413 isNullable = extensions.isOptional();
414
415 return new MyIndependentAttribute(a.getName(), getFieldName(a.getName()),
416 nameManager.toColumnName(cls.getName(), a.getName()),
417 getTypeDefinition(a.getType()), isNullable, "description", extensions);
418 }
419
420 List<MyIndependentAttribute> getNonPrimaryIdIndependentAttributeMembers() {
421 List<MyIndependentAttribute> list = newArrayList();
422 for (JAXBElement<? extends Attribute> element : cls.getAttribute()) {
423 if (element.getValue() instanceof IndependentAttribute) {
424 IndependentAttribute../xuml/tools/miuml/metamodel/jaxb/IndependentAttribute.html#IndependentAttribute">IndependentAttribute a = (IndependentAttribute) element.getValue();
425 if (!isMemberOfPrimaryIdentifier(a)) {
426 list.add(createMyIndependentAttribute(a));
427 }
428 }
429 }
430 return list;
431 }
432
433 private List<MyIndependentAttribute> getIndependentAttributeMembers() {
434 List<MyIndependentAttribute> list = newArrayList();
435 for (JAXBElement<? extends Attribute> element : cls.getAttribute()) {
436 if (element.getValue() instanceof IndependentAttribute) {
437 IndependentAttribute../xuml/tools/miuml/metamodel/jaxb/IndependentAttribute.html#IndependentAttribute">IndependentAttribute a = (IndependentAttribute) element.getValue();
438 list.add(createMyIndependentAttribute(a));
439 }
440 }
441 return list;
442 }
443
444 private boolean isMemberOfPrimaryIdentifier(IndependentAttribute a) {
445 for (IdentifierAttribute idAttribute : a.getIdentifier()) {
446 if (idAttribute.getNumber().intValue() == 1) {
447 return true;
448 }
449 }
450 return false;
451 }
452
453 List<MyEvent> getEvents() {
454 if (cls.getLifecycle() == null)
455 return newArrayList();
456 List<MyEvent> list = newArrayList();
457 CreationEvent creationEvent = getCreationEvent();
458 for (JAXBElement<? extends Event> element : cls.getLifecycle().getEvent()) {
459 Event event = element.getValue();
460 boolean isCreationEvent = event == creationEvent;
461 MyEvent myEvent = getEvent(event, isCreationEvent);
462 list.add(myEvent);
463 }
464 return list;
465 }
466
467 private MyEvent getEvent(Event event, boolean isCreationEvent) {
468 final StateModelSignature signature;
469 final String stateName;
470
471 if (event.getEventSignature() != null) {
472 signature = event.getEventSignature();
473 stateName = null;
474 } else {
475
476
477 State destinationState = getDestinationState(event);
478 if (destinationState != null) {
479 if (destinationState.getStateSignature() != null)
480 signature = destinationState.getStateSignature();
481 else
482 signature = new StateModelSignature() {
483 @Override
484 public List<StateModelParameter> getStateModelParameter() {
485 return Collections.emptyList();
486 }
487 };
488 stateName = destinationState.getName();
489 } else {
490 signature = null;
491 stateName = null;
492 }
493 }
494
495 if (signature == null)
496 throw new RuntimeException("event/state signature not found for " + cls.getName()
497 + ",event=" + event.getName());
498
499 List<MyParameter> parameters = getParameters(signature);
500
501 MyEvent/MyEvent.html#MyEvent">MyEvent myEvent = new MyEvent(event.getName(), Util.toClassSimpleName(event.getName()),
502 parameters, stateName, getStateSignatureInterfaceName(stateName), isCreationEvent);
503 return myEvent;
504 }
505
506 private List<MyParameter> getParameters(final StateModelSignature signature) {
507 List<MyParameter> parameters = Lists.newArrayList();
508 for (StateModelParameter p : signature.getStateModelParameter()) {
509 parameters.add(new MyParameter(Util.toJavaIdentifier(p.getName()),
510 lookups.getJavaType(p.getType())));
511 }
512 return parameters;
513 }
514
515 private State getDestinationState(Event event) {
516 State destinationState = null;
517
518 for (MyTransition transition : getTransitions()) {
519 if (transition.getEventId().equals(event.getID().toString())) {
520 for (State state : cls.getLifecycle().getState()) {
521 if (transition.getToState().equals(state.getName())) {
522 destinationState = state;
523 }
524 }
525 }
526 }
527 return destinationState;
528 }
529
530 private String getStateSignatureInterfaceName(final String stateName) {
531 if (stateName == null)
532 return null;
533 else
534 return "StateSignature_" + Util.upperFirst(Util.toJavaIdentifier(stateName));
535 }
536
537 Collection<String> getStateNames() {
538 Set<String> set = new TreeSet<String>();
539 if (cls.getLifecycle() == null)
540 return newArrayList();
541 else {
542 for (State state : cls.getLifecycle().getState())
543 set.add(state.getName());
544 return set;
545 }
546 }
547
548 List<MyTransition> getTransitions() {
549 List<MyTransition> list = Lists.newArrayList();
550 for (Transition transition : cls.getLifecycle().getTransition()) {
551
552 String eventName = getEventName(transition.getEventID());
553 list.add(new MyTransition(eventName, Util.toClassSimpleName(eventName),
554 transition.getEventID().toString(), transition.getState(),
555 transition.getDestination()));
556
557 }
558 CreationEvent creation = getCreationEvent();
559 if (creation != null) {
560 String eventName = getEventName(creation.getID());
561 list.add(new MyTransition(eventName, Util.toClassSimpleName(eventName),
562 creation.getID().toString(), null, creation.getState()));
563 }
564 return list;
565 }
566
567 private CreationEvent getCreationEvent() {
568 for (JAXBElement<? extends Event> element : cls.getLifecycle().getEvent()) {
569 if (element.getValue() instanceof CreationEvent)
570 return (CreationEvent) element.getValue();
571 }
572 return null;
573 }
574
575 private String getEventName(BigInteger eventId) {
576 for (JAXBElement<? extends Event> ev : cls.getLifecycle().getEvent()) {
577 if (ev.getValue().getID().equals(eventId))
578 return ev.getValue().getName();
579 }
580 return null;
581 }
582
583 String getStateAsJavaIdentifier(String stateName) {
584 for (State state : cls.getLifecycle().getState())
585 if (state.getName().equals(stateName))
586
587 return Util.toJavaConstantIdentifier(stateName);
588 throw new RuntimeException("state not found: " + stateName);
589 }
590
591 boolean isSuperclass() {
592 return lookups.isSuperclass(cls.getName());
593 }
594
595 boolean isSubclass() {
596 return lookups.isSpecialization(cls.getName());
597 }
598
599 boolean isAssociationClass() {
600 return lookups.associationForAssociationClass(cls.getName()).isPresent();
601 }
602
603 MySubclassRole getSubclassRole() {
604
605 return null;
606 }
607
608 List<MyReferenceMember> getReferenceMembers() {
609
610 List<MyReferenceMember> list = Lists.newArrayList();
611 List<Association> associations = lookups.getAssociations(cls);
612 for (Association a : associations) {
613 List<MyReferenceMember> m = createMyReferenceMembers(a, cls);
614 list.addAll(m);
615 }
616 for (Generalization g : lookups.getGeneralizations()) {
617 for (Named specialization : g.getSpecializedClass()) {
618 if (g.getSuperclass().equals(cls.getName()))
619 list.add(createMyReferenceMember(g, specialization, cls, true));
620 else if (specialization.getName().equals(cls.getName()))
621 list.add(createMyReferenceMember(g, specialization, cls, false));
622 }
623 }
624 Optional<Association> ass = lookups.associationForAssociationClass(cls.getName());
625 if (ass.isPresent()) {
626
627
628 if (ass.get() instanceof BinaryAssociation) {
629 addReferenceMembers(list, ass);
630 }
631
632 }
633 return list;
634 }
635
636 private void addReferenceMembers(List<MyReferenceMember> list, Optional<Association> ass) {
637 {
638 BinaryAssociation b = (BinaryAssociation) ass.get();
639 BinaryAssociation b2 = new BinaryAssociation();
640 ActivePerspectiveivePerspective.html#ActivePerspective">ActivePerspective p1 = new ActivePerspective();
641 p1.setViewedClass(cls.getName());
642 p1.setOnePerspective(b.getActivePerspective().isOnePerspective());
643 p1.setConditional(b.getPassivePerspective().isConditional());
644 p1.setPhrase(b.getActivePerspective().getPhrase());
645 b2.setActivePerspective(p1);
646 PassivePerspectiveivePerspective.html#PassivePerspective">PassivePerspective p2 = new PassivePerspective();
647 p2.setViewedClass(b.getActivePerspective().getViewedClass());
648 p2.setOnePerspective(true);
649 p2.setConditional(false);
650 p2.setPhrase(b.getPassivePerspective().getPhrase());
651 b2.setPassivePerspective(p2);
652 b2.setRnum(b.getRnum());
653 list.addAll(createMyReferenceMembers(b2, cls));
654 }
655
656 {
657 BinaryAssociation b = (BinaryAssociation) ass.get();
658 BinaryAssociation b2 = new BinaryAssociation();
659 ActivePerspectiveivePerspective.html#ActivePerspective">ActivePerspective p1 = new ActivePerspective();
660 p1.setViewedClass(cls.getName());
661 p1.setOnePerspective(b.getActivePerspective().isOnePerspective());
662 p1.setConditional(b.getActivePerspective().isConditional());
663 p1.setPhrase(b.getPassivePerspective().getPhrase());
664 b2.setActivePerspective(p1);
665 PassivePerspectiveivePerspective.html#PassivePerspective">PassivePerspective p2 = new PassivePerspective();
666 p2.setViewedClass(b.getPassivePerspective().getViewedClass());
667 p2.setOnePerspective(true);
668 p2.setConditional(false);
669 p2.setPhrase(b.getActivePerspective().getPhrase());
670 b2.setPassivePerspective(p2);
671 b2.setRnum(b.getRnum());
672 list.addAll(createMyReferenceMembers(b2, cls));
673 }
674 }
675
676 private MyReferenceMember createMyReferenceMember(Generalization g, Named spec, Class cls,
677 boolean isSuperclass) {
678 if (isSuperclass) {
679 return createSuperclassReferenceMember(g, spec, cls);
680 } else {
681 return createNonSuperclassReferenceMember(g, cls);
682 }
683 }
684
685 private MyReferenceMember createNonSuperclassReferenceMember(Generalization g, Class cls) {
686 ClassInfo infoOther = getClassInfo(g.getSuperclass());
687 String fieldName = nameManager.toFieldName(cls.getName(), g.getSuperclass(), g.getRnum());
688 String thisFieldName = nameManager.toFieldName(g.getSuperclass(), cls.getName(),
689 g.getRnum());
690 List<MyJoinColumn> joins = newArrayList();
691 for (MyIdAttribute member : infoOther.getPrimaryIdAttributeMembers()) {
692
693
694 MyJoinColumn jc = createJoinColumn(g, member);
695 joins.add(jc);
696 }
697 return new MyReferenceMember(g.getSuperclass(), infoOther.getClassFullName(), Mult.ZERO_ONE,
698 Mult.ONE, "generalizes", "specializes", fieldName, joins, thisFieldName,
699 (MyJoinTable) null, false, g.getRnum().toString(), Collections.emptyList());
700 }
701
702 private MyJoinColumn createJoinColumn(Generalization g, MyIdAttribute member) {
703 String attributeName = getMatchingAttributeName(g.getRnum(), member.getAttributeName());
704 MyJoinColumn/MyJoinColumn.html#MyJoinColumn">MyJoinColumn jc = new MyJoinColumn(
705 nameManager.toColumnName(g.getSuperclass(), attributeName), member.getColumnName());
706 return jc;
707 }
708
709 private MyReferenceMember createSuperclassReferenceMember(Generalization g, Named spec,
710 Class cls) {
711 ClassInfo infoOther = getClassInfo(spec.getName());
712 String fieldName = nameManager.toFieldName(cls.getName(), spec.getName(), g.getRnum());
713 String thisFieldName = nameManager.toFieldName(spec.getName(), cls.getName(), g.getRnum());
714 return new MyReferenceMember(spec.getName(), infoOther.getClassFullName(), Mult.ONE,
715 Mult.ZERO_ONE, "specializes", "generalizes", fieldName, null, thisFieldName,
716 (MyJoinTable) null, false, g.getRnum().toString(), Collections.emptyList());
717 }
718
719 private List<MyReferenceMember> createMyReferenceMembers(Association a, Class cls) {
720 if (a instanceof BinaryAssociation)
721 return createMyReferenceMembers((BinaryAssociation) a, cls);
722 else
723 return createMyReferenceMember((UnaryAssociation) a, cls);
724 }
725
726 private List<MyReferenceMember> createMyReferenceMember(UnaryAssociation a, Class cls) {
727 SymmetricPerspective p = a.getSymmetricPerspective();
728 List<MyJoinColumn> joins = newArrayList();
729 List<MyJoinColumn> joins2 = newArrayList();
730 for (MyIdAttribute member : getPrimaryIdAttributeMembers()) {
731 String attributeName = member.getAttributeName() + " R" + a.getRnum();
732
733 joins.add(new MyJoinColumn(nameManager.toColumnName(cls.getName(), attributeName),
734 member.getColumnName()));
735 MyJoinColumn/MyJoinColumn.html#MyJoinColumn">MyJoinColumn jc = new MyJoinColumn(member.getColumnName(),
736 nameManager.toColumnName(cls.getName(), attributeName));
737 joins2.add(jc);
738 }
739 List<MyReferenceMember> list = Lists.newArrayList();
740
741 String fieldName1 = nameManager.toFieldName(cls.getName(), p.getPhrase() + " Inverse",
742 a.getRnum());
743 String fieldName2 = nameManager.toFieldName(cls.getName(), p.getPhrase(), a.getRnum());
744
745 Mult fromMult;
746 if (toMult(p).equals(Mult.MANY) || toMult(p).equals(Mult.ZERO_ONE))
747 fromMult = Mult.ZERO_ONE;
748 else
749 fromMult = Mult.ONE;
750
751 list.add(new MyReferenceMember(getJavaClassSimpleName(), getClassFullName(), fromMult,
752 toMult(p), p.getPhrase() + " Inverse", p.getPhrase(), fieldName2, joins2,
753 fieldName1, null, false, a.getRnum().toString(), Collections.emptyList()));
754 list.add(new MyReferenceMember(getJavaClassSimpleName(), getClassFullName(), toMult(p),
755 fromMult, p.getPhrase(), p.getPhrase() + " Inverse", fieldName1, joins, fieldName2,
756 null, false, a.getRnum().toString(), Collections.emptyList()));
757
758 if (a.getAssociationClass() != null) {
759
760
761
762
763
764 }
765 return list;
766 }
767
768 private MyReferenceMember createImplicitReferenceMemberToAssociationClass(UnaryAssociation a,
769 Class cls) {
770 BinaryAssociation a2 = new BinaryAssociation();
771
772 ActivePerspectiveerspective.html#ActivePerspective">ActivePerspective active = new ActivePerspective();
773 active.setPhrase(a.getSymmetricPerspective().getPhrase());
774 active.setOnePerspective(true);
775 active.setConditional(false);
776 active.setViewedClass(cls.getName());
777 a2.setActivePerspective(active);
778
779 PassivePerspectiverspective.html#PassivePerspective">PassivePerspective passive = new PassivePerspective();
780 passive.setConditional(a.getSymmetricPerspective().isConditional());
781 passive.setOnePerspective(a.getSymmetricPerspective().isOnePerspective());
782 passive.setPhrase(a.getSymmetricPerspective().getPhrase() + " Inverse");
783 passive.setViewedClass(a.getAssociationClass());
784 a2.setPassivePerspective(passive);
785 a2.setRnum(a.getRnum());
786 MyReferenceMember ref = createMyReferenceMemberForDirectAssociation(a2, cls, active,
787 passive);
788 return ref;
789 }
790
791 private List<MyReferenceMember> createMyReferenceMembers(BinaryAssociation a, Class cls) {
792 AsymmetricPerspective pThis;
793 AsymmetricPerspective pThat;
794
795 if (a.getActivePerspective().getViewedClass().equals(cls.getName())) {
796 pThis = a.getActivePerspective();
797 pThat = a.getPassivePerspective();
798 } else {
799 pThis = a.getPassivePerspective();
800 pThat = a.getActivePerspective();
801 }
802 List<MyReferenceMember> list = Lists.newArrayList();
803 list.add(createMyReferenceMemberForDirectAssociation(a, cls, pThis, pThat));
804 if (a.getAssociationClass() != null) {
805 {
806 MyReferenceMember ref = createImplicitReferenceMemberToAssociationClass(a, cls,
807 pThis, pThat);
808 list.add(ref);
809 }
810 }
811 return list;
812 }
813
814 private MyReferenceMember createImplicitReferenceMemberToAssociationClass(BinaryAssociation a,
815 Class cls, AsymmetricPerspective pThis, AsymmetricPerspective pThat) {
816 BinaryAssociation a2 = new BinaryAssociation();
817 ActivePerspectiveerspective.html#ActivePerspective">ActivePerspective active = new ActivePerspective();
818 active.setPhrase(pThis.getPhrase());
819 active.setOnePerspective(true);
820 active.setConditional(false);
821 active.setViewedClass(cls.getName());
822 a2.setActivePerspective(active);
823
824 PassivePerspectiverspective.html#PassivePerspective">PassivePerspective passive = new PassivePerspective();
825 passive.setConditional(pThat.isConditional());
826 passive.setOnePerspective(false);
827 passive.setPhrase(pThat.getPhrase());
828 passive.setViewedClass(a.getAssociationClass());
829 a2.setPassivePerspective(passive);
830 a2.setRnum(a.getRnum());
831 MyReferenceMember ref = createMyReferenceMemberForDirectAssociation(a2, cls, active,
832 passive);
833 return ref;
834 }
835
836 private MyReferenceMember createMyReferenceMemberForDirectAssociation(BinaryAssociation a,
837 Class cls, AsymmetricPerspective pThis, AsymmetricPerspective pThat) {
838
839 String otherClassName = pThat.getViewedClass();
840 ClassInfo infoOther = getClassInfo(otherClassName);
841
842 List<MyJoinColumn> joins;
843 if (pThat.isOnePerspective())
844 joins = getJoinColumns(a.getRnum(), cls, infoOther);
845 else
846 joins = Lists.newArrayList();
847
848 final String fieldName = nameManager.toFieldName(cls.getName(), pThat.getViewedClass(),
849 a.getRnum());
850
851 List<OtherId> otherIds = infoOther.getPrimaryIdAttributeMembers().stream()
852 .map(att -> new OtherId(att.getFieldName(), att.getType()))
853 .collect(Collectors.toList());
854
855
856 String mappedBy = nameManager.toFieldName(otherClassName, cls.getName(), a.getRnum());
857 boolean inPrimaryId = inPrimaryId(a.getRnum());
858
859 MyJoinTable manyToMany = createManyToMany(a, cls, infoOther, pThis, pThat);
860
861 return new MyReferenceMember(otherClassName, infoOther.getClassFullName(), toMult(pThis),
862 toMult(pThat), pThis.getPhrase(), pThat.getPhrase(), fieldName, joins, mappedBy,
863 manyToMany, inPrimaryId, a.getRnum().toString(), otherIds);
864 }
865
866 public static class OtherId {
867
868 private final String fieldName;
869 private final MyTypeDefinition type;
870
871 OtherId(String fieldName, MyTypeDefinition type) {
872 this.fieldName = fieldName;
873 this.type = type;
874 }
875
876 public String getFieldName() {
877 return fieldName;
878 }
879
880 public MyTypeDefinition getType() {
881 return type;
882 }
883
884 @Override
885 public String toString() {
886 return "OtherId [fieldName=" + fieldName + ", type=" + type + "]";
887 }
888
889 }
890
891 private List<MyJoinColumn> getJoinColumns(BigInteger rnum, Class cls, ClassInfo infoOther) {
892 List<MyJoinColumn> joins = Lists.newArrayList();
893 for (MyIdAttribute member : infoOther.getPrimaryIdAttributeMembers()) {
894 String attributeName = getMatchingAttributeName(rnum, member.getAttributeName());
895 MyJoinColumn/MyJoinColumn.html#MyJoinColumn">MyJoinColumn jc = new MyJoinColumn(
896 nameManager.toColumnName(cls.getName(), attributeName), member.getColumnName());
897 joins.add(jc);
898 }
899 return joins;
900 }
901
902 private MyJoinTable createManyToMany(BinaryAssociation a, Class cls, ClassInfo infoOther,
903 AsymmetricPerspective pThis, AsymmetricPerspective pThat) {
904 if (!pThis.isOnePerspective() && !pThat.isOnePerspective()) {
905 String joinClass;
906 final List<MyJoinColumn> joinColumns = Lists.newArrayList();
907 final List<MyJoinColumn> inverseJoinColumns = Lists.newArrayList();
908 if (a.getAssociationClass() == null) {
909
910
911
912 joinClass = getImplicitJoinClass(pThis, pThat);
913 for (MyIdAttribute member : getPrimaryIdAttributeMembers()) {
914 joinColumns.add(new MyJoinColumn(
915 nameManager.toColumnName(joinClass,
916 cls.getName() + " " + member.getAttributeName()),
917 member.getColumnName()));
918 }
919 for (MyIdAttribute member : infoOther.getPrimaryIdAttributeMembers()) {
920 inverseJoinColumns.add(new MyJoinColumn(
921 nameManager.toColumnName(joinClass,
922 infoOther.getName() + " " + member.getAttributeName()),
923 member.getColumnName()));
924 }
925 } else {
926 joinClass = a.getAssociationClass();
927 ClassInfo joinInfo = getClassInfo(joinClass);
928 for (MyIdAttribute member : getPrimaryIdAttributeMembers()) {
929 String otherAttributeName = joinInfo
930 .getMatchingAttributeNameForAssociativeReference(a.getRnum(),
931 cls.getName(), member.getAttributeName());
932 joinColumns.add(new MyJoinColumn(
933 nameManager.toColumnName(joinClass, otherAttributeName),
934 member.getColumnName()));
935 }
936 for (MyIdAttribute member : infoOther.getPrimaryIdAttributeMembers()) {
937 String otherAttributeName = joinInfo
938 .getMatchingAttributeNameForAssociativeReference(a.getRnum(),
939 infoOther.getName(), member.getAttributeName());
940 inverseJoinColumns.add(new MyJoinColumn(
941 nameManager.toColumnName(joinClass, otherAttributeName),
942 member.getColumnName()));
943 }
944 }
945
946 MyJoinTableo/MyJoinTable.html#MyJoinTable">MyJoinTable mm = new MyJoinTable(nameManager.toTableName(getSchema(), joinClass),
947 getSchema(), joinColumns, inverseJoinColumns);
948 return mm;
949 } else
950 return null;
951 }
952
953 private String getImplicitJoinClass(AsymmetricPerspective pThis, AsymmetricPerspective pThat) {
954 String joinClass;
955 if (pThis.getViewedClass().compareTo(pThat.getViewedClass()) < 0)
956 joinClass = pThis.getViewedClass() + " " + pThat.getViewedClass();
957 else
958 joinClass = pThat.getViewedClass() + " " + pThis.getViewedClass();
959 return joinClass;
960 }
961
962 private String getMatchingAttributeNameForAssociativeReference(BigInteger rNum,
963 String otherClassName, String otherAttributeName) {
964 for (JAXBElement<? extends Attribute> element : cls.getAttribute()) {
965 Attribute a = element.getValue();
966 if (a instanceof ReferentialAttribute) {
967 ReferentialAttribute r = (ReferentialAttribute) a;
968 if (r.getReference().getValue() instanceof AssociativeReference) {
969 AssociativeReference./xuml/tools/miuml/metamodel/jaxb/AssociativeReference.html#AssociativeReference">AssociativeReference ar = (AssociativeReference) r.getReference().getValue();
970 if (ar.getRelationship().equals(rNum)
971 && ar.getAttribute().equals(otherAttributeName)
972 && ar.getClazz().equals(otherClassName))
973 return r.getName();
974 }
975 }
976 }
977 throw new RuntimeException("could not find matching attribute " + cls.getName() + " R"
978 + rNum + " " + otherClassName + "." + otherAttributeName);
979 }
980
981 private boolean inPrimaryId(BigInteger rnum) {
982 for (JAXBElement<? extends Attribute> element : cls.getAttribute()) {
983 Attribute a = element.getValue();
984 if (a instanceof ReferentialAttribute) {
985 ReferentialAttribute r = (ReferentialAttribute) a;
986 if (r.getReference().getValue().getRelationship().equals(rnum))
987 for (IdentifierAttribute ia : r.getIdentifier()) {
988 if (ia.getNumber().equals(BigInteger.ONE))
989 return true;
990 }
991 }
992 }
993 return false;
994 }
995
996 private String getMatchingAttributeName(BigInteger rNum, String otherAttributeName) {
997 for (JAXBElement<? extends Attribute> element : cls.getAttribute()) {
998 Attribute a = element.getValue();
999 if (a instanceof ReferentialAttribute) {
1000 ReferentialAttribute r = (ReferentialAttribute) a;
1001 if (r.getReference().getValue().getRelationship().equals(rNum)
1002 && r.getReference().getValue().getAttribute().equals(otherAttributeName))
1003 return r.getName();
1004 }
1005 }
1006 throw new RuntimeException("could not find matching attribute " + cls.getName() + " R"
1007 + rNum + " " + otherAttributeName);
1008 }
1009
1010 private static Mult toMult(Perspective p) {
1011 if (p.isConditional() && p.isOnePerspective())
1012 return Mult.ZERO_ONE;
1013 else if (p.isConditional() && !p.isOnePerspective())
1014 return Mult.MANY;
1015 else if (p.isOnePerspective())
1016 return Mult.ONE;
1017 else
1018 return Mult.ONE_MANY;
1019 }
1020
1021 Set<String> getAtLeastOneFieldChecks() {
1022
1023 return Sets.newHashSet();
1024 }
1025
1026 String getImports(String relativeToClass) {
1027 return getTypes().getImports(relativeToClass);
1028 }
1029
1030 String getIdColumnName() {
1031
1032 return "ID";
1033 }
1034
1035 String getContextPackageName() {
1036
1037 return packageName;
1038 }
1039
1040 TypeRegister getTypes() {
1041 return typeRegister;
1042 }
1043
1044 Type getType(String name) {
1045 String javaClassName = lookups.getJavaType(name);
1046 return new Type(javaClassName);
1047 }
1048
1049 public List<MySpecializations> getSpecializations() {
1050 List<MySpecializations> list = Lists.newArrayList();
1051
1052 for (Generalization g : lookups.getGeneralizations()) {
1053 if (g.getSuperclass().equals(cls.getName())) {
1054 Set<String> fieldNames = Sets.newHashSet();
1055 for (Named spec : g.getSpecializedClass()) {
1056
1057 String attributeName = null;
1058 for (JAXBElement<? extends Attribute> element : cls.getAttribute()) {
1059 if (element.getValue() instanceof ReferentialAttribute) {
1060 ReferentialAttribute r = (ReferentialAttribute) element.getValue();
1061 Reference ref = r.getReference().getValue();
1062 if (ref instanceof SpecializationReference) {
1063 if (ref.getRelationship().equals(g.getRnum()))
1064 attributeName = r.getName();
1065 }
1066 }
1067 }
1068 if (attributeName == null)
1069 throw new RuntimeException(
1070 "could not find attribute name for generalization " + g.getRnum()
1071 + ", specialization " + spec.getName());
1072 String fieldName = nameManager.toFieldName(cls.getName(), spec.getName(),
1073 g.getRnum());
1074 fieldNames.add(fieldName);
1075 }
1076 list.add(new MySpecializations(g.getRnum(), fieldNames));
1077 }
1078 }
1079 return list;
1080 }
1081
1082 public List<MyFind> getFinders() {
1083 Map<String, MyIndependentAttribute> map = Maps.newHashMap();
1084 for (MyIndependentAttribute a : getIndependentAttributeMembers())
1085 map.put(a.getAttributeName(), a);
1086
1087 List<MyFind> finds = Lists.newArrayList();
1088 for (Extension ext : cls.getExtension()) {
1089 for (Object any : ext.getAny()) {
1090 Object e = getJaxbElementValue(any);
1091 if (e != null && e instanceof Find) {
1092 Find find = (Find) e;
1093 List<MyIndependentAttribute> list = Lists.newArrayList();
1094 for (xuml.tools.miuml.metamodel.extensions.jaxb.Attribute attribute : find
1095 .getAttribute())
1096 list.add(map.get(attribute.getName()));
1097 finds.add(new MyFind(list));
1098 }
1099 }
1100 }
1101 return finds;
1102 }
1103
1104 public MyTypeDefinition getTypeDefinition(String name) {
1105 AtomicType t = lookups.getAtomicType(name);
1106 if (t instanceof SymbolicType)
1107 return getTypeDefinition((SymbolicType) t);
1108 else if (t instanceof BooleanType)
1109 return getTypeDefinition((BooleanType) t);
1110 else if (t instanceof EnumeratedType)
1111 return getTypeDefinition((EnumeratedType) t);
1112 else if (t instanceof IntegerType)
1113 return getTypeDefinition((IntegerType) t);
1114 else if (t instanceof RealType)
1115 return getTypeDefinition((RealType) t);
1116 else
1117 throw new RuntimeException("unexpected");
1118 }
1119
1120 private MyTypeDefinition getTypeDefinition(RealType t) {
1121 return new MyTypeDefinition(t.getName(), MyType.REAL, new Type(Double.class), t.getUnits(),
1122 t.getPrecision(), t.getLowerLimit(), t.getUpperLimit(), t.getDefaultValue() + "",
1123 null, null, null, null, null, null);
1124 }
1125
1126 private MyTypeDefinition getTypeDefinition(IntegerType t) {
1127 MyType myType;
1128 Type type;
1129
1130 if ("date".equals(t.getName())) {
1131 myType = MyType.DATE;
1132 type = new Type(Date.class);
1133 } else if ("timestamp".equals(t.getName())) {
1134 myType = MyType.TIMESTAMP;
1135 type = new Type(Date.class);
1136 } else {
1137 myType = MyType.INTEGER;
1138 type = new Type(Integer.class);
1139 }
1140
1141 return new MyTypeDefinition(t.getName(), myType, type, t.getUnits(), null,
1142 toBigDecimal(t.getLowerLimit()), toBigDecimal(t.getUpperLimit()),
1143 toString(t.getDefaultValue()), null, null, null, null, null, null);
1144 }
1145
1146 private static BigDecimal toBigDecimal(BigInteger n) {
1147 if (n == null)
1148 return null;
1149 else
1150 return new BigDecimal(n);
1151 }
1152
1153 private static String toString(BigInteger n) {
1154 if (n == null)
1155 return null;
1156 else
1157 return n.toString();
1158 }
1159
1160 private MyTypeDefinition getTypeDefinition(EnumeratedType t) {
1161
1162 return new MyTypeDefinition(t.getName(), MyType.STRING, new Type(String.class), null, null,
1163 null, null, t.getDefaultValue().toString(), null, BigInteger.ONE,
1164 BigInteger.valueOf(4096L), "", "", ".*");
1165 }
1166
1167 private MyTypeDefinition getTypeDefinition(BooleanType t) {
1168 return new MyTypeDefinition(t.getName(), MyType.BOOLEAN, new Type(Boolean.class), null,
1169 null, null, null, ((Boolean) t.isDefaultValue()).toString(), null, null, null, null,
1170 null, null);
1171 }
1172
1173 private MyTypeDefinition getTypeDefinition(SymbolicType t) {
1174 if (t.getName().equalsIgnoreCase("bytes")) {
1175 return new MyTypeDefinition(t.getName(), MyType.BYTES, new Type(byte.class, true), null,
1176 null, null, null, t.getDefaultValue().toString(), null, t.getMinLength(),
1177 t.getMaxLength(), t.getPrefix(), t.getSuffix(), t.getValidationPattern());
1178 } else
1179 return new MyTypeDefinition(t.getName(), MyType.STRING, new Type(String.class), null,
1180 null, null, null, t.getDefaultValue().toString(), null, t.getMinLength(),
1181 t.getMaxLength(), t.getPrefix(), t.getSuffix(), t.getValidationPattern());
1182 }
1183
1184 final public String getBehaviourPackage() {
1185 return getPackage() + ".behaviour";
1186 }
1187
1188 final public String getBehaviourFactoryFullClassName() {
1189 return getBehaviourPackage() + "." + getBehaviourFactorySimpleName();
1190 }
1191
1192 final public String getBehaviourFullClassName() {
1193 return getBehaviourPackage() + "." + getJavaClassSimpleName() + "Behaviour";
1194 }
1195
1196 final public String getBehaviourFactorySimpleName() {
1197 return getJavaClassSimpleName() + "BehaviourFactory";
1198 }
1199
1200 final public String addType(java.lang.Class<?> cls) {
1201 return getTypes().addType(cls);
1202 }
1203
1204 final public void addTypes(java.lang.Class<?>... classes) {
1205 getTypes().addTypes(classes);
1206 }
1207
1208 final public String addType(String fullClassName) {
1209 return getTypes().addType(fullClassName);
1210 }
1211
1212 final public String addType(Type type) {
1213 return getTypes().addType(type);
1214 }
1215
1216 final public String getContextFullClassName() {
1217 return getContextPackageName() + ".Context";
1218 }
1219
1220 final public String getBehaviourFactoryFieldName() {
1221 return Util.toJavaIdentifier(getBehaviourFactorySimpleName());
1222 }
1223
1224 final public String getClassFullName() {
1225
1226 return getPackage() + "." + getJavaClassSimpleName();
1227 }
1228
1229 public String getEmbeddedIdSimpleClassName() {
1230 return getJavaClassSimpleName() + "Id";
1231 }
1232
1233 public String getEmbeddedIdAttributeName() {
1234 return "id";
1235 }
1236
1237 public boolean hasBehaviour() {
1238 return getEvents().size() > 0;
1239 }
1240
1241 public boolean useGuiceInjection() {
1242
1243 return "true".equalsIgnoreCase(System.getProperty("guice"));
1244 }
1245
1246 }