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 Micro//S ystems, Inc. Portions Copyright 1997-2007 Sun
028: * Micro//S ystems, 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.spi.debugger.jpda;
042:
043: import java.beans.PropertyChangeListener;
044: import java.util.ArrayList;
045: import java.util.Collection;
046: import java.util.Collections;
047: import java.util.Iterator;
048: import java.util.List;
049: import org.netbeans.api.debugger.jpda.LineBreakpoint;
050: import org.netbeans.api.debugger.jpda.LocalVariable;
051: import org.netbeans.api.debugger.jpda.Variable;
052:
053: /**
054: * Defines bridge to editor and src hierarchy. It allows to use different
055: * source viewer for debugger (like some UML view).
056: *
057: * @author Jan Jancura
058: */
059: public abstract class EditorContext {
060:
061: /** Annotation type constant. */
062: public static final String BREAKPOINT_ANNOTATION_TYPE = "Breakpoint";
063: /** Annotation type constant. */
064: public static final String DISABLED_BREAKPOINT_ANNOTATION_TYPE = "DisabledBreakpoint";
065: /** Annotation type constant. */
066: public static final String CONDITIONAL_BREAKPOINT_ANNOTATION_TYPE = "CondBreakpoint";
067: /** Annotation type constant. */
068: public static final String DISABLED_CONDITIONAL_BREAKPOINT_ANNOTATION_TYPE = "DisabledCondBreakpoint";
069: /** Annotation type constant. */
070: public static final String FIELD_BREAKPOINT_ANNOTATION_TYPE = "FieldBreakpoint";
071: /** Annotation type constant. */
072: public static final String DISABLED_FIELD_BREAKPOINT_ANNOTATION_TYPE = "DisabledFieldBreakpoint";
073: /** Annotation type constant. */
074: public static final String METHOD_BREAKPOINT_ANNOTATION_TYPE = "MethodBreakpoint";
075: /** Annotation type constant. */
076: public static final String DISABLED_METHOD_BREAKPOINT_ANNOTATION_TYPE = "DisabledMethodBreakpoint";
077: /** Annotation type constant. */
078: public static final String CURRENT_LINE_ANNOTATION_TYPE = "CurrentPC";
079: /** Annotation type constant. */
080: public static final String CALL_STACK_FRAME_ANNOTATION_TYPE = "CallSite";
081: /** Annotation type constant. */
082: public static final String CURRENT_LAST_OPERATION_ANNOTATION_TYPE = "LastOperation";
083: /** Annotation type constant. */
084: public static final String CURRENT_OUT_OPERATION_ANNOTATION_TYPE = "StepOutOperation";
085: /** Annotation type constant. */
086: public static final String CURRENT_EXPRESSION_SECONDARY_LINE_ANNOTATION_TYPE = "CurrentExpression";
087: /** Annotation type constant. */
088: public static final String CURRENT_EXPRESSION_CURRENT_LINE_ANNOTATION_TYPE = "CurrentExpressionLine";
089:
090: /** Property name constant. */
091: public static final String PROP_LINE_NUMBER = "lineNumber";
092:
093: /**
094: * Shows source with given url on given line number.
095: *
096: * @param url a url of source to be shown
097: * @param lineNumber a number of line to be shown
098: * @param timeStamp a time stamp to be used
099: */
100: public abstract boolean showSource(String url, int lineNumber,
101: Object timeStamp);
102:
103: /**
104: * Creates a new time stamp.
105: *
106: * @param timeStamp a new time stamp
107: */
108: public abstract void createTimeStamp(Object timeStamp);
109:
110: /**
111: * Disposes given time stamp.
112: *
113: * @param timeStamp a time stamp to be disposed
114: */
115: public abstract void disposeTimeStamp(Object timeStamp);
116:
117: /**
118: * Updates timeStamp for gived url.
119: *
120: * @param timeStamp time stamp to be updated
121: * @param url an url
122: */
123: public abstract void updateTimeStamp(Object timeStamp, String url);
124:
125: /**
126: * Adds annotation to given url on given line.
127: *
128: * @param url a url of source annotation should be set into
129: * @param lineNumber a number of line annotation should be set into
130: * @param annotationType a type of annotation to be set
131: * @param timeStamp a time stamp to be used
132: *
133: * @return annotation or <code>null</code>, when the annotation can not be
134: * created at the given URL or line number.
135: */
136: public abstract Object annotate(String url, int lineNumber,
137: String annotationType, Object timeStamp);
138:
139: /**
140: * Adds annotation to given url on given character range.
141: *
142: * @param url a url of source annotation should be set into
143: * @param startPosition the offset of the starting position of the annotation
144: * @param endPosition the offset of the ending position of the annotation
145: * @param annotationType a type of annotation to be set
146:
147: * @return annotation or <code>null</code>, when the annotation can not be
148: * created at the given URL or line number.
149: */
150: public Object annotate(String url, int startPosition,
151: int endPosition, String annotationType, Object timeStamp) {
152: return null;
153: }
154:
155: /**
156: * Returns line number given annotation is associated with.
157: *
158: * @param annotation a annotation
159: * @param timeStamp a time stamp to be used
160: *
161: * @return line number given annotation is associated with
162: */
163: public abstract int getLineNumber(Object annotation,
164: Object timeStamp);
165:
166: /**
167: * Removes given annotation.
168: */
169: public abstract void removeAnnotation(Object annotation);
170:
171: /**
172: * Returns number of line currently selected in editor or <code>-1</code>.
173: *
174: * @return number of line currently selected in editor or <code>-1</code>
175: */
176: public abstract int getCurrentLineNumber();
177:
178: /**
179: * Returns name of class currently selected in editor or empty string.
180: *
181: * @return name of class currently selected in editor or empty string
182: */
183: public abstract String getCurrentClassName();
184:
185: /**
186: * Returns URL of source currently selected in editor or empty string.
187: *
188: * @return URL of source currently selected in editor or empty string
189: */
190: public abstract String getCurrentURL();
191:
192: /**
193: * Returns name of method currently selected in editor or empty string.
194: *
195: * @return name of method currently selected in editor or empty string
196: */
197: public abstract String getCurrentMethodName();
198:
199: /**
200: * Returns name of field currently selected in editor or <code>null</code>.
201: *
202: * @return name of field currently selected in editor or <code>null</code>
203: */
204: public abstract String getCurrentFieldName();
205:
206: /**
207: * Returns identifier currently selected in editor or <code>null</code>.
208: *
209: * @return identifier currently selected in editor or <code>null</code>
210: */
211: public abstract String getSelectedIdentifier();
212:
213: /**
214: * Returns method name currently selected in editor or empty string.
215: *
216: * @return method name currently selected in editor or empty string
217: */
218: public abstract String getSelectedMethodName();
219:
220: /**
221: * Returns line number of given field in given class.
222: *
223: * @param url the url of source file the class is deined in
224: * @param className the name of class (or innerclass) the field is
225: * defined in
226: * @param fieldName the name of field
227: *
228: * @return line number or -1
229: */
230: public abstract int getFieldLineNumber(String url,
231: String className, String fieldName);
232:
233: /**
234: * Returns line number of given method in given class.
235: *
236: * @param url the url of source file the class is deined in
237: * @param className the name of class (or innerclass) the method is
238: * defined in
239: * @param methodName the name of the method
240: * @param methodSignature the JNI-style signature of the method.
241: * If <code>null</code>, then the first method found is returned.
242: *
243: * @return line number or -1
244: */
245: public int getMethodLineNumber(String url, final String className,
246: final String methodName, final String methodSignature) {
247: return -1;
248: }
249:
250: /**
251: * Returns name and signature of method declaration currently selected in editor,
252: * or <code>null</code>.
253: *
254: * @return name and signature of the method, or <code>null</code>.
255: */
256: public String[] getCurrentMethodDeclaration() {
257: return null;
258: }
259:
260: /**
261: * Returns class name for given url and line number or null.
262: *
263: * @param url a url
264: * @param lineNumber a line number
265: *
266: * @return class name for given url and line number or null
267: */
268: public abstract String getClassName(String url, int lineNumber);
269:
270: /**
271: * Returns list of imports for given source url.
272: *
273: * @param url the url of source file
274: *
275: * @return list of imports for given source url
276: */
277: public abstract String[] getImports(String url);
278:
279: /**
280: * Creates an operation which is determined by starting and ending position.
281: *
282: protected final Operation createOperation(Position startPosition,
283: Position endPosition,
284: int bytecodeIndex) {
285: return new Operation(startPosition, endPosition, bytecodeIndex);
286: }
287: */
288:
289: /**
290: * Creates a method operation.
291: * @param startPosition The starting position of the operation
292: * @param endPosition The ending position of the operation
293: * @param methodStartPosition The starting position of the method name
294: * @param methodEndPosition The ending position of the method name
295: * @param methodName The string representation of the method name
296: * @param methodClassType The class type, which defines this method
297: * @param bytecodeIndex The bytecode index of this method call
298: */
299: protected final Operation createMethodOperation(
300: Position startPosition, Position endPosition,
301: Position methodStartPosition, Position methodEndPosition,
302: String methodName, String methodClassType, int bytecodeIndex) {
303: return new Operation(startPosition, endPosition,
304: methodStartPosition, methodEndPosition, methodName,
305: methodClassType, bytecodeIndex);
306: }
307:
308: /**
309: * Assign a next operation, concatenates operations.
310: * @param operation The first operation
311: * @param next The next operation
312: */
313: protected final void addNextOperationTo(Operation operation,
314: Operation next) {
315: operation.addNextOperation(next);
316: }
317:
318: /**
319: * Creates a new {@link Position} object.
320: * @param offset The offset
321: * @param line The line number
322: * @param column The column number
323: */
324: protected final Position createPosition(int offset, int line,
325: int column) {
326:
327: return new Position(offset, line, column);
328: }
329:
330: /**
331: * Get the list of operations that are in expression(s) located at the given line.
332: * @param url The file's URL
333: * @param lineNumber The line number
334: * @param bytecodeProvider The provider of method bytecodes.
335: */
336: public Operation[] getOperations(String url, int lineNumber,
337: BytecodeProvider bytecodeProvider) {
338: throw new UnsupportedOperationException(
339: "This method is not implemented.");
340: }
341:
342: /**
343: * Get a list of arguments to the given operation.
344: * @param url The URL of the source file with the operation
345: * @param operation The operation
346: */
347: public MethodArgument[] getArguments(String url, Operation operation) {
348: throw new UnsupportedOperationException(
349: "This method is not implemented.");
350: }
351:
352: /**
353: * Get a list of arguments passed to method located at the given line.
354: * @param url The URL of the source file
355: * @param methodLineNumber The line number of the method header
356: */
357: public MethodArgument[] getArguments(String url,
358: int methodLineNumber) {
359: throw new UnsupportedOperationException(
360: "This method is not implemented.");
361: }
362:
363: /**
364: * Adds a property change listener.
365: *
366: * @param l the listener to add
367: */
368: public abstract void addPropertyChangeListener(
369: PropertyChangeListener l);
370:
371: /**
372: * Removes a property change listener.
373: *
374: * @param l the listener to remove
375: */
376: public abstract void removePropertyChangeListener(
377: PropertyChangeListener l);
378:
379: /**
380: * Adds a property change listener.
381: *
382: * @param propertyName the name of property
383: * @param l the listener to add
384: */
385: public abstract void addPropertyChangeListener(String propertyName,
386: PropertyChangeListener l);
387:
388: /**
389: * Removes a property change listener.
390: *
391: * @param propertyName the name of property
392: * @param l the listener to remove
393: */
394: public abstract void removePropertyChangeListener(
395: String propertyName, PropertyChangeListener l);
396:
397: /**
398: * A provider of method bytecode information.
399: */
400: public interface BytecodeProvider {
401:
402: /**
403: * Retrieve the class' constant pool.
404: */
405: byte[] constantPool();
406:
407: /**
408: * Retrieve the bytecodes of the method.
409: */
410: byte[] byteCodes();
411:
412: /**
413: * Get an array of bytecode indexes of operations between the starting
414: * and ending line.
415: * @param startLine The starting line
416: * @param endLine The ending line
417: */
418: int[] indexAtLines(int startLine, int endLine);
419:
420: }
421:
422: /**
423: * The operation definition.
424: */
425: public static final class Operation {
426:
427: private final Position startPosition;
428: private final Position endPosition;
429: private final int bytecodeIndex;
430:
431: private Position methodStartPosition;
432: private Position methodEndPosition;
433: private String methodName;
434: private String methodClassType;
435: private Variable returnValue;
436:
437: private List<Operation> nextOperations;
438:
439: /*
440: Operation(Position startPosition, Position endPosition,
441: int bytecodeIndex) {
442: this.startPosition = startPosition;
443: this.endPosition = endPosition;
444: this.bytecodeIndex = bytecodeIndex;
445: }
446: */
447:
448: /**
449: * Creates a new method operation.
450: */
451: Operation(Position startPosition, Position endPosition,
452: Position methodStartPosition,
453: Position methodEndPosition, String methodName,
454: String methodClassType, int bytecodeIndex) {
455: this .startPosition = startPosition;
456: this .endPosition = endPosition;
457: this .bytecodeIndex = bytecodeIndex;
458: this .methodStartPosition = methodStartPosition;
459: this .methodEndPosition = methodEndPosition;
460: this .methodName = methodName;
461: this .methodClassType = methodClassType;
462: }
463:
464: synchronized void addNextOperation(Operation next) {
465: if (nextOperations == null) {
466: nextOperations = new ArrayList<Operation>();
467: }
468: nextOperations.add(next);
469: }
470:
471: /**
472: * Get the starting position of this operation.
473: */
474: public Position getStartPosition() {
475: return startPosition;
476: }
477:
478: /**
479: * Get the ending position of this operation.
480: */
481: public Position getEndPosition() {
482: return endPosition;
483: }
484:
485: /**
486: * Get the starting position of the method call of this operation.
487: */
488: public Position getMethodStartPosition() {
489: return methodStartPosition;
490: }
491:
492: /**
493: * Get the ending position of the method call of this operation.
494: */
495: public Position getMethodEndPosition() {
496: return methodEndPosition;
497: }
498:
499: /**
500: * Get the method name.
501: */
502: public String getMethodName() {
503: return methodName;
504: }
505:
506: /**
507: * Get the class type declaring the method.
508: */
509: public String getMethodClassType() {
510: return methodClassType;
511: }
512:
513: /**
514: * Get the bytecode index of this operation.
515: */
516: public int getBytecodeIndex() {
517: return bytecodeIndex;
518: }
519:
520: /**
521: * Set the return value of this operation.
522: */
523: public void setReturnValue(Variable returnValue) {
524: this .returnValue = returnValue;
525: }
526:
527: /**
528: * Get the return value of this operation.
529: */
530: public Variable getReturnValue() {
531: return returnValue;
532: }
533:
534: /**
535: * Get the list of following operations.
536: */
537: public List<Operation> getNextOperations() {
538: if (nextOperations == null) {
539: return Collections.emptyList();
540: } else {
541: synchronized (this ) {
542: return Collections.unmodifiableList(nextOperations);
543: }
544: }
545: }
546:
547: public boolean equals(Object obj) {
548: if (obj instanceof Operation) {
549: Operation op2 = (Operation) obj;
550: return bytecodeIndex == op2.bytecodeIndex
551: && ((startPosition == null) ? op2.startPosition == null
552: : startPosition
553: .equals(op2.startPosition))
554: && ((endPosition == null) ? op2.endPosition == null
555: : endPosition.equals(op2.endPosition));
556: }
557: return false;
558: }
559:
560: public int hashCode() {
561: return bytecodeIndex;
562: }
563:
564: }
565:
566: /**
567: * Representation of a position in a source code.
568: */
569: public static final class Position {
570:
571: private final int offset;
572: private final int line;
573: private final int column;
574:
575: Position(int offset, int line, int column) {
576: this .offset = offset;
577: this .line = line;
578: this .column = column;
579: }
580:
581: /**
582: * Get the offset of this position.
583: */
584: public int getOffset() {
585: return offset;
586: }
587:
588: /**
589: * Get the line number of this position.
590: */
591: public int getLine() {
592: return line;
593: }
594:
595: /**
596: * Get the column number of this position.
597: */
598: public int getColumn() {
599: return column;
600: }
601:
602: public boolean equals(Object obj) {
603: if (obj instanceof Position) {
604: Position pos = (Position) obj;
605: return pos.offset == offset;
606: }
607: return false;
608: }
609:
610: public int hashCode() {
611: return offset;
612: }
613:
614: }
615:
616: /**
617: * Representation of an argument to a method.
618: * @since 2.10
619: */
620: public static final class MethodArgument {
621:
622: private String name;
623: private String type;
624: private Position startPos;
625: private Position endPos;
626:
627: /**
628: * Creates a new argument.
629: * @param name The argument name
630: * @param type The declared type of the argument
631: * @param startPos Starting position of the argument in the source code
632: * @param endPos Ending position of the argument in the source code
633: */
634: public MethodArgument(String name, String type,
635: Position startPos, Position endPos) {
636: this .name = name;
637: this .type = type;
638: startPos = startPos;
639: endPos = endPos;
640: }
641:
642: /**
643: * Get the name of this argument.
644: * @return The name.
645: */
646: public String getName() {
647: return name;
648: }
649:
650: /**
651: * Get the declared type of this argument.
652: * @return The declared type.
653: */
654: public String getType() {
655: return type;
656: }
657:
658: /**
659: * Get the starting position of this argument in the source code.
660: * @return The starting position.
661: */
662: public Position getStartPosition() {
663: return startPos;
664: }
665:
666: /**
667: * Get the ending position of this argument in the source code.
668: * @return The ending position.
669: */
670: public Position getEndPosition() {
671: return endPos;
672: }
673:
674: }
675:
676: }
|