001: /* ====================================================================
002: * The JRefactory License, Version 1.0
003: *
004: * Copyright (c) 2001 JRefactory. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by the
021: * JRefactory (http://www.sourceforge.org/projects/jrefactory)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. The names "JRefactory" must not be used to endorse or promote
026: * products derived from this software without prior written
027: * permission. For written permission, please contact seguin@acm.org.
028: *
029: * 5. Products derived from this software may not be called "JRefactory",
030: * nor may "JRefactory" appear in their name, without prior written
031: * permission of Chris Seguin.
032: *
033: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036: * DISCLAIMED. IN NO EVENT SHALL THE CHRIS SEGUIN OR
037: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044: * SUCH DAMAGE.
045: * ====================================================================
046: *
047: * This software consists of voluntary contributions made by many
048: * individuals on behalf of JRefactory. For more information on
049: * JRefactory, please see
050: * <http://www.sourceforge.org/projects/jrefactory>.
051: */
052: package org.acm.seguin.uml;
053:
054: import java.util.Iterator;
055: import javax.swing.*;
056: import org.acm.seguin.ide.common.SourceBrowser;
057: import org.acm.seguin.ide.common.SourceBrowserAdapter;
058: import org.acm.seguin.summary.ParameterSummary;
059: import org.acm.seguin.summary.MethodSummary;
060: import org.acm.seguin.summary.PackageSummary;
061: import org.acm.seguin.summary.TypeSummary;
062: import org.acm.seguin.uml.refactor.AddChildClassListener;
063: import org.acm.seguin.uml.refactor.AddMoveClassListener;
064: import org.acm.seguin.uml.refactor.AddParentClassListener;
065: import org.acm.seguin.uml.refactor.AddRenameClassListener;
066: import org.acm.seguin.uml.refactor.DialogViewListener;
067: import org.acm.seguin.uml.refactor.ExtractInterfaceListener;
068: import org.acm.seguin.uml.refactor.MoveMethodListener;
069: import org.acm.seguin.uml.refactor.PushDownFieldListener;
070: import org.acm.seguin.uml.refactor.RenameFieldListener;
071: import org.acm.seguin.uml.refactor.RenameMethodListener;
072: import org.acm.seguin.uml.refactor.PushDownMethodListener;
073: import org.acm.seguin.uml.refactor.PushUpAbstractMethodListener;
074: import org.acm.seguin.uml.refactor.PushUpFieldListener;
075: import org.acm.seguin.uml.refactor.PushUpMethodListener;
076: import org.acm.seguin.uml.refactor.RemoveClassListener;
077: import org.acm.seguin.uml.refactor.RenameParameterListener;
078: import org.acm.seguin.uml.refactor.BatchRename;
079:
080: /**
081: * UMLPopupMenu
082: *
083: *@author Chris Seguin
084: *@created September 12, 2001
085: */
086: public class UMLPopupMenu {
087: // Instance Variables
088: private JPopupMenu popupMenu;
089: private JPanel activeComponent;
090: private UMLPackage current;
091:
092: /**
093: * Constructor for the UMLPopupMenu object
094: *
095: *@param top the package diagram
096: *@param init the specific panel
097: */
098: public UMLPopupMenu(UMLPackage top, JPanel init) {
099: // Set the variables
100: activeComponent = init;
101: current = top;
102:
103: popupMenu = createPopupMenu();
104: popupMenu.setInvoker(activeComponent);
105: }
106:
107: /**
108: * Get the popup menu
109: *
110: *@return the popup menu
111: */
112: public JPopupMenu getMenu() {
113: return popupMenu;
114: }
115:
116: /**
117: * Add in the metrics
118: *
119: *@param menu Description of Parameter
120: *@return the metrics
121: */
122: protected JMenuItem getMetricsMenu(JPopupMenu menu) {
123: // Add in metrics
124: JMenu metrics = new JMenu("Metrics");
125:
126: JMenuItem item = new JMenuItem("Project Metrics");
127: metrics.add(item);
128: ProjectMetricsListener projectML = new ProjectMetricsListener(
129: menu, item);
130: item.addMouseListener(projectML);
131: item.addActionListener(projectML);
132:
133: item = new JMenuItem("Package Metrics");
134: metrics.add(item);
135: PackageMetricsListener packageML = new PackageMetricsListener(
136: current, menu, item);
137: item.addMouseListener(packageML);
138: item.addActionListener(packageML);
139:
140: item = new JMenuItem("Class Metrics");
141: metrics.add(item);
142: TypeMetricsListener tml = new TypeMetricsListener(
143: activeComponent, menu, item);
144: item.addMouseListener(tml);
145: item.addActionListener(tml);
146:
147: if (activeComponent == null) {
148: // Do nothing
149: } else if (activeComponent instanceof UMLMethod) {
150: UMLMethod umlMethod = (UMLMethod) activeComponent;
151: item = new JMenuItem("Method Metrics");
152: metrics.add(item);
153: MethodMetricsListener listener = new MethodMetricsListener(
154: umlMethod.getSummary(), menu, item);
155: item.addMouseListener(listener);
156: item.addActionListener(listener);
157: }
158:
159: // Return the value
160: return metrics;
161: }
162:
163: /**
164: * Create the popup menu
165: *
166: *@return Description of the Returned Value
167: */
168: protected JPopupMenu createPopupMenu() {
169: JMenuItem item;
170: JPopupMenu menu = new JPopupMenu("UML Diagram");
171:
172: if (activeComponent == null) {
173: // Do nothing
174: } else if (activeComponent instanceof UMLField) {
175: UMLField field = (UMLField) activeComponent;
176:
177: if (field.isAssociation()) {
178: item = new JMenuItem("Convert to Attribute");
179: } else {
180: item = new JMenuItem("Convert to Association");
181: }
182: item.setEnabled(field.isConvertable());
183: menu.add(item);
184: item.addMouseListener(new PopupMenuListener(menu, item));
185: item.addActionListener(new ConvertAdapter(current, field));
186: menu.addSeparator();
187: }
188:
189: // Add refactorings
190: addRefactorings(menu);
191: menu.addSeparator();
192:
193: // Add metrics
194: item = getMetricsMenu(menu);
195: menu.add(item);
196:
197: // Add source link
198: if (SourceBrowser.get().canBrowseSource()) {
199: menu.addSeparator();
200: item = new JMenuItem("Show source");
201: SourceBrowserAdapter adapter = new SourceBrowserAdapter(
202: (ISourceful) activeComponent);
203: item.addActionListener(adapter);
204: menu.add(item);
205: }
206:
207: // Return the menu
208: return menu;
209: }
210:
211: /**
212: * Refactorings
213: *
214: *@param menu The feature to be added to the Refactorings attribute
215: */
216: protected void addRefactorings(JPopupMenu menu) {
217: addTypeRefactorings(menu);
218:
219: if (activeComponent == null) {
220: // Do nothing
221: } else if (activeComponent instanceof UMLMethod) {
222: addMethodRefactorings(menu);
223: } else if (activeComponent instanceof UMLField) {
224: addFieldRefactorings(menu);
225: }
226: }
227:
228: /**
229: * Gets the Type attribute of the UMLPopupMenu object
230: *
231: *@return The Type value
232: */
233: private UMLType getType() {
234: if (activeComponent instanceof UMLType) {
235: return (UMLType) activeComponent;
236: } else if (activeComponent instanceof UMLLine) {
237: return ((UMLLine) activeComponent).getParentType();
238: }
239: return null;
240: }
241:
242: /**
243: * Gets the Type attribute of the UMLPopupMenu object
244: *
245: *@return The Type value
246: */
247: private TypeSummary getTypeSummary() {
248: UMLType umlType = getType();
249: if (umlType == null) {
250: return null;
251: }
252:
253: return umlType.getSummary();
254: }
255:
256: /**
257: * Adds a feature to the FieldRefactorings attribute of the UMLPopupMenu
258: * object
259: *
260: *@param menu The feature to be added to the FieldRefactorings attribute
261: */
262: private void addFieldRefactorings(JPopupMenu menu) {
263: // Add in metrics
264: JMenu fieldRefactorings = new JMenu("Field Refactorings");
265: menu.add(fieldRefactorings);
266:
267: JMenuItem item = new JMenuItem("Rename");
268: fieldRefactorings.add(item);
269: item.setEnabled(true);
270: RenameFieldListener renameListener = new RenameFieldListener(
271: current, ((UMLField) activeComponent).getSummary(),
272: menu, item);
273: item.addMouseListener(renameListener);
274: item.addActionListener(renameListener);
275:
276: item = new JMenuItem("Push Up");
277: fieldRefactorings.add(item);
278: item.setEnabled(true);
279: PushUpFieldListener pushUpListener = new PushUpFieldListener(
280: current, getTypeSummary(), ((UMLField) activeComponent)
281: .getSummary(), menu, item);
282: item.addMouseListener(pushUpListener);
283: item.addActionListener(pushUpListener);
284:
285: item = new JMenuItem("Push Down");
286: fieldRefactorings.add(item);
287: item.setEnabled(true);
288: PushDownFieldListener pushDownListener = new PushDownFieldListener(
289: current, getTypeSummary(), ((UMLField) activeComponent)
290: .getSummary(), menu, item);
291: item.addMouseListener(pushDownListener);
292: item.addActionListener(pushDownListener);
293: }
294:
295: /**
296: * Adds a feature to the MethodRefactorings attribute of the UMLPopupMenu
297: * object
298: *
299: *@param menu The feature to be added to the MethodRefactorings attribute
300: */
301: private void addMethodRefactorings(JPopupMenu menu) {
302: MethodSummary methodSummary = ((UMLMethod) activeComponent)
303: .getSummary();
304:
305: // Add in metrics
306: JMenu methodRefactorings = new JMenu("Method Refactorings");
307: menu.add(methodRefactorings);
308:
309: JMenuItem item = new JMenuItem("Rename");
310: methodRefactorings.add(item);
311: item.setEnabled(true);
312: RenameMethodListener renameListener = new RenameMethodListener(
313: current, getTypeSummary(),
314: ((UMLMethod) activeComponent).getSummary(), menu, item);
315: item.addMouseListener(renameListener);
316: item.addActionListener(renameListener);
317:
318: item = new JMenuItem("Push Up");
319: methodRefactorings.add(item);
320: item.setEnabled(true);
321: PushUpMethodListener pushUpListener = new PushUpMethodListener(
322: current, ((UMLMethod) activeComponent).getSummary(),
323: menu, item);
324: item.addMouseListener(pushUpListener);
325: item.addActionListener(pushUpListener);
326:
327: item = new JMenuItem("Push Up (Abstract)");
328: methodRefactorings.add(item);
329: item.setEnabled(true);
330: PushUpAbstractMethodListener pushUpAbsListener = new PushUpAbstractMethodListener(
331: current, ((UMLMethod) activeComponent).getSummary(),
332: menu, item);
333: item.addMouseListener(pushUpAbsListener);
334: item.addActionListener(pushUpAbsListener);
335:
336: item = new JMenuItem("Push Down");
337: methodRefactorings.add(item);
338: item.setEnabled(true);
339: PushDownMethodListener pushDownListener = new PushDownMethodListener(
340: current, getTypeSummary(), methodSummary, menu, item);
341: item.addMouseListener(pushDownListener);
342: item.addActionListener(pushDownListener);
343:
344: item = new JMenuItem("Move Method");
345: methodRefactorings.add(item);
346:
347: item.setEnabled(methodSummary.getParameterCount() > 0);
348: MoveMethodListener moveListener = new MoveMethodListener(
349: current, getTypeSummary(), methodSummary, menu, item);
350: item.addMouseListener(moveListener);
351: item.addActionListener(moveListener);
352:
353: if (methodSummary.getParameterCount() == 0) {
354: item = new JMenuItem("Rename Parameters");
355: item.setEnabled(false);
356: methodRefactorings.add(item);
357: } else {
358: JMenu rename = new JMenu("Rename Parameter:");
359: methodRefactorings.add(rename);
360:
361: Iterator iter = methodSummary.getParameters();
362: while (iter.hasNext()) {
363: ParameterSummary next = (ParameterSummary) iter.next();
364: item = new JMenuItem(next.getName());
365: rename.add(item);
366:
367: RenameParameterListener rpl = new RenameParameterListener(
368: menu, item, current, next);
369: item.addMouseListener(rpl);
370: item.addActionListener(rpl);
371: }
372: }
373: }
374:
375: /**
376: * Adds a feature to the TypeRefactorings attribute of the UMLPopupMenu
377: * object
378: *
379: *@param menu The feature to be added to the TypeRefactorings attribute
380: */
381: private void addTypeRefactorings(JPopupMenu menu) {
382: TypeSummary[] typeArray = SelectedSummaryList.list(current,
383: getType());
384:
385: // Add in metrics
386: JMenu typeRefactorings = new JMenu("Type Refactorings");
387: menu.add(typeRefactorings);
388:
389: JMenuItem item = new JMenuItem("Rename Class");
390: typeRefactorings.add(item);
391: DialogViewListener rcl = new AddRenameClassListener(current,
392: getTypeSummary(), menu, item);
393: item.addMouseListener(rcl);
394: item.addActionListener(rcl);
395:
396: // Add in moving a class
397: item = new JMenuItem("Move Class To");
398: item.setEnabled(true);
399: typeRefactorings.add(item);
400: DialogViewListener ncl = new AddMoveClassListener(typeArray,
401: menu, item);
402: item.addMouseListener(ncl);
403: item.addActionListener(ncl);
404:
405: // Add in a parent class
406: item = new JMenuItem("Add Abstract Parent Class");
407: item.setEnabled(true);
408: typeRefactorings.add(item);
409: DialogViewListener aapl = new AddParentClassListener(current,
410: typeArray, menu, item);
411: item.addMouseListener(aapl);
412: item.addActionListener(aapl);
413:
414: // Add in a child class
415: item = new JMenuItem("Add Child Class");
416: typeRefactorings.add(item);
417: item.setEnabled(true);
418: DialogViewListener accl = new AddChildClassListener(current,
419: getTypeSummary(), menu, item);
420: item.addMouseListener(accl);
421: item.addActionListener(accl);
422:
423: // Remove a child class
424: item = new JMenuItem("Remove Class");
425: typeRefactorings.add(item);
426: item.setEnabled(true);
427: RemoveClassListener removeListener = new RemoveClassListener(
428: current, getTypeSummary(), menu, item);
429: item.addMouseListener(removeListener);
430: item.addActionListener(removeListener);
431:
432: // Extract Interface
433: item = new JMenuItem("Extract Interface");
434: typeRefactorings.add(item);
435: item.setEnabled(true);
436: DialogViewListener eil = new ExtractInterfaceListener(current,
437: typeArray, menu, item);
438: item.addMouseListener(eil);
439: item.addActionListener(eil);
440:
441: // Extract Interface
442: item = new JMenuItem(
443: "Rename Variables Using Hungarian Notation");
444: typeRefactorings.add(item);
445: item.setEnabled(true);
446: BatchRename brl = new BatchRename(menu, item, getTypeSummary());
447: item.addMouseListener(brl);
448: item.addActionListener(brl);
449: }
450: }
|