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 : RoundTripOperationEventsSink.java
044: * Version : 1.2
045: * Description : Listener for operation change events.
046: * Author : Ashish
047: */
048: package org.netbeans.modules.uml.integration.ide;
049:
050: import java.util.Vector;
051:
052: import org.netbeans.modules.uml.integration.ide.events.ClassInfo;
053: import org.netbeans.modules.uml.integration.ide.events.MethodInfo;
054: import org.netbeans.modules.uml.integration.ide.events.MethodParameterInfo;
055: import org.netbeans.modules.uml.integration.ide.listeners.IOperationChangeListener;
056: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
057: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IClassifier;
058: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IOperation;
059: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IParameter;
060: import org.netbeans.modules.uml.core.roundtripframework.IChangeRequest;
061: import org.netbeans.modules.uml.core.roundtripframework.IMultipleParameterTypeChangeRequest;
062: import org.netbeans.modules.uml.core.roundtripframework.IParameterChangeRequest;
063: import org.netbeans.modules.uml.core.roundtripframework.IParameterTypeChangeRequest;
064: import org.netbeans.modules.uml.core.roundtripframework.IRoundTripOperationEventsSink;
065: import org.netbeans.modules.uml.core.support.umlsupport.IResultCell;
066: import org.netbeans.modules.uml.core.support.umlsupport.Log;
067:
068: //import org.netbeans.modules.uml.integration.netbeans.NBEventProcessor;
069:
070: /**
071: * Listens for changes to operations in the Describe model.
072: *
073: * Revision History
074: * No. Date Who What
075: * --- ---- --- ----
076: * 1 2002-04-23 Darshan Added file and class comments.
077: * 2 2002-04-25 Darshan Added support for IDE integrations to add
078: * secondary listeners to this.
079: * 3 2002-04-26 Darshan Removed diagnostic messages from second
080: * (post-change) event functions.
081: * 4 2002-05-03 Darshan Incorporated Sumitabh's changes to make the
082: * operation model-source event handler correctly
083: * handle return type and parameter changes.
084: * 5 2002-06-14 Darshan Reintroduced the ChangeUtils.say() call.
085: * 6 2002-06-19 Darshan Fixed operation change events not correctly
086: * processed for interfaces (bug 154).
087: * 7 2002-08-06 Mukta Added code to handle the
088: * IMultipleParameterTypeChangeRequest
089: *
090: * @author Ashish
091: * @version 1.0
092: */
093: public class RoundTripOperationEventsSink extends RoundTripSource
094: implements IRoundTripOperationEventsSink {
095:
096: public void onPreOperationChangeRequest(IChangeRequest newVal,
097: IResultCell cell) {
098: }
099:
100: public void onOperationChangeRequest(IChangeRequest newVal,
101: IResultCell cell) {
102: try {
103: // if(NBEventProcessor.isUpdatingModel() == false)
104: // {
105: ChangeUtils.say(newVal);
106: fireOperationChangeEvent(newVal, false);
107: // }
108: } catch (Exception e) {
109: Log.stackTrace(e);
110: }
111: }
112:
113: protected void fireOperationChangeEvent(IChangeRequest newVal,
114: boolean beforeChange) {
115: // Get change type
116: int changeType = newVal.getState();
117:
118: IElement eBefore = newVal.getBefore(), eAfter = newVal
119: .getAfter();
120:
121: if (eBefore instanceof IOperation) {
122: IOperation before = (IOperation) eBefore, after = (IOperation) eAfter;
123:
124: switch (changeType) {
125: case ChangeUtils.CT_CREATE: {
126: if (isValidEvent(after)) {
127: MethodInfo oper = new MethodInfo(null, after);
128: fireOperationAddedEvent(oper, beforeChange);
129:
130: if (!oper.isAccessor() && !oper.isMutator())
131: scheduleForNavigation(after);
132: }
133: break;
134: }
135: case ChangeUtils.CT_DELETE: {
136: if (isValidEvent(before)) {
137: MethodInfo clazz = new MethodInfo(null, before);
138: fireOperationDeletedEvent(clazz, beforeChange);
139: }
140: break;
141: }
142: case ChangeUtils.CT_MODIFY: {
143: if (isValidEvent(before) && isValidEvent(after)) {
144: MethodInfo oldC = new MethodInfo(null, before), newC = new MethodInfo(
145: null, after);
146: if (oldC.getContainingClass() == null
147: && newC.getContainingClass() != null)
148: oldC.setContainingClass(newC
149: .getContainingClass());
150:
151: if (newVal.getRequestDetailType() == ChangeUtils.RDT_MULTIPLE_PARAMETER_TYPE_MODIFIED) {
152: IMultipleParameterTypeChangeRequest req = (IMultipleParameterTypeChangeRequest) newVal;
153: IOperation impactedOperation = req
154: .getImpactedOperation();
155: oldC = new MethodInfo(null, impactedOperation);
156: newC = new MethodInfo(null, impactedOperation);
157: MethodParameterInfo[] paraminfo = oldC
158: .getParameters();
159: for (int i = 0; i < paraminfo.length; i++) {
160: if (paraminfo[i].getType().equals(
161: req.getNewTypeName()))
162: paraminfo[i].setType(req
163: .getOldTypeName());
164: }
165: oldC.setParameters(paraminfo);
166: }
167: Log.out("Firing change event for " + oldC.getName()
168: + " to " + newC.getName());
169: fireOperationChangedEvent(oldC, newC, beforeChange);
170: }
171: break;
172: }
173: }
174: } else if (eBefore instanceof IParameter) {
175: if (newVal instanceof IParameterChangeRequest) {
176: IParameterChangeRequest req = (IParameterChangeRequest) newVal;
177:
178: IOperation before = req.getBeforeOperation(), after = req
179: .getAfterOperation();
180:
181: if (!isValidEvent(before) || !isValidEvent(after))
182: return;
183:
184: IElement clazz = before.getOwner();
185: if (clazz == null)
186: clazz = after.getOwner();
187: IClassifier classEl = clazz instanceof IClassifier ? (IClassifier) clazz
188: : null;
189:
190: if (clazz == null || classEl == null) {
191: Log.out("E----- Can't find class owning operation");
192: // We can't proceed if we don't know what class to change.
193: return;
194: }
195: ClassInfo ci = null;
196:
197: try {
198: //ci = new ClassInfo(classEl);
199: ci = ClassInfo.getRefClassInfo(classEl, true);
200: } catch (Exception e) {
201: Log.stackTrace(e);
202: }
203:
204: MethodInfo oldM = new MethodInfo(ci, before);
205: MethodInfo newM = new MethodInfo(ci, after);
206:
207: fireOperationChangedEvent(oldM, newM, beforeChange);
208: } else {
209: IParameterTypeChangeRequest req = (IParameterTypeChangeRequest) newVal;
210: IParameter pm = req.getImpactedParameter();
211: IOperation before = (IOperation) pm.getOwner();
212: IOperation after = (IOperation) pm.getOwner();
213:
214: if (!isValidEvent(before) || !isValidEvent(after))
215: return;
216:
217: IElement clazz = before.getOwner();
218: if (clazz == null)
219: clazz = after.getOwner();
220: IClassifier classEl = clazz instanceof IClassifier ? (IClassifier) clazz
221: : null;
222:
223: if (clazz == null || classEl == null) {
224: Log.out("E----- Can't find class owning operation");
225: // We can't proceed if we don't know what class to change.
226: return;
227: }
228: ClassInfo ci = null;
229:
230: try {
231: //ci = new ClassInfo(classEl);
232: ci = ClassInfo.getRefClassInfo(classEl, true);
233: } catch (Exception e) {
234: Log.stackTrace(e);
235: }
236:
237: MethodInfo oldM = new MethodInfo(ci, before);
238: MethodInfo newM = new MethodInfo(ci, after);
239:
240: MethodParameterInfo[] bList = oldM.getParameters();
241: MethodParameterInfo parm = null;
242:
243: for (int i = 0; i < bList.length; i++) {
244: if (bList[i].getName().equals(pm.getName())) {
245: parm = bList[i];
246: parm.setType(req.getOldTypeName());
247: }
248: }
249: fireOperationChangedEvent(oldM, newM, beforeChange);
250:
251: }
252: } else {
253: Log.out("Unknown event object!");
254: }
255: }
256:
257: protected void fireOperationAddedEvent(final MethodInfo method,
258: final boolean before) {
259: if (!isValidEvent(method, method.getContainingClass()))
260: return;
261:
262: Log.out("Operation added (M->S): " + method);
263: for (int i = 0; i < changeListeners.size(); ++i) {
264: final IOperationChangeListener listener = (IOperationChangeListener) changeListeners
265: .elementAt(i);
266: RoundtripThread r = new RoundtripThread() {
267: public void work() {
268: setDefaultProject(method);
269: listener.operationAdded(method, before);
270: }
271: };
272: queue(r);
273: }
274: }
275:
276: protected void fireOperationDeletedEvent(final MethodInfo method,
277: final boolean before) {
278: if (!isValidEvent(method, method.getContainingClass()))
279: return;
280:
281: Log.out("Operation deleted (M->S): " + method);
282: for (int i = 0; i < changeListeners.size(); ++i) {
283: final IOperationChangeListener listener = (IOperationChangeListener) changeListeners
284: .elementAt(i);
285: RoundtripThread r = new RoundtripThread() {
286: public void work() {
287: setDefaultProject(method);
288: listener.operationDeleted(method, before);
289: }
290: };
291: queue(r);
292: }
293: }
294:
295: protected void fireOperationChangedEvent(final MethodInfo oldM,
296: final MethodInfo newM, final boolean before) {
297: Log
298: .out("Operation changed (M->S) from " + oldM + " to "
299: + newM);
300: for (int i = 0; i < changeListeners.size(); ++i) {
301: final IOperationChangeListener listener = (IOperationChangeListener) changeListeners
302: .elementAt(i);
303: RoundtripThread r = new RoundtripThread() {
304: public void work() {
305: setDefaultProject(newM);
306: listener.operationChanged(oldM, newM, before);
307: }
308: };
309: queue(r);
310: }
311: }
312:
313: public static void addOperationChangeListener(
314: IOperationChangeListener listener) {
315: if (listener != null && !changeListeners.contains(listener))
316: changeListeners.add(listener);
317: }
318:
319: public static void removeOperationChangeListener(
320: IOperationChangeListener listener) {
321: if (listener != null)
322: changeListeners.remove(listener);
323: }
324:
325: private static Vector changeListeners = new Vector();
326: }
|