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: package org.netbeans.modules.php.dbgp.breakpoints;
042:
043: import java.lang.reflect.InvocationTargetException;
044:
045: import javax.swing.JEditorPane;
046: import javax.swing.SwingUtilities;
047: import javax.swing.text.Caret;
048: import javax.swing.text.StyledDocument;
049:
050: import org.netbeans.api.debugger.Breakpoint;
051: import org.netbeans.api.debugger.DebuggerManager;
052: import org.netbeans.modules.php.dbgp.DebugSession;
053: import org.netbeans.modules.php.dbgp.api.SessionId;
054: import org.netbeans.modules.php.dbgp.breakpoints.FunctionBreakpoint.Type;
055: import org.netbeans.modules.php.dbgp.packets.BrkpntCommandBuilder;
056: import org.netbeans.modules.php.dbgp.packets.BrkpntRemoveCommand;
057: import org.netbeans.modules.php.dbgp.packets.BrkpntSetCommand;
058: import org.netbeans.modules.php.dbgp.packets.BrkpntSetCommand.State;
059: import org.netbeans.modules.php.lexer.PhpTokenId;
060: import org.openide.cookies.EditorCookie;
061: import org.openide.cookies.LineCookie;
062: import org.openide.filesystems.FileObject;
063: import org.openide.loaders.DataObject;
064: import org.openide.nodes.Node;
065: import org.openide.text.Line;
066: import org.openide.text.NbDocument;
067: import org.openide.windows.TopComponent;
068:
069: /**
070: * @author ads
071: *
072: */
073: public class Utils {
074:
075: private Utils() {
076: // avoid inst-ion
077: }
078:
079: public static Line getCurrentLine() {
080: if (!SwingUtilities.isEventDispatchThread()) {
081: return getCurrentLineInAwt();
082: }
083:
084: Node node = getCurrentNode();
085: FileObject fileObject = getCurrentFileObject(node);
086:
087: if (!isPhpFile(fileObject)) {
088: return null;
089: }
090:
091: LineCookie lineCookie = node.getCookie(LineCookie.class);
092:
093: if (lineCookie == null) {
094: return null;
095: }
096:
097: return getLine(lineCookie, node.getCookie(EditorCookie.class));
098: }
099:
100: public static BrkpntSetCommand getCommand(DebugSession session,
101: SessionId id, AbstractBreakpoint breakpoint) {
102: if (!breakpoint.isSessionRelated(session)) {
103: return null;
104: }
105:
106: BrkpntSetCommand command = null;
107: if (breakpoint instanceof LineBreakpoint) {
108: LineBreakpoint lineBreakpoint = (LineBreakpoint) breakpoint;
109: command = BrkpntCommandBuilder.buildLineBreakpoint(id,
110: session.getTransactionId(), lineBreakpoint);
111:
112: } else if (breakpoint instanceof FunctionBreakpoint) {
113: FunctionBreakpoint functionBreakpoint = (FunctionBreakpoint) breakpoint;
114: Type type = functionBreakpoint.getType();
115: if (type == Type.CALL) {
116: command = BrkpntCommandBuilder.buildCallBreakpoint(
117: session.getTransactionId(), functionBreakpoint);
118: } else if (type == Type.RETURN) {
119: command = BrkpntCommandBuilder.buildReturnBreakpoint(
120: session.getTransactionId(), functionBreakpoint);
121: } else {
122: assert false;
123: }
124: }
125:
126: if (!breakpoint.isEnabled()) {
127: command.setState(State.DISABLED);
128: }
129:
130: return command;
131: }
132:
133: public static AbstractBreakpoint getBreakpoint(String id) {
134: Breakpoint[] breakpoints = DebuggerManager.getDebuggerManager()
135: .getBreakpoints();
136: for (Breakpoint breakpoint : breakpoints) {
137: if (!(breakpoint instanceof AbstractBreakpoint)) {
138: continue;
139: }
140: AbstractBreakpoint bkpnt = (AbstractBreakpoint) breakpoint;
141: String bkpntId = bkpnt.getBreakpointId();
142: if (id.equals(bkpntId)) {
143: return bkpnt;
144: }
145: }
146: return null;
147: }
148:
149: public static void cleanBreakpoint(DebugSession session,
150: String breakpointId) {
151: BrkpntRemoveCommand removeCommand = new BrkpntRemoveCommand(
152: session.getTransactionId(), breakpointId);
153: session.sendCommandLater(removeCommand);
154: }
155:
156: public static void log(Throwable exception) {
157: exception.printStackTrace();
158: }
159:
160: public static void log(InvocationTargetException exception) {
161: log(exception.getCause());
162: }
163:
164: private static Line getCurrentLineInAwt() {
165: final Line[] lines = new Line[1];
166: try {
167: SwingUtilities.invokeAndWait(new Runnable() {
168: public void run() {
169: Line line = getCurrentLine();
170: lines[0] = line;
171: }
172: });
173: } catch (InterruptedException e) {
174: // awt thread should not be interrupted
175: assert false;
176: } catch (InvocationTargetException e) {
177: log(e);
178: }
179: return lines[0];
180: }
181:
182: private static Line getLine(LineCookie lineCookie,
183: EditorCookie editorCookie) {
184: if (editorCookie == null) {
185: return null;
186: }
187:
188: JEditorPane editorPane = getEditorPane(editorCookie);
189:
190: if (editorPane == null) {
191: return null;
192: }
193:
194: StyledDocument document = editorCookie.getDocument();
195: if (document == null) {
196: return null;
197: }
198:
199: Caret caret = editorPane.getCaret();
200:
201: if (caret == null) {
202: return null;
203: }
204:
205: int lineNumber = NbDocument.findLineNumber(document, caret
206: .getDot());
207:
208: try {
209: Line.Set lineSet = lineCookie.getLineSet();
210: assert lineSet != null;
211:
212: return lineSet.getCurrent(lineNumber);
213: } catch (IndexOutOfBoundsException ex) {
214: return null;
215: }
216: }
217:
218: public static FileObject getCurrentFileObject(Node node) {
219: if (node == null) {
220: return null;
221: }
222: FileObject fileObject = node.getLookup().lookup(
223: FileObject.class);
224:
225: if (fileObject == null) {
226: DataObject dobj = node.getLookup().lookup(DataObject.class);
227:
228: if (dobj != null) {
229: fileObject = dobj.getPrimaryFile();
230: }
231: }
232: return fileObject;
233: }
234:
235: public static Node getCurrentNode() {
236: Node[] nodes = TopComponent.getRegistry().getCurrentNodes();
237: if (nodes == null || nodes.length != 1) {
238: return null;
239: }
240: return nodes[0];
241: }
242:
243: public static JEditorPane getEditorPane(
244: final EditorCookie editorCookie) {
245: assert SwingUtilities.isEventDispatchThread();
246: JEditorPane[] panes = editorCookie.getOpenedPanes();
247: if (panes == null || panes.length == 0) {
248: return null;
249: }
250: return panes[0];
251: }
252:
253: public static boolean isPhpFile(FileObject fileObject) {
254: if (fileObject == null) {
255: return false;
256: } else {
257: String mimeType = fileObject.getMIMEType();
258: return PhpTokenId.MIME_TYPE.equals(mimeType);
259: }
260: }
261:
262: /**
263: * NB : <code>line</code> is 1-based debugger DBGP line.
264: * It differs from editor line !
265: * @param line 1-based line in file
266: * @param remoteFileName remote file name
267: * @param id current debugger session id
268: * @return
269: */
270: public static Line getLine(int line, String remoteFileName,
271: SessionId id) {
272: DataObject dataObject = id
273: .getDataObjectByRemote(remoteFileName);
274: if (dataObject == null) {
275: return null;
276: }
277:
278: LineCookie lineCookie = (LineCookie) dataObject
279: .getCookie(LineCookie.class);
280: if (lineCookie == null) {
281: return null;
282: }
283: Line.Set set = lineCookie.getLineSet();
284: if (set == null) {
285: return null;
286: }
287: return set.getOriginal(line - 1);
288: }
289:
290: }
|