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 : SourceNavigable.java
044: * Version : 1.0
045: * Description : Base class for classes that can generate source navigation
046: * events.
047: * Author : Darshan
048: */
049: package org.netbeans.modules.uml.integration.ide;
050:
051: import javax.swing.SwingUtilities;
052:
053: import org.netbeans.modules.uml.integration.ide.events.ClassInfo;
054: import org.netbeans.modules.uml.integration.ide.events.MemberInfo;
055: import org.netbeans.modules.uml.integration.ide.events.MethodInfo;
056: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
057: import org.netbeans.modules.uml.core.metamodel.dynamics.ILifeline;
058: import org.netbeans.modules.uml.core.metamodel.dynamics.IMessage;
059: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAssociation;
060: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAssociationEnd;
061: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IAttribute;
062: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IClassifier;
063: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IGeneralization;
064: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IImplementation;
065: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.INavigableEnd;
066: import org.netbeans.modules.uml.core.metamodel.infrastructure.coreinfrastructure.IOperation;
067: import org.netbeans.modules.uml.core.metamodel.structure.IProject;
068: import org.netbeans.modules.uml.core.support.umlsupport.Log;
069: import org.netbeans.modules.uml.core.support.umlutils.ETList;
070:
071: //import org.netbeans.modules.uml.ui.support.presentationnavigation.SourceNavigator;
072:
073: /**
074: * A convenience base class for classes that generate source navigation
075: * events.
076: *
077: * Revision History
078: * No. Date Who What
079: * --- ---- --- ----
080: * 1 2002-05-22 Darshan Created.
081: * 2 2002-05-23 Darshan Moved source navigation calls into invokeLater
082: * threads, which should hopefully kill the hang
083: * when navigating.
084: * 3 2002-05-27 Darshan Fixed NPE when orphan element is passed to
085: * source navigator.
086: * 4 2002-06-05 Darshan Incorporated Sumitabh's code to navigate to
087: * the source for generalizations, implementations
088: * and associations.
089: * 5 2002-06-17 Darshan Removed annoying logging statements.
090: * 6 2002-06-18 Darshan Added code to navigate to the classifier for a
091: * lifeline.
092: * 7 2002-06-20 Darshan Added navigation to the operation for sequence
093: * diagram messages (fix for bug 145).
094: *
095: * @author Darshan
096: */
097: abstract public class SourceNavigable implements ISourceNavigable {
098: protected SourceNavigator navigator;
099: private int lineNoOffset = 0;
100:
101: public void setSourceNavigator(SourceNavigator nav) {
102: navigator = nav;
103: }
104:
105: public SourceNavigator getSourceNavigator() {
106: return navigator;
107: }
108:
109: protected void fireNavigateEvent(IElement target) {
110: try {
111: if (UMLSupport.navigateToSource)
112: doFireNavigateEvent(target);
113: } catch (Throwable t) {
114: Log.stackTrace(t);
115: }
116: }
117:
118: protected void fireNavigateMethod(final MethodInfo minf) {
119: SwingUtilities.invokeLater(new Runnable() {
120: public void run() {
121: if (minf != null) {
122: String fileName = minf.getFilename();
123: String projName = null;
124: IProject proj = minf.getProject();
125: if (proj != null) {
126: projName = proj.getName();
127: }
128: UMLSupport.setProjectForPath(fileName, projName);
129: navigator.navigateTo(minf);
130: }
131: }
132: });
133: }
134:
135: protected void fireNavigateAttribute(final MemberInfo minf) {
136: SwingUtilities.invokeLater(new Runnable() {
137: public void run() {
138: if (minf != null) {
139: String fileName = minf.getFilename();
140: String projName = null;
141: IProject proj = minf.getProject();
142: if (proj != null) {
143: projName = proj.getName();
144: }
145: UMLSupport.setProjectForPath(fileName, projName);
146: navigator.navigateTo(minf);
147: }
148: }
149: });
150: }
151:
152: protected void fireNavigateClass(final ClassInfo cl) {
153: SwingUtilities.invokeLater(new Runnable() {
154: public void run() {
155: if (cl != null) {
156: String fileName = cl.getFilename();
157: String projName = null;
158: IProject proj = cl.getProject();
159: if (proj != null) {
160: projName = proj.getName();
161: }
162: UMLSupport.setProjectForPath(fileName, projName);
163: navigator.navigateTo(cl);
164: }
165: }
166: });
167: }
168:
169: /**
170: * Fires a source navigation event with the given target element.
171: * @param target The element to be navigated to in the source code.
172: */
173: protected void doFireNavigateEvent(IElement target) {
174: if (navigator == null || target == null) {
175: return;
176: }
177:
178: // It's a good idea to look for the more exotic elements first, since
179: // they typically derive from the basic IClassifier.
180: if (target instanceof IOperation) {
181: IOperation op = (IOperation) target;
182: final MethodInfo minf = new MethodInfo(null, op);
183: minf.setLineNo(lineNoOffset);
184: if (minf.getContainingClass() != null)
185: fireNavigateMethod(minf);
186: lineNoOffset = 0;
187:
188: } else if (target instanceof IAttribute) {
189: IAttribute attr = (IAttribute) target;
190: final MemberInfo minf = new MemberInfo(attr);
191: if (minf.getContainingClass() != null)
192: fireNavigateAttribute(minf);
193: } else if (target instanceof IGeneralization) {
194: IGeneralization gen = (IGeneralization) target;
195: IClassifier clazz = gen.getSpecific();
196: final ClassInfo cl = new ClassInfo(clazz);
197: fireNavigateClass(cl);
198: } else if (target instanceof IImplementation) {
199: IImplementation imp = (IImplementation) target;
200: IClassifier clazz = imp.getImplementingClassifier();
201: final ClassInfo cl = new ClassInfo(clazz);
202: fireNavigateClass(cl);
203: } else if (target instanceof IAssociation) {
204: // General association handling code also takes care of compositions
205: // and aggregations.
206: IAssociation assoc = (IAssociation) target;
207: ETList<IAssociationEnd> ends = assoc.getEnds();
208: if (ends.getCount() > 0) {
209: for (int j = 0; j < ends.getCount(); j++) {
210: IAssociationEnd end = ends.item(j);
211: if (end.getIsNavigable()) {
212: INavigableEnd nEnd = (INavigableEnd) end;
213: final MemberInfo minf = new MemberInfo(nEnd);
214: fireNavigateAttribute(minf);
215: // Don't worry about navigating to other ends - only
216: // one line can be hightlighted anyway
217: break;
218: }
219: }
220: }
221: } else if (target instanceof ILifeline) {
222: ILifeline life = (ILifeline) target;
223: IClassifier clazz = life.getRepresentingClassifier();
224: if (clazz != null) {
225: final ClassInfo cl = new ClassInfo(clazz);
226: fireNavigateClass(cl);
227: }
228: } else if (target instanceof IMessage) {
229:
230: IMessage mess = (IMessage) target;
231: IOperation op = null;
232: IElement owner = mess.getInteraction().getOwner();
233: if (owner instanceof IOperation) {
234: op = (IOperation) mess.getInteraction().getOwner();
235: lineNoOffset = target.getLineNumber() - 1;
236: }
237: if (op != null)
238: doFireNavigateEvent(op);
239: } else if (target instanceof IClassifier) {
240: // Don't move the IClassifier check up, since it tends to swallow
241: // other elements.
242: IClassifier clazz = (IClassifier) target;
243: if (clazz.getName().equals(
244: Preferences.getDefaultElementName()))
245: return;
246: final ClassInfo cl = ClassInfo.getRefClassInfo(clazz, true);
247: fireNavigateClass(cl);
248: }
249: }
250: }
|