001: // This file is part of KeY - Integrated Deductive Software Design
002: // Copyright (C) 2001-2007 Universitaet Karlsruhe, Germany
003: // Universitaet Koblenz-Landau, Germany
004: // Chalmers University of Technology, Sweden
005: //
006: // The KeY system is protected by the GNU General Public License.
007: // See LICENSE.TXT for details.
008: //
009: //
010:
011: package de.uka.ilkd.key.casetool.together;
012:
013: import java.io.File;
014: import java.util.*;
015:
016: import com.togethersoft.openapi.ide.project.IdeProject;
017: import com.togethersoft.openapi.ide.project.IdeProjectManager;
018: import com.togethersoft.openapi.ide.project.IdeProjectManagerAccess;
019: import com.togethersoft.openapi.rwi.*;
020: import com.togethersoft.openapi.sci.SciElement;
021: import com.togethersoft.openapi.sci.SciModel;
022: import com.togethersoft.openapi.sci.SciModelAccess;
023:
024: import de.uka.ilkd.key.casetool.*;
025: import de.uka.ilkd.key.collection.IteratorOfString;
026: import de.uka.ilkd.key.collection.ListOfString;
027: import de.uka.ilkd.key.collection.SLListOfString;
028: import de.uka.ilkd.key.java.Services;
029: import de.uka.ilkd.key.speclang.*;
030: import de.uka.ilkd.key.speclang.ocl.OCLClassInvariant;
031: import de.uka.ilkd.key.util.Debug;
032:
033: /**
034: * Central point of access to Together model.
035: */
036: public class TogetherModelClass extends TogetherReprModel implements
037: UMLModelClass {
038:
039: private static final String CLASS = "Class";
040:
041: private RwiNode orig;
042: private RwiModel currRwiModel;
043: private RwiDiagram currRwiDiagram;
044:
045: private RwiNode origParent;
046: private boolean origParentAlreadySet = false;
047:
048: private String name;
049: private String inv;
050: private String fullName;
051: private String throughout;
052: private String rootDir;
053:
054: public TogetherModelClass(RwiNode theOrig, RwiModel model,
055: RwiDiagram diag) {
056: orig = theOrig;
057: currRwiModel = model;
058: currRwiDiagram = diag;
059: name = orig.getProperty(RwiProperty.NAME);
060: fullName = orig.getProperty(RwiProperty.FULL_NAME);
061: inv = orig.getProperty("invariants");
062: throughout = orig.getProperty("throughout");
063: rootDir = createRootDirectory();
064: }
065:
066: public String getClassName() {
067: return name;
068: }
069:
070: public String getContainingPackage() {
071: String localFullName = getFullClassName();
072: if (localFullName.lastIndexOf(".") == -1) {
073: return null;
074: } else {
075: return localFullName.substring(0, localFullName
076: .lastIndexOf("."));
077: }
078: }
079:
080: public String getFullClassName() {
081: return fullName;
082: }
083:
084: // looks if orig has a parent and set it if needed
085: private RwiNode getOrigParent() {
086: if (origParentAlreadySet) {
087: return origParent;
088: } else {
089: if (orig.getProperty(RwiProperty.EXTENDS) == null) {
090: origParent = null;
091: } else {
092: Enumeration extended = orig
093: .properties(RwiProperty.EXTENDS);
094: while (extended.hasMoreElements()) {
095: RwiProperty nextExtended = (RwiProperty) extended
096: .nextElement();
097: RwiPropertyMap subpropertiesContainer = nextExtended
098: .getSubproperties();
099: RwiElement foundClassOrInterface = currRwiModel
100: .findElement(subpropertiesContainer
101: .getProperty(RwiProperty.REFERENCED_ELEMENT));
102: if (foundClassOrInterface != null
103: && foundClassOrInterface.getProperty(
104: RwiProperty.SHAPE_TYPE).equals(
105: RwiShapeType.CLASS)) {
106: // we have found from the parents the
107: // (unique iff it exists)
108: // element which is a class
109: RwiReference foundRwiReference = currRwiDiagram
110: .findReference(foundClassOrInterface);
111: if (foundRwiReference == null) {
112: // there is a superclass but not in the
113: // current diagram
114: origParentAlreadySet = true;
115: return null;
116: }
117: assert foundRwiReference instanceof RwiNodeReference : "Unexpected type.";
118: RwiNodeReference foundRwiNodeReference = (RwiNodeReference) foundRwiReference;
119: origParent = foundRwiNodeReference.getNode();
120: }
121: } //while
122: }
123: origParentAlreadySet = true;
124: }
125: return origParent;
126: }
127:
128: // Now, a service for ReprModelMeth
129: // @param aUniqueMethName is a name getting from aRwiMember.getUniqueName()
130: // @return the method declaration of param in the parents of the current
131: // class
132: public RwiMember findParentMeth(String aUniqueMethName) {
133: String origClassName = getFullClassName();
134: String candMethName = substituteCNinUniqueMethName(
135: aUniqueMethName, origClassName);
136: if (candMethName.equals(aUniqueMethName)) {
137: // a Method of aUniqueMethName exists within orig
138: // So, we have to ask the parent
139: if (getOrigParent() == null) {
140: return null;
141: } else {
142: TogetherModelClass parentReprClass = new TogetherModelClass(
143: getOrigParent(), currRwiModel, currRwiDiagram);
144: return (parentReprClass.findParentMeth(aUniqueMethName));
145: }
146: } else {
147: // we have to look if candMethName really exists in the model
148: // If not, we ask our parent
149: RwiMember returnvalue = (RwiMember) currRwiModel
150: .findElement(candMethName);
151: if (returnvalue == null) {
152: if (getOrigParent() != null) {
153: TogetherModelClass parentReprClass = new TogetherModelClass(
154: getOrigParent(), currRwiModel,
155: currRwiDiagram);
156: returnvalue = parentReprClass
157: .findParentMeth(aUniqueMethName);
158: }
159: }
160: return returnvalue;
161: }
162: }
163:
164: private String substituteCNinUniqueMethName(String uName,
165: String newClassName) {
166: // region between 2nd and 3rd '#' is substituted by newClassName
167: int firstOcc = uName.indexOf('#', 0);
168: int secondOcc = uName.indexOf('#', firstOcc + 1);
169: int thirdOcc = uName.indexOf('#', secondOcc + 1);
170: String beginning = uName.substring(0, secondOcc + 1);
171: String ending = uName.substring(thirdOcc, uName.length());
172: return beginning + newClassName + ending;
173: }
174:
175: public String getMyInv() {
176: return ((inv == null) ? "" : inv);
177: }
178:
179: public String getMyThroughout() {
180: return ((throughout == null) ? "" : throughout);
181: }
182:
183: /** relies on a valid backing RWI model element, i.e. the together
184: * project is still valid (opened)
185: * @author Kristofer Johannisson
186: */
187: public void setMyInv(String inv) {
188: this .inv = inv;
189: orig.setProperty("invariants", inv);
190: }
191:
192: /** relies on a valid backing RWI model element, i.e. the together
193: * project is still valid (opened)
194: * @author Kristofer Johannisson
195: */
196: public void setMyInvGFAbs(String inv) {
197: orig.setProperty("invariantGFAbstractSyntax", inv);
198: }
199:
200: /** relies on a valid backing RWI model element, i.e. the together
201: * project is still valid (opened)
202: * @author Kristofer Johannisson
203: */
204: public String getMyInvGFAbs() {
205: String result = orig.getProperty("invariantGFAbstractSyntax");
206: if (result == null)
207: return "";
208: else
209: return result;
210: }
211:
212: /** relies on a valid backing RWI model element, i.e. the together
213: * project is still valid (opened)
214: * @return the invariant of the parent
215: */
216: public String getParentInv() {
217: if (getOrigParent() != null) {
218: ModelClass parentRepr = new TogetherModelClass(
219: getOrigParent(), currRwiModel, currRwiDiagram);
220: return parentRepr.getMyInv();
221: } else {
222: return "";
223: }
224: }
225:
226: /** relies on a valid backing RWI model element, i.e. the together
227: * project is still valid (opened)
228: * @return the classname of the parent
229: */
230: public String getParentClassName() {
231: if (getOrigParent() != null) {
232: ModelClass parentRepr = new TogetherModelClass(
233: getOrigParent(), currRwiModel, currRwiDiagram);
234: return parentRepr.getClassName();
235: } else {
236: return "";
237: }
238: }
239:
240: /** relies on a valid backing RWI model element, i.e. the together
241: * project is still valid (opened)
242: */
243: public boolean hasOrigParent() {
244: return (getOrigParent() != null);
245: }
246:
247: /** relies on a valid backing RWI model element, i.e. the together
248: * project is still valid (opened)
249: * @return a vector of ModelMethod
250: */
251: public Vector getParentOps() {
252: if (getOrigParent() != null) {
253: UMLModelClass parentRepr = new TogetherModelClass(
254: getOrigParent(), currRwiModel, currRwiDiagram);
255: return parentRepr.getOps();
256: } else {
257: return null;
258: }
259: }
260:
261: /** relies on a valid backing RWI model element, i.e. the together
262: * project is still valid (opened)
263: * @return a vector of String
264: */
265: public Vector getInheritedOpNames() {
266: Vector opNames = getInheritedOps();
267: Vector result = new Vector();
268: if (opNames != null) {
269: for (int i = 0; i < opNames.size(); i++)
270: result.addElement(((TogetherModelMethod) opNames
271: .elementAt(i)).getName());
272: return result;
273: } else {
274: return null;
275: }
276:
277: }
278:
279: /** relies on a valid backing RWI model element, i.e. the together
280: * project is still valid (opened)
281: * @return a vector of ReprModelMethod
282: */
283: public Vector getInheritedOps() {
284: Vector opVector = getParentOps();
285: Vector result = new Vector();
286: TogetherModelMethod op;
287: if (opVector != null) {
288: for (int i = 0; i < opVector.size(); i++) {
289: op = (TogetherModelMethod) (opVector.elementAt(i));
290: if (!op.isConstructor() && !op.isPrivate()) {
291: result.addElement(opVector.elementAt(i));
292: }
293:
294: }
295: return result;
296: } else {
297: return null;
298: }
299:
300: }
301:
302: /** relies on a valid backing RWI model element, i.e. the together
303: * project is still valid (opened)
304: * @return a vector of String
305: */
306: public Vector getOpNames() {
307: Enumeration allMembers = orig.members();
308: Vector opMemberNames = new Vector();
309: while (allMembers.hasMoreElements()) {
310: RwiMember nextMember = (RwiMember) allMembers.nextElement();
311: if (RwiShapeType.OPERATION.equals(nextMember
312: .getProperty(RwiProperty.SHAPE_TYPE))) {
313: opMemberNames.add(nextMember
314: .getProperty(RwiProperty.NAME));
315: }
316: }
317: return opMemberNames;
318: }
319:
320: /** relies on a valid backing RWI model element, i.e. the together
321: * project is still valid (opened)
322: * @return a vector of ReprModelMethod
323: */
324: public Vector getOps() {
325: Enumeration allMembers = orig.members();
326: Vector opVector = new Vector();
327: while (allMembers.hasMoreElements()) {
328: RwiMember nextMember = (RwiMember) allMembers.nextElement();
329: if (RwiShapeType.OPERATION.equals(nextMember
330: .getProperty(RwiProperty.SHAPE_TYPE))) {
331: opVector.add(new TogetherModelMethod(nextMember,
332: currRwiModel, currRwiDiagram));
333: }
334: }
335: return opVector;
336: }
337:
338: /** relies on a valid backing RWI model element, i.e. the together
339: * project is still valid (opened)
340: */
341: private String getAssociationRole(RwiElement rwiMember,
342: RwiLink link, String which) {
343: SciModel model = SciModelAccess.getModel();
344: String role;
345: role = model.findElement(rwiMember.getUniqueName())
346: .getTagList().getTagValue(which);
347: if (role == null) {
348: if ("clientRole".equals(which))
349: role = link.getSource().toString();
350: else if ("supplierRole".equals(which))
351: role = link.getDestination().toString();
352: else
353: return null;
354: role = role.substring(0, 1).toLowerCase()
355: + role.substring(1, role.length());
356: }
357: return role;
358: }
359:
360: /** relies on a valid backing RWI model element, i.e. the together
361: * project is still valid (opened)
362: */
363: public String getText() {
364: return orig.getProperty(RwiProperty.TEXT);
365: }
366:
367: /** relies on a valid backing RWI / SCI model element, i.e. the together
368: * project is still valid (opened)
369: */
370: private HashSet getAllJavaFiles(RwiPackage pac, HashSet v) {
371: Enumeration subpackages = pac.subpackages();
372: while (subpackages.hasMoreElements()) {
373: v = getAllJavaFiles((RwiPackage) subpackages.nextElement(),
374: v);
375: }
376: Enumeration en = pac.nodes();
377: while (en.hasMoreElements()) {
378: RwiElement rwin = (RwiElement) en.nextElement();
379: if (rwin.getProperty(RwiProperty.SHAPE_TYPE).equals(CLASS)) {
380: String filename = rwin.getProperty(RwiProperty.FILE);
381: if (filename != null && filename.endsWith(".java")) {
382: v.add(filename);
383: Debug.out("Let recoder read file: " + filename);
384: }
385: }
386: }
387: return v;
388: }
389:
390: /** relies on a valid backing RWI / SCI model element, i.e. the together
391: * project is still valid (opened)
392: */
393: public String[] getClassesInPackage() {
394: HashSet v = new HashSet();
395: RwiPackage rootPac = orig.getContainingPackage();
396: while (rootPac.getContainingPackage() != null) {
397: rootPac = rootPac.getContainingPackage();
398: }
399: v = getAllJavaFiles(rootPac, v);
400: String[] strings = new String[v.size()];
401: Iterator it = v.iterator();
402: int i = 0;
403: while (it.hasNext()) {
404: strings[i] = (String) it.next();
405: i++;
406: }
407: return strings;
408: }
409:
410: /** returns the root directory of the active project */
411: public String getRootDirectory() {
412: return rootDir;
413: }
414:
415: public String createRootDirectory() {
416: IdeProjectManager pm = IdeProjectManagerAccess
417: .getProjectManager();
418: IdeProject prj = pm.getActiveProject();
419: File f = new File(prj.getFileName());
420: return f.getParentFile().getAbsolutePath();
421: }
422:
423: /** returns all classes of the currently loaded project
424: */
425: public Set getAllClasses() {
426: // Put everything in "result" by recursing, set result to an
427: // empty HashSet in case this method gets called more than once.
428: RwiPackage rootPackage = orig.getContainingPackage();
429: //this did not work (Tg bug!?):
430: //rootPackage.getContainingPackage()!=null
431: while (rootPackage.getContainingPackage() != null
432: && rootPackage.getContainingPackage().nodes()
433: .hasMoreElements()) {
434: rootPackage = rootPackage.getContainingPackage();
435: }
436: Set result = new HashSet();
437: rwiRecurse(rootPackage.nodes(), result);
438: return result;
439: }
440:
441: // this method adds to "result"!
442: private void rwiRecurse(Enumeration nodeEnum, Set result) {
443: RwiNode node = null;
444: ModelClass reprClass = null;
445: while (nodeEnum.hasMoreElements()) {
446: node = (RwiNode) nodeEnum.nextElement();
447: if (RwiShapeType.CLASS.equals(node
448: .getProperty(RwiProperty.SHAPE_TYPE))) {
449: // current RwiNode is "node"
450: RwiModel model = RwiModelAccess.getModel();
451: RwiDiagram diagram = model.findDiagramFor(node);
452:
453: reprClass = new TogetherModelClass(node, model, diagram);
454: result.add(reprClass);
455: } else {
456: rwiRecurse(node.subnodes(), result);
457: }
458: }
459: }
460:
461: public ListOfClassInvariant getMyClassInvariants() {
462: ListOfClassInvariant result = SLListOfClassInvariant.EMPTY_LIST;
463:
464: String myInv = getMyInv();
465: if (!myInv.equals("")) {
466: ClassInvariant invariant = new OCLClassInvariant(this ,
467: myInv);
468: result = result.append(invariant);
469: }
470:
471: return result;
472: }
473:
474: public ListOfClassInvariant getMyThroughoutClassInvariants() {
475: ListOfClassInvariant result = SLListOfClassInvariant.EMPTY_LIST;
476:
477: String myThroughout = getMyThroughout();
478: if (!myThroughout.equals("")) {
479: ClassInvariant invariant = new OCLClassInvariant(this ,
480: myThroughout);
481: result = result.append(invariant);
482: }
483:
484: return result;
485: }
486:
487: public String toString() {
488: return getClassName();
489: }
490:
491: /**
492: * relies on a valid backing RWI model element, i.e. the together
493: * project is still valid (opened)
494: */
495: public ListOfModelClass getMyParents() {
496: ListOfString parentNames = SLListOfString.EMPTY_LIST;
497: RwiModel model = RwiModelAccess.getModel();
498:
499: Enumeration extended = orig.properties(RwiProperty.EXTENDS);
500: while (extended.hasMoreElements()) {
501: RwiProperty parentProperty = (RwiProperty) extended
502: .nextElement();
503: RwiPropertyMap subProperties = parentProperty
504: .getSubproperties();
505: RwiElement parentElement = model.findElement(subProperties
506: .getProperty(RwiProperty.REFERENCED_ELEMENT));
507: String parentName = parentElement
508: .getProperty(RwiProperty.FULL_NAME);
509: parentNames = parentNames.prepend(parentName);
510: }
511:
512: Enumeration implemented = orig
513: .properties(RwiProperty.IMPLEMENTS);
514: while (implemented.hasMoreElements()) {
515: RwiProperty parentProperty = (RwiProperty) implemented
516: .nextElement();
517: RwiPropertyMap subProperties = parentProperty
518: .getSubproperties();
519: RwiElement parentElement = model.findElement(subProperties
520: .getProperty(RwiProperty.REFERENCED_ELEMENT));
521: String parentName = parentElement
522: .getProperty(RwiProperty.FULL_NAME);
523: parentNames = parentNames.prepend(parentName);
524: }
525:
526: ListOfModelClass result = SLListOfModelClass.EMPTY_LIST;
527:
528: Iterator it = getAllClasses().iterator();
529: while (it.hasNext()) {
530: UMLModelClass modelClass = (UMLModelClass) (it.next());
531: IteratorOfString it2 = parentNames.iterator();
532: while (it2.hasNext()) {
533: if (it2.next().equals(modelClass.getFullClassName())) {
534: result = result.prepend(modelClass);
535: break;
536: }
537: }
538: }
539:
540: return result;
541: }
542:
543: /**
544: * Helper for getAllAssociations().
545: */
546: private static RwiMember getMemberForLink(
547: TogetherModelClass modelClass, RwiLink link) {
548: Enumeration rwiMemberEnum = modelClass.orig.members();
549: while (rwiMemberEnum.hasMoreElements()) {
550: RwiMember rwiMember = (RwiMember) rwiMemberEnum
551: .nextElement();
552: if (rwiMember.getUniqueName().indexOf(link.toString()) != -1) {
553: return rwiMember;
554: }
555: }
556:
557: return null;
558: }
559:
560: /**
561: * Helper for createUMLInfo().
562: */
563: private ListOfAssociation getAllAssociations(Services services) {
564: ListOfAssociation result = SLListOfAssociation.EMPTY_LIST;
565:
566: //get all classes
567: Set allClasses = getAllClasses();
568:
569: //build hash map for looking up classes by their name
570: Map /*String -> ModelClass*/classesByName = new HashMap();
571: Iterator it = allClasses.iterator();
572: while (it.hasNext()) {
573: TogetherModelClass modelClass = (TogetherModelClass) it
574: .next();
575: classesByName.put(modelClass.orig.toString(), modelClass);
576: }
577:
578: //iterate over all classes
579: SciModel model = SciModelAccess.getModel();
580: it = allClasses.iterator();
581: while (it.hasNext()) {
582: TogetherModelClass sourceClass = (TogetherModelClass) it
583: .next();
584:
585: //iterate over all links of this class
586: Enumeration linkEnum = sourceClass.orig.outgoingLinks();
587: while (linkEnum.hasMoreElements()) {
588: RwiLink link = (RwiLink) linkEnum.nextElement();
589:
590: //ignore links which are no associations
591: if (!link.getProperty(RwiProperty.SHAPE_TYPE).equals(
592: RwiShapeType.ASSOCIATION)) {
593: continue;
594: }
595:
596: //get target class
597: TogetherModelClass targetClass = (TogetherModelClass) classesByName
598: .get(link.getDestination().toString());
599: if (targetClass == null) {
600: continue;
601: }
602:
603: //get associated rwiMember in source class
604: RwiMember rwiMember = getMemberForLink(sourceClass,
605: link);
606: if (rwiMember == null) {
607: continue;
608: }
609:
610: //get multiplicities
611: String sourceMultString = model.findElement(
612: rwiMember.getUniqueName()).getTagList()
613: .getTagValue("clientCardinality");
614: Multiplicity sourceMult = Multiplicity.STANDARD;
615: if (sourceMultString != null) {
616: sourceMult = Multiplicity
617: .getMultiplicityFromString(sourceMultString);
618: }
619: String targetMultString = model.findElement(
620: rwiMember.getUniqueName()).getTagList()
621: .getTagValue("supplierCardinality");
622: Multiplicity targetMult = Multiplicity.STANDARD;
623: if (targetMultString != null) {
624: targetMult = Multiplicity
625: .getMultiplicityFromString(targetMultString);
626: }
627:
628: //get names
629: String assocName = model.findElement(
630: rwiMember.getUniqueName()).getTagList()
631: .getTagValue("label");
632: String sourceRoleName = getAssociationRole(rwiMember,
633: link, "clientRole");
634: String targetRoleName = getAssociationRole(rwiMember,
635: link, "supplierRole");
636:
637: //create association
638: AssociationEnd sourceEnd = new AssociationEnd(
639: sourceRoleName, sourceMult, sourceClass);
640: AssociationEnd targetEnd = new AssociationEnd(
641: targetRoleName, targetMult, targetClass);
642: Association assoc = new Association(services,
643: assocName, sourceEnd, targetEnd);
644: result = result.prepend(assoc);
645: }
646: }
647:
648: return result;
649: }
650:
651: /**
652: * relies on a valid backing RWI model element, i.e. the together
653: * project is still valid (opened)
654: */
655: public UMLInfo createUMLInfo(Services services) {
656: return new UMLInfo(services, getAllAssociations(services));
657: }
658:
659: //-------------------------------------------------------------------------
660: //deprecated
661: //-------------------------------------------------------------------------
662:
663: /** relies on a valid backing RWI / SCI model element, i.e. the together
664: * project is still valid (opened)
665: * @deprecated
666: */
667: public void getAssociations(HashMapOfClassifier classifiers) {
668:
669: SciModel model = SciModelAccess.getModel();
670: Enumeration linkEnum = orig.outgoingLinks();
671: RwiLink link;
672: Multiplicity sourceMult = null, targetMult = null;
673: String sourceRole = null, targetRole = null;
674: Enumeration rwiMemberEnum;
675: RwiMember rwiMember;
676: while (linkEnum.hasMoreElements()) {
677: link = (RwiLink) linkEnum.nextElement();
678: //filter out associations
679: if (link.getProperty(RwiProperty.SHAPE_TYPE).equals(
680: RwiShapeType.ASSOCIATION)) {
681: // get cardinality and client role
682: targetMult = null;
683: targetRole = null;
684: rwiMemberEnum = orig.members();
685: rwiMember = null;
686: while (rwiMemberEnum.hasMoreElements()) {
687: rwiMember = (RwiMember) rwiMemberEnum.nextElement();
688: if (rwiMember.getUniqueName().indexOf(
689: link.toString()) != -1) {
690: SciElement e = model.findElement(rwiMember
691: .getUniqueName());
692: String card = model.findElement(
693: rwiMember.getUniqueName()).getTagList()
694: .getTagValue("supplierCardinality");
695: targetMult = Multiplicity.STANDARD;
696: if (card != null)
697: targetMult = Multiplicity
698: .getMultiplicityFromString(card);
699:
700: targetRole = getAssociationRole(rwiMember,
701: link, "supplierRole");
702:
703: break;
704: }
705: }
706:
707: // associations are bi-directional. So we have to add the
708: // association also to the target classifier
709:
710: sourceMult = null;
711: sourceRole = null;
712:
713: String card = model.findElement(
714: rwiMember.getUniqueName()).getTagList()
715: .getTagValue("clientCardinality");
716: sourceMult = Multiplicity.STANDARD;
717: if (card != null)
718: sourceMult = Multiplicity
719: .getMultiplicityFromString(card);
720:
721: sourceRole = getAssociationRole(rwiMember, link,
722: "clientRole");
723:
724: UMLOCLClassifier sourceClassifier = classifiers
725: .getClassifier(orig.toString());
726: UMLOCLClassifier targetClassifier = classifiers
727: .getClassifier(link.getDestination().toString());
728: if (sourceClassifier != null
729: && targetClassifier != null) {
730: sourceClassifier.addAssociation(targetRole,
731: new UMLOCLTogetherAssociation(
732: sourceClassifier, sourceRole,
733: sourceMult, targetClassifier,
734: targetRole, targetMult));
735: targetClassifier.addAssociation(sourceRole,
736: new UMLOCLTogetherAssociation(
737: targetClassifier, targetRole,
738: targetMult, sourceClassifier,
739: sourceRole, sourceMult));
740:
741: }
742: }
743: }
744: }
745: }
|