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-2006 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: package org.netbeans.modules.debugger.jpda.ui.models;
043:
044: import com.sun.jdi.AbsentInformationException;
045: import java.beans.PropertyChangeEvent;
046: import java.beans.PropertyChangeListener;
047: import java.lang.ref.WeakReference;
048: import java.util.List;
049: import java.util.Vector;
050:
051: import org.netbeans.api.debugger.DebuggerEngine;
052: import org.netbeans.spi.debugger.ContextProvider;
053: import org.netbeans.api.debugger.Session;
054: import org.netbeans.api.debugger.jpda.CallStackFrame;
055: import org.netbeans.api.debugger.jpda.JPDADebugger;
056: import org.netbeans.spi.viewmodel.ModelEvent;
057: import org.netbeans.spi.viewmodel.NodeModel;
058: import org.netbeans.spi.viewmodel.TreeModel;
059: import org.netbeans.spi.viewmodel.ModelListener;
060: import org.netbeans.spi.viewmodel.UnknownTypeException;
061: import org.openide.util.NbBundle;
062:
063: /**
064: * @author Jan Jancura
065: */
066: public class CallStackNodeModel implements NodeModel {
067:
068: public static final String CALL_STACK = "org/netbeans/modules/debugger/resources/callStackView/NonCurrentFrame";
069: public static final String CURRENT_CALL_STACK = "org/netbeans/modules/debugger/resources/callStackView/CurrentFrame";
070:
071: private JPDADebugger debugger;
072: private Session session;
073: private Vector listeners = new Vector();
074:
075: public CallStackNodeModel(ContextProvider lookupProvider) {
076: debugger = lookupProvider.lookupFirst(null, JPDADebugger.class);
077: session = lookupProvider.lookupFirst(null, Session.class);
078: new Listener(this , debugger);
079: }
080:
081: public String getDisplayName(Object o) throws UnknownTypeException {
082: if (o == TreeModel.ROOT) {
083: return NbBundle.getBundle(CallStackNodeModel.class)
084: .getString("CTL_CallstackModel_Column_Name_Name");
085: } else if (o instanceof CallStackFrame) {
086: CallStackFrame sf = (CallStackFrame) o;
087: CallStackFrame ccsf = debugger.getCurrentCallStackFrame();
088: if ((ccsf != null) && (ccsf.equals(sf)))
089: return BoldVariablesTableModelFilterFirst.toHTML(
090: getCSFName(session, sf, false), true, false,
091: null);
092: return getCSFName(session, sf, false);
093: } else if ("No current thread" == o) {
094: return NbBundle.getMessage(CallStackNodeModel.class,
095: "NoCurrentThread");
096: } else if ("Thread is running" == o) {
097: return NbBundle.getMessage(CallStackNodeModel.class,
098: "ThreadIsRunning");
099: } else
100: throw new UnknownTypeException(o);
101: }
102:
103: public String getShortDescription(Object o)
104: throws UnknownTypeException {
105: if (o == TreeModel.ROOT) {
106: return NbBundle.getBundle(CallStackNodeModel.class)
107: .getString("CTL_CallstackModel_Column_Name_Desc");
108: } else if (o instanceof CallStackFrame) {
109: CallStackFrame sf = (CallStackFrame) o;
110: return getCSFName(session, sf, true);
111: } else if ("No current thread" == o) {
112: return NbBundle.getMessage(CallStackNodeModel.class,
113: "NoCurrentThread");
114: } else if ("Thread is running" == o) {
115: return NbBundle.getMessage(CallStackNodeModel.class,
116: "ThreadIsRunning");
117: } else
118: throw new UnknownTypeException(o);
119: }
120:
121: public String getIconBase(Object node) throws UnknownTypeException {
122: if (node instanceof String)
123: return null;
124: if (node instanceof CallStackFrame) {
125: CallStackFrame ccsf = debugger.getCurrentCallStackFrame();
126: if ((ccsf != null) && (ccsf.equals(node)))
127: return CURRENT_CALL_STACK;
128: return CALL_STACK;
129: }
130: throw new UnknownTypeException(node);
131: }
132:
133: /**
134: *
135: * @param l the listener to add
136: */
137: public void addModelListener(ModelListener l) {
138: listeners.add(l);
139: }
140:
141: /**
142: *
143: * @param l the listener to remove
144: */
145: public void removeModelListener(ModelListener l) {
146: listeners.remove(l);
147: }
148:
149: private void fireNodeChanged(Object node) {
150: Vector v = (Vector) listeners.clone();
151: int k = v.size();
152: if (k == 0)
153: return;
154: ModelEvent.NodeChanged nodeChangedEvent = new ModelEvent.NodeChanged(
155: this , node);
156: for (int i = 0; i < k; i++) {
157: ((ModelListener) v.get(i)).modelChanged(nodeChangedEvent);
158: }
159: }
160:
161: public static String getCSFName(Session s, CallStackFrame sf,
162: boolean l) {
163: String language = sf.getDefaultStratum();
164: int ln = sf.getLineNumber(language);
165: String fileName = l ? sf.getClassName() : BreakpointsNodeModel
166: .getShort(sf.getClassName());
167: if ("Java".equals(language))
168: fileName += "." + sf.getMethodName();
169: else
170: try {
171: fileName = sf.getSourcePath(language);
172: } catch (AbsentInformationException e) {
173: fileName += "." + sf.getMethodName();
174: }
175: if (ln < 0)
176: return fileName;
177: return fileName + ":" + ln;
178: }
179:
180: // innerclasses ............................................................
181:
182: /**
183: * Listens on DebuggerManager on PROP_CURRENT_ENGINE, and on
184: * currentTreeModel.
185: */
186: private static class Listener implements PropertyChangeListener {
187:
188: private WeakReference ref;
189: private JPDADebugger debugger;
190:
191: private Listener(CallStackNodeModel rm, JPDADebugger debugger) {
192: ref = new WeakReference(rm);
193: this .debugger = debugger;
194: debugger.addPropertyChangeListener(
195: debugger.PROP_CURRENT_CALL_STACK_FRAME, this );
196: }
197:
198: private CallStackNodeModel getModel() {
199: CallStackNodeModel rm = (CallStackNodeModel) ref.get();
200: if (rm == null) {
201: debugger.removePropertyChangeListener(
202: debugger.PROP_CURRENT_CALL_STACK_FRAME, this );
203: }
204: return rm;
205: }
206:
207: public void propertyChange(PropertyChangeEvent e) {
208: CallStackNodeModel rm = getModel();
209: if (rm == null)
210: return;
211: rm.fireNodeChanged(e.getOldValue());
212: rm.fireNodeChanged(e.getNewValue());
213: }
214: }
215: }
|