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: package org.netbeans.modules.php.dbgp.breakpoints;
043:
044: import java.util.Map;
045: import java.util.WeakHashMap;
046:
047: import org.netbeans.api.debugger.Breakpoint;
048: import org.netbeans.api.debugger.DebuggerManager;
049: import org.netbeans.modules.php.dbgp.DebugSession;
050: import org.netbeans.modules.php.dbgp.models.ViewModelSupport;
051: import org.netbeans.modules.php.dbgp.packets.Stack;
052: import org.netbeans.spi.debugger.ui.Constants;
053: import org.netbeans.spi.viewmodel.ModelEvent;
054: import org.netbeans.spi.viewmodel.NodeModel;
055: import org.netbeans.spi.viewmodel.TableModel;
056: import org.netbeans.spi.viewmodel.UnknownTypeException;
057: import org.openide.filesystems.FileObject;
058: import org.openide.util.NbBundle;
059:
060: /**
061: *
062: * @author ads
063: */
064: public class BreakpointModel extends ViewModelSupport implements
065: NodeModel, TableModel {
066:
067: public static final String BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/NonLineBreakpoint"; // NOI18N
068: public static final String LINE_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/Breakpoint"; // NOI18N
069: public static final String CURRENT_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/NonLineBreakpointHit"; // NOI18N
070: public static final String CURRENT_LINE_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/BreakpointHit"; // NOI18N
071: public static final String DISABLED_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/DisabledNonLineBreakpoint"; // NOI18N
072: public static final String DISABLED_LINE_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/DisabledBreakpoint"; // NOI18N
073: public static final String DISABLED_CURRENT_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/DisabledNonLineBreakpointHit"; // NOI18N
074: public static final String DISABLED_CURRENT_LINE_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/DisabledBreakpointHit"; // NOI18N
075: public static final String LINE_CONDITIONAL_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/ConditionalBreakpoint"; // NOI18N
076: public static final String CURRENT_LINE_CONDITIONAL_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/ConditionalBreakpointHit"; // NOI18N
077: public static final String DISABLED_LINE_CONDITIONAL_BREAKPOINT = "org/netbeans/modules/debugger/resources/breakpointsView/DisabledConditionalBreakpoint";// NOI18N
078:
079: private static final String METHOD = "TXT_Method"; // NOI18N
080:
081: private static final String PARENS = "()"; // NOI18N
082:
083: public BreakpointModel() {
084: myCurrentBreakpoints = new WeakHashMap<DebugSession, AbstractBreakpoint>();
085: }
086:
087: /* (non-Javadoc)
088: * @see org.netbeans.modules.php.dbgp.models.ViewModelSupport#clearModel()
089: */
090: @Override
091: public void clearModel() {
092: }
093:
094: /* (non-Javadoc)
095: * @see org.netbeans.spi.viewmodel.NodeModel#getDisplayName(java.lang.Object)
096: */
097: public String getDisplayName(Object node)
098: throws UnknownTypeException {
099: if (node instanceof LineBreakpoint) {
100: LineBreakpoint breakpoint = (LineBreakpoint) node;
101: FileObject fileObject = breakpoint.getLine().getLookup()
102: .lookup(FileObject.class);
103: return fileObject.getNameExt() + ":"
104: + (breakpoint.getLine().getLineNumber() + 1);
105: } else if (node instanceof FunctionBreakpoint) {
106: FunctionBreakpoint breakpoint = (FunctionBreakpoint) node;
107: StringBuilder builder = new StringBuilder(NbBundle
108: .getMessage(BreakpointModel.class, METHOD));
109: builder.append(" ");
110: builder.append(breakpoint.getFunction());
111: builder.append(PARENS);
112: return builder.toString();
113: }
114: throw new UnknownTypeException(node);
115: }
116:
117: /* (non-Javadoc)
118: * @see org.netbeans.spi.viewmodel.NodeModel#getIconBase(java.lang.Object)
119: */
120: public String getIconBase(Object node) throws UnknownTypeException {
121: synchronized (myCurrentBreakpoints) {
122: for (AbstractBreakpoint breakpoint : myCurrentBreakpoints
123: .values()) {
124: if (node.equals(breakpoint)) {
125: return getCurrentBreakpointIconBase(breakpoint);
126: }
127: }
128: }
129: if (node instanceof LineBreakpoint) {
130: LineBreakpoint breakpoint = (LineBreakpoint) node;
131: if (!breakpoint.isEnabled()) {
132: return DISABLED_LINE_BREAKPOINT;
133: }
134: /*Line line = Utils.getCurrentLine();
135: if(line != null &&
136: line.getLineNumber() == breakpoint.getLine().getLineNumber())
137: {
138: return CURRENT_LINE_BREAKPOINT;
139: }*/
140: return LINE_BREAKPOINT;
141: } else if (node instanceof AbstractBreakpoint) {
142: AbstractBreakpoint breakpoint = (AbstractBreakpoint) node;
143: if (!breakpoint.isEnabled()) {
144: return DISABLED_BREAKPOINT;
145: }
146: return BREAKPOINT;
147: }
148: throw new UnknownTypeException(node);
149: }
150:
151: /* (non-Javadoc)
152: * @see org.netbeans.spi.viewmodel.NodeModel#getShortDescription(java.lang.Object)
153: */
154: public String getShortDescription(Object node)
155: throws UnknownTypeException {
156: if (node instanceof LineBreakpoint) {
157: return ((LineBreakpoint) node).getLine().getDisplayName();
158: }
159:
160: throw new UnknownTypeException(node);
161: }
162:
163: /* (non-Javadoc)
164: * @see org.netbeans.spi.viewmodel.TableModel#getValueAt(java.lang.Object, java.lang.String)
165: */
166: public Object getValueAt(Object node, String columnID)
167: throws UnknownTypeException {
168: if (node instanceof AbstractBreakpoint) {
169: if (columnID.equals(Constants.BREAKPOINT_ENABLED_COLUMN_ID)) {
170: return ((AbstractBreakpoint) node).isEnabled();
171: }
172: assert false;
173: }
174:
175: throw new UnknownTypeException(node);
176: }
177:
178: public boolean isReadOnly(Object node, String columnID)
179: throws UnknownTypeException {
180: if (node instanceof AbstractBreakpoint) {
181: if (columnID.equals(Constants.BREAKPOINT_ENABLED_COLUMN_ID)) {
182: return false;
183: }
184: assert false;
185: }
186:
187: throw new UnknownTypeException(node);
188: }
189:
190: /* (non-Javadoc)
191: * @see org.netbeans.spi.viewmodel.TableModel#setValueAt(java.lang.Object, java.lang.String, java.lang.Object)
192: */
193: public void setValueAt(Object node, String columnID, Object value)
194: throws UnknownTypeException {
195: if (node instanceof AbstractBreakpoint) {
196: if (columnID.equals(Constants.BREAKPOINT_ENABLED_COLUMN_ID)) {
197: if (((Boolean) value).equals(Boolean.TRUE)) {
198: ((AbstractBreakpoint) node).enable();
199: } else {
200: ((AbstractBreakpoint) node).disable();
201: }
202: }
203: } else {
204: throw new UnknownTypeException(node);
205: }
206: }
207:
208: public void setCurrentStack(Stack stack, DebugSession session) {
209: if (stack == null) {
210: synchronized (myCurrentBreakpoints) {
211: AbstractBreakpoint breakpoint = myCurrentBreakpoints
212: .remove(session);
213: fireChangeEvent(new ModelEvent.NodeChanged(this ,
214: breakpoint));
215: }
216: return;
217: }
218: String currentCommand = stack.getCurrentCommandName();
219:
220: if (foundLineBreakpoint(stack.getLine() - 1, session)) {
221: return;
222: } else {
223: foundFunctionBreakpoint(currentCommand, session);
224: }
225: }
226:
227: private String getCurrentBreakpointIconBase(
228: AbstractBreakpoint breakpoint) {
229: if (breakpoint instanceof LineBreakpoint) {
230: return CURRENT_LINE_BREAKPOINT;
231: } else {
232: return CURRENT_BREAKPOINT;
233: }
234: }
235:
236: private boolean foundFunctionBreakpoint(String currentCommand,
237: DebugSession session) {
238: return foundBreakpoint(session, new FunctionBreakpointAcceptor(
239: currentCommand));
240: }
241:
242: private boolean foundLineBreakpoint(int line, DebugSession session) {
243: return foundBreakpoint(session,
244: new LineBreakpointAcceptor(line));
245: }
246:
247: private boolean foundBreakpoint(DebugSession session,
248: Acceptor acceptor) {
249: Breakpoint[] breakpoints = DebuggerManager.getDebuggerManager()
250: .getBreakpoints();
251: for (Breakpoint breakpoint : breakpoints) {
252: if (!(breakpoint instanceof AbstractBreakpoint)) {
253: continue;
254: }
255: if (!((AbstractBreakpoint) breakpoint)
256: .isSessionRelated(session)) {
257: continue;
258: }
259: if (acceptor.accept(breakpoint)) {
260: AbstractBreakpoint abpnt = (AbstractBreakpoint) breakpoint;
261: synchronized (myCurrentBreakpoints) {
262: AbstractBreakpoint bpnt = myCurrentBreakpoints
263: .get(session);
264: myCurrentBreakpoints.put(session, abpnt);
265: fireChangeEvents(new ModelEvent[] {
266: new ModelEvent.NodeChanged(this , bpnt),
267: new ModelEvent.NodeChanged(this , abpnt) });
268: }
269: return true;
270: }
271: }
272: return false;
273: }
274:
275: private interface Acceptor {
276: boolean accept(Breakpoint breakpoint);
277: }
278:
279: private class LineBreakpointAcceptor implements Acceptor {
280:
281: LineBreakpointAcceptor(int lineNumber) {
282: myLine = lineNumber;
283: }
284:
285: public boolean accept(Breakpoint breakpoint) {
286: if (!(breakpoint instanceof LineBreakpoint)) {
287: return false;
288: }
289: LineBreakpoint lineBreakpoint = (LineBreakpoint) breakpoint;
290: return myLine == lineBreakpoint.getLine().getLineNumber();
291: }
292:
293: private int myLine;
294: }
295:
296: private class FunctionBreakpointAcceptor implements Acceptor {
297: FunctionBreakpointAcceptor(String function) {
298: myFunction = function;
299: }
300:
301: public boolean accept(Breakpoint breakpoint) {
302: if (!(breakpoint instanceof FunctionBreakpoint)) {
303: return false;
304: }
305: String function = ((FunctionBreakpoint) breakpoint)
306: .getFunction();
307: // TODO : need more accurate implementation for class methods f.e.
308:
309: return function == null ? false : function
310: .equals(myFunction);
311: }
312:
313: private String myFunction;
314:
315: }
316:
317: private Map<DebugSession, AbstractBreakpoint> myCurrentBreakpoints;
318:
319: }
|