001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: /*
043: * File : RoundTripRelationEventsSink.java
044: * Version : 1.2
045: * Description : Listener for Describe relationship change events
046: * Authors : Ashish
047: */
048: package org.netbeans.modules.uml.integration.ide;
049:
050: import org.netbeans.modules.uml.integration.ide.events.ClassInfo;
051: import org.netbeans.modules.uml.integration.ide.events.MemberInfo;
052: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
053: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAssociationEnd;
054: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IClassifier;
055: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IInterface;
056: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.INavigableEnd;
057: import org.netbeans.modules.uml.core.roundtripframework.IChangeRequest;
058: import org.netbeans.modules.uml.core.roundtripframework.IGeneralizationChangeRequest;
059: import org.netbeans.modules.uml.core.roundtripframework.IImplementationChangeRequest;
060: import org.netbeans.modules.uml.core.roundtripframework.IRoundTripRelationEventsSink;
061: import org.netbeans.modules.uml.core.support.umlsupport.IResultCell;
062: import org.netbeans.modules.uml.core.support.umlsupport.Log;
063:
064: /**
065: * Listens for relationship change events on the Describe model. It extends
066: * from the class events sink because it fires class change events.
067: *
068: * Revision History
069: * No. Date Who What
070: * --- ---- --- ----
071: * 1 2002-04-23 Darshan Added file and class comments.
072: * 2 2002-05-30 Darshan Added support for generalization and
073: * implementation change events.
074: * 3 2002-06-05 Darshan Modified to allow handling of generalizations
075: * between two interfaces.
076: * 4 2002-06-18 Sumitabh Modified to handle relationship create events.
077: * 5 2002-06-19 Darshan Included support for relationship delete events.
078: * 6 2002-06-26 Darshan Incorporated Sumitabh'schanges to handle
079: * association moves.
080: *
081: * @author Ashish
082: * @version 1.2
083: */
084: public class RoundTripRelationEventsSink extends
085: RoundTripClassEventsSink implements
086: IRoundTripRelationEventsSink {
087:
088: private RoundTripAttributeEventsSink attrSink = new RoundTripAttributeEventsSink();
089:
090: public RoundTripRelationEventsSink() {
091: }
092:
093: public void onPreRelationChangeRequest(IChangeRequest newVal,
094: IResultCell cell) {
095: }
096:
097: public void onRelationChangeRequest(IChangeRequest newVal,
098: IResultCell cell) {
099: Log.out("onRelationChangeRequest called");
100:
101: int type = newVal.getRequestDetailType();
102:
103: Log.out("Got request detail type " + type);
104: if (!isValidEventType(type)) {
105: Log.out("Request detail type " + type
106: + " is blocked, abandoning");
107: return;
108: }
109:
110: if (type == ChangeUtils.RDT_RELATION_CREATED) {
111: if (newVal instanceof IGeneralizationChangeRequest)
112: createGeneralization(newVal, false);
113: else if (newVal instanceof IImplementationChangeRequest)
114: createImplementation(newVal, false);
115: } else if (type == ChangeUtils.RDT_ASSOCIATION_END_MODIFIED) {
116: Log.out("Handling the association move event");
117: handleAssociationMove(newVal, false);
118: } else {
119: if (newVal instanceof IGeneralizationChangeRequest)
120: handleGeneralization(newVal, false);
121: else if (newVal instanceof IImplementationChangeRequest)
122: handleImplementation(newVal, false);
123: }
124: }
125:
126: protected void handleAssociationMove(IChangeRequest newVal,
127: boolean before) {
128: IElement bef = newVal.getBefore();
129: IElement aft = newVal.getAfter();
130: IClassifier befCl = null;
131: IClassifier aftCl = null;
132: INavigableEnd befAttr = null;
133: INavigableEnd aftAttr = null;
134:
135: if (bef instanceof IAssociationEnd) {
136: IAssociationEnd befEnd = (IAssociationEnd) bef;
137: befCl = befEnd.getParticipant();
138: befAttr = (INavigableEnd) befEnd.getOtherEnd2();
139: }
140: if (aft instanceof IAssociationEnd) {
141: IAssociationEnd aftEnd = (IAssociationEnd) aft;
142: aftCl = aftEnd.getParticipant();
143: aftAttr = (INavigableEnd) aftEnd.getOtherEnd2();
144: }
145:
146: if (!isValidEvent(befCl) || !isValidEvent(befAttr)
147: || !isValidEvent(aftCl) || !isValidEvent(aftAttr))
148: return;
149:
150: ClassInfo beforeClass = new ClassInfo(befCl);
151: //ClassInfo afterClass = new ClassInfo(aftCl);
152:
153: MemberInfo beforeMember = new MemberInfo(beforeClass, aftAttr);
154: MemberInfo afterMember = new MemberInfo(aftAttr);
155:
156: attrSink.fireAttributeDeletedEvent(beforeMember, before);
157: attrSink.fireAttributeAddedEvent(afterMember, before);
158: }
159:
160: protected void handleGeneralization(IChangeRequest req,
161: boolean before) {
162: int type = req.getRequestDetailType();
163:
164: IGeneralizationChangeRequest gcr = (IGeneralizationChangeRequest) req;
165: IClassifier oldG = gcr.getBeforeGeneralizing();
166: IClassifier newG = gcr.getAfterGeneralizing();
167: IClassifier oldS = gcr.getBeforeSpecializing();
168: IClassifier newS = gcr.getAfterSpecializing();
169:
170: if (newS == null || oldS == null)
171: return;
172:
173: if (!isValidEvent(oldG) || !isValidEvent(newG)
174: || !isValidEvent(oldS) || !isValidEvent(newS))
175: return;
176: if (oldG instanceof IInterface && oldS instanceof IInterface) {
177: handleImplementation(req, before);
178: return;
179: }
180:
181: ClassInfo newC = new ClassInfo(newS);
182:
183: boolean oldNewSame = oldS.getXMIID().equals(newS.getXMIID());
184:
185: if (oldNewSame && type == ChangeUtils.RDT_RELATION_DELETED) {
186: Log.out("Deleting generalization!");
187: newC.setExtendedClass(null, null);
188: }
189:
190: // Passing newC as both old and new parameters is fully intentional -
191: // the IDE integration should/will only look at the qualified name from
192: // the old element, and then change everything in the source code to
193: // resemble the new element. Since this is a generalization change, the
194: // qualified name will be the same for both old and new elements and
195: // we can use the same object for both. QED.
196: fireClassChangedEvent(newC, newC, before);
197:
198: if (!oldNewSame) {
199: // The subclass was changed
200: ClassInfo oldC = new ClassInfo(oldS);
201: fireClassChangedEvent(oldC, oldC, before);
202: }
203: }
204:
205: protected void createGeneralization(IChangeRequest req,
206: boolean before) {
207: IGeneralizationChangeRequest gcr = (IGeneralizationChangeRequest) req;
208: IClassifier newG = gcr.getAfterGeneralizing();
209: IClassifier newS = gcr.getAfterSpecializing();
210:
211: if (newS == null || newG == null)
212: return;
213:
214: if (!isValidEvent(newG) || !isValidEvent(newS))
215: return;
216:
217: Log.out("New superclass");
218: ChangeUtils.sayElement(newG);
219: Log.out("New subclass");
220: ChangeUtils.sayElement(newS);
221:
222: ClassInfo newC = new ClassInfo(newS);
223:
224: // Passing newC as both old and new parameters is fully intentional -
225: // the IDE integration should/will only look at the qualified name from
226: // the old element, and then change everything in the source code to
227: // resemble the new element. Since this is a generalization change, the
228: // qualified name will be the same for both old and new elements and
229: // we can use the same object for both. QED.
230: fireClassChangedEvent(newC, newC, before);
231:
232: }
233:
234: protected void handleImplementation(IChangeRequest req,
235: boolean before) {
236: int type = req.getRequestDetailType();
237: IClassifier beforeC = null, afterC = null, beforeI = null, afterI = null;
238:
239: if (req instanceof IGeneralizationChangeRequest) {
240: IGeneralizationChangeRequest gcr = (IGeneralizationChangeRequest) req;
241: beforeI = gcr.getBeforeGeneralizing();
242: afterI = gcr.getAfterGeneralizing();
243: beforeC = gcr.getBeforeSpecializing();
244: afterC = gcr.getAfterSpecializing();
245: } else {
246: IImplementationChangeRequest icr = (IImplementationChangeRequest) req;
247: beforeC = icr.getBeforeImplementing();
248: afterC = icr.getAfterImplementing();
249: beforeI = icr.getBeforeInterface();
250: afterI = icr.getAfterInterface();
251: }
252:
253: if (beforeC == null || afterC == null || beforeI == null
254: || afterI == null)
255: return;
256:
257: if (!isValidEvent(beforeC) || !isValidEvent(afterC)
258: || !isValidEvent(beforeI) || !isValidEvent(afterI))
259: return;
260:
261: String oldInterface = JavaClassUtils
262: .getFullyQualifiedName(beforeI), newInterface = JavaClassUtils
263: .getFullyQualifiedName(afterI);
264:
265: if (beforeC.getXMIID().equals(afterC.getXMIID())) {
266: // The implemented interface has been changed
267: ClassInfo c = new ClassInfo(afterC);
268: c.removeInterface(oldInterface);
269: c.addInterface(newInterface);
270:
271: if (type == ChangeUtils.RDT_RELATION_DELETED)
272: c.removeInterface(newInterface);
273:
274: fireClassChangedEvent(c, c, before);
275: } else if (type != ChangeUtils.RDT_RELATION_DELETED) {
276: // The class that implements the interface has been changed.
277: ClassInfo oldC = new ClassInfo(beforeC), newC = new ClassInfo(
278: afterC);
279: oldC.removeInterface(oldInterface);
280: newC.addInterface(newInterface);
281: fireClassChangedEvent(oldC, oldC, before);
282: fireClassChangedEvent(newC, newC, before);
283: }
284: }
285:
286: protected void createImplementation(IChangeRequest req,
287: boolean before) {
288: IClassifier afterC = null, afterI = null;
289:
290: IImplementationChangeRequest icr = (IImplementationChangeRequest) req;
291: afterC = icr.getAfterImplementing();
292: afterI = icr.getAfterInterface();
293:
294: if (afterC == null || afterI == null)
295: return;
296:
297: if (!isValidEvent(afterC) || !isValidEvent(afterI))
298: return;
299:
300: String newInterface = JavaClassUtils
301: .getFullyQualifiedName(afterI);
302:
303: ClassInfo c = new ClassInfo(afterC);
304: c.addInterface(newInterface);
305:
306: fireClassChangedEvent(c, c, before);
307: }
308: }
|