View Javadoc
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   * Provides information about a metmodel Class definition.
86   * 
87   * @author dxm
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      * Constructor.
102      * 
103      * @param nameManager
104      * @param cls
105      * @param packageName
106      * @param classDescription
107      * @param schema
108      * @param lookups
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      * The full package name
121      * 
122      * @return
123      */
124     String getPackage() {
125         return packageName;
126     }
127 
128     /**
129      * Returns the class description.
130      * 
131      * @return
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      * Returns the list of groups of unique column names for the class.
143      * 
144      * @return
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      * Returns the name of the class.
162      * 
163      * @return
164      */
165     public String getName() {
166         return cls.getName();
167     }
168 
169     /**
170      * Returns the Attributes from this class involved in a each identifier as a
171      * Map.
172      * 
173      * @return
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             // extension will not be used because not recognized
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             // TODO
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         // look for attribute
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         // not found
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             // TODO of eventSignature is null then get signature from
476             // destination state
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             // TODO what to do about event name? Event inheritance is involved.
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                 // TODO use nameManager
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         // TODO Auto-generated method stub
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             // current class is an Association Class so prepare the implicit
627             // associations from the ends to the Association Class
628             if (ass.get() instanceof BinaryAssociation) {
629                 addReferenceMembers(list, ass);
630             }
631             // TODO handle unary association classes
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             // TODO handle when matching attribute not found, use some
693             // default, see schema
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             // TODO get this working
760             // MyReferenceMember ref =
761             // createImplicitReferenceMemberToAssociationClass(
762             // a, cls);
763             // list.add(ref);
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         // now establish the name of the field for this class as seen in the
855         // other class
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                 // TODO use NameManager to get implicit join class name, must do
910                 // this because there could be multiple many to many
911                 // associations between the two classes.
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         // TODO Auto-generated method stub
1023         return Sets.newHashSet();
1024     }
1025 
1026     String getImports(String relativeToClass) {
1027         return getTypes().getImports(relativeToClass);
1028     }
1029 
1030     String getIdColumnName() {
1031         // TODO Auto-generated method stub
1032         return "ID";
1033     }
1034 
1035     String getContextPackageName() {
1036         // TODO Auto-generated method stub
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                     // get the attribute name
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         // TODO do something type safe using generated enum because we can
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         // TODO is this the best way to specify guice injection?
1243         return "true".equalsIgnoreCase(System.getProperty("guice"));
1244     }
1245 
1246 }