blob: f607ad0536c6bc19065b5693d8fc7d296d7ff1ed [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.debugger.jpda.projectsui;
import org.netbeans.api.java.source.support.ErrorAwareTreePathScanner;
import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Function;
import java.util.logging.Logger;
import javax.lang.model.element.ElementKind;
import javax.swing.JEditorPane;
import javax.swing.SwingUtilities;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import org.netbeans.api.debugger.Breakpoint;
import org.netbeans.api.debugger.Properties;
import org.netbeans.api.debugger.jpda.InvalidExpressionException;
import org.netbeans.api.debugger.jpda.JPDAThread;
import org.netbeans.api.debugger.jpda.LineBreakpoint;
import org.netbeans.api.editor.mimelookup.MimeLookup;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.api.editor.settings.AttributesUtilities;
import org.netbeans.api.editor.settings.EditorStyleConstants;
import org.netbeans.api.editor.settings.FontColorSettings;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.editor.JumpList;
import org.netbeans.modules.debugger.jpda.projects.ASTOperationCreationDelegate;
import org.netbeans.modules.debugger.jpda.projects.EditorContextSupport;
import org.netbeans.modules.parsing.api.ResultIterator;
import org.netbeans.modules.parsing.spi.ParseException;
import org.netbeans.modules.parsing.spi.Parser.Result;
import org.netbeans.spi.debugger.jpda.EditorContext;
import org.netbeans.spi.debugger.jpda.Evaluator.Expression;
import org.netbeans.spi.debugger.jpda.SourcePathProvider;
import org.netbeans.spi.debugger.ui.EditorContextDispatcher;
import org.openide.ErrorManager;
import org.openide.cookies.EditorCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.text.Annotation;
import org.openide.text.Line;
import org.openide.text.Line.ShowOpenType;
import org.openide.text.Line.ShowVisibilityType;
import org.openide.text.NbDocument;
import org.openide.util.Pair;
import org.openide.util.Utilities;
import org.openide.util.WeakListeners;
/**
*
* @author Jan Jancura
*/
@EditorContext.Registration()
public class EditorContextImpl extends EditorContext {
private static String fronting =
System.getProperty ("netbeans.debugger.fronting", "true");
private static final Logger logger = Logger.getLogger(EditorContextImpl.class.getName());
private PropertyChangeSupport pcs;
private Map<Annotation, String> annotationToURL = new HashMap<Annotation, String>();
private final Object annotationToURLLock = new Object();
private PropertyChangeListener dispatchListener;
private EditorContextDispatcher contextDispatcher;
{
pcs = new PropertyChangeSupport (this);
dispatchListener = new EditorContextDispatchListener();
contextDispatcher = EditorContextDispatcher.getDefault();
contextDispatcher.addPropertyChangeListener("text/x-java",
WeakListeners.propertyChange(dispatchListener, contextDispatcher));
}
/**
* Shows source with given url on given line number.
*
* @param url a url of source to be shown
* @param lineNumber a number of line to be shown
* @param timeStamp a time stamp to be used
*/
@Override
public boolean showSource (String url, int lineNumber, Object timeStamp) {
Line l = showSourceLine(url, lineNumber, timeStamp);
if (l != null) {
addPositionToJumpList(url, l, 0);
}
return l != null;
}
static Line showSourceLine (String url, int lineNumber, Object timeStamp) {
Line l = LineTranslations.getTranslations().getLine (url, lineNumber, timeStamp); // false = use original ln
if (l == null) {
ErrorManager.getDefault().log(ErrorManager.WARNING,
"Show Source: Have no line for URL = "+url+", line number = "+lineNumber);
return null;
}
Properties p = Properties.getDefault().getProperties("debugger.options.JPDA");
boolean reuseEditorTabs = p.getBoolean("ReuseEditorTabs", true);
if ("true".equalsIgnoreCase(fronting)) {
if (reuseEditorTabs) {
l.show (ShowOpenType.REUSE, ShowVisibilityType.FOCUS);
} else {
l.show (ShowOpenType.OPEN, ShowVisibilityType.FOCUS);
}
l.show (ShowOpenType.OPEN, ShowVisibilityType.FRONT); //FIX 47825
} else {
if (reuseEditorTabs) {
l.show (ShowOpenType.REUSE, ShowVisibilityType.FOCUS);
} else {
l.show (ShowOpenType.OPEN, ShowVisibilityType.FOCUS);
}
}
return l;
}
/**
* Shows source with given url on given line number.
*
* @param url a url of source to be shown
* @param lineNumber a number of line to be shown
* @param timeStamp a time stamp to be used
*/
public boolean showSource (String url, int lineNumber, int column, int length, Object timeStamp) {
Line l = LineTranslations.getTranslations().getLine (url, lineNumber, timeStamp); // false = use original ln
if (l == null) {
ErrorManager.getDefault().log(ErrorManager.WARNING,
"Show Source: Have no line for URL = "+url+", line number = "+lineNumber);
return false;
}
if ("true".equalsIgnoreCase(fronting)) {
l.show (ShowOpenType.OPEN, ShowVisibilityType.FRONT, column); //FIX 47825
} else {
l.show (ShowOpenType.OPEN, ShowVisibilityType.FOCUS, column);
}
addPositionToJumpList(url, l, column);
return true;
}
/** Add the line offset into the jump history */
private void addPositionToJumpList(String url, Line l, int column) {
DataObject dataObject = getDataObject (url);
if (dataObject != null) {
EditorCookie ec = dataObject.getLookup().lookup(EditorCookie.class);
if (ec != null) {
try {
StyledDocument doc = ec.openDocument();
JEditorPane[] eps = ec.getOpenedPanes();
if (eps != null && eps.length > 0) {
JumpList.addEntry(eps[0], NbDocument.findLineOffset(doc, l.getLineNumber()) + column);
}
} catch (java.io.IOException ioex) {
ErrorManager.getDefault().notify(ioex);
}
}
}
}
/**
* Creates a new time stamp.
*
* @param timeStamp a new time stamp
*/
@Override
public void createTimeStamp (Object timeStamp) {
LineTranslations.getTranslations().createTimeStamp(timeStamp);
}
/**
* Disposes given time stamp.
*
* @param timeStamp a time stamp to be disposed
*/
@Override
public void disposeTimeStamp (Object timeStamp) {
LineTranslations.getTranslations().disposeTimeStamp(timeStamp);
}
@Override
public Object annotate (
String url,
int lineNumber,
String annotationType,
Object timeStamp
) {
return annotate(url, lineNumber, annotationType, timeStamp, null);
}
@Override
public Object annotate (
String url,
int lineNumber,
String annotationType,
Object timeStamp,
JPDAThread thread
) {
Line l = LineTranslations.getTranslations().getLine (
url,
lineNumber,
(timeStamp instanceof Breakpoint) ? null : timeStamp
);
if (l == null) {
return null;
}
Annotation annotation;
if (timeStamp instanceof Breakpoint) {
annotation = new DebuggerBreakpointAnnotation(annotationType, l, (Breakpoint) timeStamp);
} else {
annotation = new DebuggerAnnotation (annotationType, l, thread);
}
synchronized (annotationToURLLock) {
assert url != null;
annotationToURL.put (annotation, url);
}
return annotation;
}
@Override
public Object annotate (
String url,
int startPosition,
int endPosition,
String annotationType,
Object timeStamp
) {
AttributeSet attrs;
if (EditorContext.CURRENT_LAST_OPERATION_ANNOTATION_TYPE.equals(annotationType)) {
attrs = AttributesUtilities.createImmutable(EditorStyleConstants.WaveUnderlineColor, getColor(annotationType));
} else {
attrs = AttributesUtilities.createImmutable(StyleConstants.Background, getColor(annotationType));
}
DebuggerAnnotation annotation;
try {
annotation = new DebuggerAnnotation(annotationType, attrs, startPosition, endPosition,
URLMapper.findFileObject(new URL(url)));
} catch (MalformedURLException ex) {
throw new RuntimeException("Bad URL: "+url, ex);
}
synchronized (annotationToURLLock) {
assert url != null;
annotationToURL.put (annotation, url);
}
return annotation;
}
private static Color getColor(String annotationType) {
if (annotationType.endsWith("_broken")) {
annotationType = annotationType.substring(0, annotationType.length() - "_broken".length());
}
if (EditorContext.BREAKPOINT_ANNOTATION_TYPE.equals(annotationType)) {
return getHighlight(annotationType, 0xFC9D9F);
} else if (EditorContext.CURRENT_LINE_ANNOTATION_TYPE.equals(annotationType) ||
EditorContext.CURRENT_OUT_OPERATION_ANNOTATION_TYPE.equals(annotationType)) {
return getHighlight(annotationType, 0xBDE6AA);
//} else if (EditorContext.CURRENT_EXPRESSION_CURRENT_LINE_ANNOTATION_TYPE.equals(annotationType)) {
// return getHighlight(annotationType, 0xE9FFE6); // 0xE3FFD2// 0xD1FFBC
} else if (EditorContext.CURRENT_LAST_OPERATION_ANNOTATION_TYPE.equals(annotationType)) {
return getHighlight(annotationType, 0x99BB8A);
} else {
return new Color(0x0000FF);
}
}
private static Color getHighlight(String name, int defaultRGB) {
FontColorSettings fcs = MimeLookup.getLookup(MimePath.EMPTY).lookup(FontColorSettings.class);
AttributeSet as = (fcs != null) ? fcs.getFontColors(name) : null;
if (as != null) {
return (Color) as.getAttribute(StyleConstants.Background);
} else {
return new Color(defaultRGB);
}
}
/**
* Removes given annotation.
*
* @return true if annotation has been successfully removed
*/
@Override
public void removeAnnotation (
Object a
) {
if (a instanceof Collection) {
Collection annotations = ((Collection) a);
for (Iterator it = annotations.iterator(); it.hasNext(); ) {
removeAnnotation((Annotation) it.next());
}
} else {
removeAnnotation((Annotation) a);
}
}
private void removeAnnotation(Annotation annotation) {
synchronized (annotationToURLLock) {
String url = annotationToURL.remove (annotation);
//logger.severe("Removing "+annotation+", URL = "+url+", thread = "+Thread.currentThread().getId());
//Thread.dumpStack();
assert url != null;
}
annotation.detach ();
}
/**
* Returns line number given annotation is associated with.
*
* @param annotation an annotation, or an array of "url" and new Integer(line number)
* @param timeStamp a time stamp to be used
*
* @return line number given annotation is associated with
*/
@Override
public int getLineNumber (
Object annotation,
Object timeStamp
) {
if (annotation instanceof LineBreakpoint) {
// A sort of hack to be able to retrieve the original line.
LineBreakpoint lb = (LineBreakpoint) annotation;
return LineTranslations.getTranslations().getOriginalLineNumber(lb, timeStamp);
}
/*if (annotation instanceof Object[]) {
// A sort of hack to be able to retrieve the original line.
Object[] urlLine = (Object[]) annotation;
String url = (String) urlLine[0];
int line = ((Integer) urlLine[1]).intValue();
return LineTranslations.getTranslations().getOriginalLineNumber(url, line, timeStamp);
}*/
Line line;
if (annotation instanceof DebuggerBreakpointAnnotation) {
line = ((DebuggerBreakpointAnnotation) annotation).getLine();
} else {
line = ((DebuggerAnnotation) annotation).getLine();
}
if (timeStamp == null) {
return line.getLineNumber () + 1;
}
String url;
synchronized (annotationToURLLock) {
url = annotationToURL.get ((Annotation) annotation);
assert url != null;
}
Line.Set lineSet = LineTranslations.getTranslations().getLineSet (url, timeStamp);
return lineSet.getOriginalLineNumber (line) + 1;
}
/**
* Updates timeStamp for gived url.
*
* @param timeStamp time stamp to be updated
* @param url an url
*/
@Override
public void updateTimeStamp (Object timeStamp, String url) {
LineTranslations.getTranslations().updateTimeStamp(timeStamp, url);
}
/**
* Returns number of line currently selected in editor or <code>-1</code>.
*
* @return number of line currently selected in editor or <code>-1</code>
*/
@Override
public int getCurrentLineNumber () {
return contextDispatcher.getCurrentLineNumber();
}
/**
* Returns number of line currently selected in editor or <code>-1</code>.
*
* @return number of line currently selected in editor or <code>-1</code>
*/
public int getCurrentOffset () {
JEditorPane ep = contextDispatcher.getCurrentEditor();
if (ep == null) {
return -1;
}
Caret caret = ep.getCaret ();
if (caret == null) {
return -1;
}
return caret.getDot();
}
/**
* Returns name of class currently selected in editor or empty string.
*
* @return name of class currently selected in editor or empty string
*/
@Override
public String getCurrentClassName () {
String currentClass = getCurrentElement(ElementKind.CLASS);
if (currentClass == null) {
return "";
} else {
return currentClass;
}
}
/**
* Returns name of class recently selected in editor or empty string.
*
* @return name of class recently selected in editor or empty string
*/
public String getMostRecentClassName () {
String clazz = getMostRecentElement(ElementKind.CLASS);
if (clazz == null) {
return "";
} else {
return clazz;
}
}
/**
* Returns URL of source currently selected in editor or empty string.
*
* @return URL of source currently selected in editor or empty string
*/
@Override
public String getCurrentURL () {
return contextDispatcher.getCurrentURLAsString();
}
/**
* Returns name of method currently selected in editor or empty string.
*
* @return name of method currently selected in editor or empty string
*/
@Override
public String getCurrentMethodName () {
String currentMethod = getCurrentElement(ElementKind.METHOD);
if (currentMethod == null) {
return "";
} else {
return currentMethod;
}
}
/**
* Returns name of method recently selected in editor or empty string.
*
* @return name of method recently selected in editor or empty string
*/
public String getMostRecentMethodName () {
String method = getMostRecentElement(ElementKind.METHOD);
if (method == null) {
return "";
} else {
return method;
}
}
/**
* Returns signature of method currently selected in editor or null.
*
* @return signature of method currently selected in editor or null
*/
public String getCurrentMethodSignature () {
final String[] elementSignaturePtr = new String[] { null };
try {
getCurrentElement(ElementKind.METHOD, elementSignaturePtr);
} catch (final java.awt.IllegalComponentStateException icse) {
throw new java.awt.IllegalComponentStateException() {
@Override
public String getMessage() {
icse.getMessage();
return elementSignaturePtr[0];
}
};
}
return elementSignaturePtr[0];
}
public String getMostRecentMethodSignature () {
final String[] elementSignaturePtr = new String[] { null };
try {
getMostRecentElement(ElementKind.METHOD, elementSignaturePtr);
} catch (final java.awt.IllegalComponentStateException icse) {
throw new java.awt.IllegalComponentStateException() {
@Override
public String getMessage() {
icse.getMessage();
return elementSignaturePtr[0];
}
};
}
return elementSignaturePtr[0];
}
/**
* Returns name of field currently selected in editor or <code>null</code>.
*
* @return name of field currently selected in editor or <code>null</code>
*/
@Override
public String getCurrentFieldName () {
String currentField = getCurrentElement(ElementKind.FIELD);
if (currentField == null) {
return "";
} else {
return currentField;
}
//return getSelectedIdentifier ();
}
/**
* Returns name of field recently selected in editor or <code>null</code>.
*
* @return name of field recently selected in editor or <code>null</code>
*/
public String getMostRecentFieldName () {
String field = getMostRecentElement(ElementKind.FIELD);
if (field == null) {
return "";
} else {
return field;
}
}
/**
* Returns identifier currently selected in editor or <code>null</code>.
*
* @return identifier currently selected in editor or <code>null</code>
*/
@Override
public String getSelectedIdentifier () {
JEditorPane ep = contextDispatcher.getCurrentEditor ();
if (ep == null) {
return null;
}
Caret caret = ep.getCaret();
if (caret == null) {
// No caret => no selected text
return null;
}
String s = ep.getSelectedText ();
if (s == null) {
return null;
}
if (Utilities.isJavaIdentifier (s)) {
return s;
}
return null;
}
/**
* Returns method name currently selected in editor or empty string.
*
* @return method name currently selected in editor or empty string
*/
@Override
public String getSelectedMethodName () {
if (SwingUtilities.isEventDispatchThread()) {
return getSelectedMethodName_();
} else {
final String[] mn = new String[1];
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
mn[0] = getSelectedMethodName_();
}
});
} catch (InvocationTargetException ex) {
ErrorManager.getDefault().notify(ex.getTargetException());
} catch (InterruptedException ex) {
// interrupted, ignored.
}
return mn[0];
}
}
private String getSelectedMethodName_() {
JEditorPane ep = contextDispatcher.getCurrentEditor ();
if (ep == null) {
return "";
}
StyledDocument doc = (StyledDocument) ep.getDocument ();
if (doc == null) {
return "";
}
int offset = ep.getCaret ().getDot ();
String t;
// if ( (ep.getSelectionStart () <= offset) &&
// (offset <= ep.getSelectionEnd ())
// ) t = ep.getSelectedText ();
// if (t != null) return t;
int line = NbDocument.findLineNumber (
doc,
offset
);
int col = NbDocument.findLineColumn (
doc,
offset
);
try {
javax.swing.text.Element lineElem =
org.openide.text.NbDocument.findLineRootElement (doc).
getElement (line);
if (lineElem == null) {
return "";
}
int lineStartOffset = lineElem.getStartOffset ();
int lineLen = lineElem.getEndOffset () - lineStartOffset;
// t contains current line in editor
t = doc.getText (lineStartOffset, lineLen);
int identStart = col;
while ( identStart > 0 &&
Character.isJavaIdentifierPart (
t.charAt (identStart - 1)
)
) {
identStart--;
}
int identEnd = col;
while (identEnd < lineLen &&
Character.isJavaIdentifierPart (t.charAt (identEnd))
) {
identEnd++;
}
int i = t.indexOf ('(', identEnd);
if (i < 0) {
return "";
}
if (t.substring (identEnd, i).trim ().length () > 0) {
return "";
}
if (identStart == identEnd) {
return "";
}
return t.substring (identStart, identEnd);
} catch (javax.swing.text.BadLocationException ex) {
return "";
}
}
/**
* Returns line number of given field in given class.
*
* @param url the url of file the class is deined in
* @param className the name of class (or innerclass) the field is
* defined in
* @param fieldName the name of field
*
* @return line number or -1
*/
@Override
public int getFieldLineNumber (
String url,
final String className,
final String fieldName
) {
return EditorContextSupport.getFieldLineNumber(url, className, fieldName);
}
/**
* Returns line number of given method in given class.
*
* @param url the url of file the class is deined in
* @param className the name of class (or innerclass) the method is
* defined in
* @param methodName the name of method
* @param methodSignature the JNI-style signature of the method.
* If <code>null</code>, then the first method found is returned.
*
* @return line number or -1
*/
@Override
public int getMethodLineNumber (
String url,
final String className,
final String methodName,
final String methodSignature
) {
return EditorContextSupport.getMethodLineNumber(url, className, methodName, methodSignature);
}
/** @return declared class name
*/
public String getCurrentClassDeclaration() {
FileObject fo = contextDispatcher.getCurrentFile();
if (fo == null) {
return null;
}
JEditorPane ep = contextDispatcher.getCurrentEditor();
final int currentOffset = (ep == null) ? 0 : ep.getCaretPosition();
//final int currentOffset = org.netbeans.editor.Registry.getMostActiveComponent().getCaretPosition();
return EditorContextSupport.getClassDeclaredAt(fo, currentOffset);
}
/** @return { "method name", "method signature", "enclosing class name" }
*/
@Override
public String[] getCurrentMethodDeclaration() {
FileObject fo = contextDispatcher.getCurrentFile();
if (fo == null) {
return null;
}
JEditorPane ep = contextDispatcher.getCurrentEditor();
final int currentOffset = (ep == null) ? 0 : ep.getCaretPosition();
return EditorContextSupport.getMethodDeclaredAt(fo, currentOffset);
}
/**
* Returns binary class name for given url and line number or null.
*
* @param url a url
* @param lineNumber a line number
*
* @return binary class name for given url and line number or null
*/
@Override
public String getClassName (
String url,
int lineNumber
) {
return EditorContextSupport.getClassName(url, lineNumber);
}
@Override
public Operation[] getOperations(String url, final int lineNumber,
final BytecodeProvider bytecodeProvider) {
return EditorContextSupport.getOperations(url, lineNumber,
bytecodeProvider,
new OperationCreationDelegateImpl());
}
/** return the offset of the first non-whitespace character on the line,
or -1 when the line does not exist
*/
private static int findLineOffset(StyledDocument doc, int lineNumber) {
int offset;
try {
offset = NbDocument.findLineOffset (doc, lineNumber - 1);
int offset2 = NbDocument.findLineOffset (doc, lineNumber);
try {
String lineStr = doc.getText(offset, offset2 - offset);
for (int i = 0; i < lineStr.length(); i++) {
if (!Character.isWhitespace(lineStr.charAt(i))) {
offset += i;
break;
}
}
} catch (BadLocationException ex) {
// ignore
}
} catch (IndexOutOfBoundsException ioobex) {
return -1;
}
return offset;
}
@Override
public MethodArgument[] getArguments(String url, final Operation operation) {
return EditorContextSupport.getArguments(url, operation, new OperationCreationDelegateImpl());
}
@Override
public MethodArgument[] getArguments(String url, final int methodLineNumber) {
return EditorContextSupport.getArguments(url, methodLineNumber, new OperationCreationDelegateImpl());
}
/**
* Returns list of imports for given source url.
*
* @param url the url of source file
*
* @return list of imports for given source url
*/
@Override
public String[] getImports (
String url
) {
return EditorContextSupport.getImports(url);
}
public <R,D> R interpretOrCompileCode(final Expression<Object> expression, String url, final int line,
final ErrorAwareTreePathScanner<Boolean,D> canInterpret,
final ErrorAwareTreePathScanner<R,D> interpreter,
final D context, final boolean staticContext,
final Function<Pair<String, byte[]>, Boolean> compiledClassHandler,
final SourcePathProvider sp) throws InvalidExpressionException {
return EditorContextSupport.interpretOrCompileCode(expression, url, line,
canInterpret,
interpreter,
context, staticContext,
compiledClassHandler,
sp);
}
/**
* Adds a property change listener.
*
* @param l the listener to add
*/
@Override
public void addPropertyChangeListener (PropertyChangeListener l) {
pcs.addPropertyChangeListener (l);
}
/**
* Removes a property change listener.
*
* @param l the listener to remove
*/
@Override
public void removePropertyChangeListener (PropertyChangeListener l) {
pcs.removePropertyChangeListener (l);
}
/**
* Adds a property change listener.
*
* @param propertyName the name of property
* @param l the listener to add
*/
@Override
public void addPropertyChangeListener (
String propertyName,
PropertyChangeListener l
) {
pcs.addPropertyChangeListener (propertyName, l);
}
/**
* Removes a property change listener.
*
* @param propertyName the name of property
* @param l the listener to remove
*/
@Override
public void removePropertyChangeListener (
String propertyName,
PropertyChangeListener l
) {
pcs.removePropertyChangeListener (propertyName, l);
}
// private helper methods ..................................................
// public void fileChanged (FileEvent fe) {
// pcs.firePropertyChange (PROP_LINE_NUMBER, null, null);
// }
//
// public void fileDeleted (FileEvent fe) {}
// public void fileAttributeChanged (org.openide.filesystems.FileAttributeEvent fe) {}
// public void fileDataCreated (FileEvent fe) {}
// public void fileFolderCreated (FileEvent fe) {}
// public void fileRenamed (org.openide.filesystems.FileRenameEvent fe) {}
private String getCurrentElement(ElementKind kind) {
return getCurrentElement(kind, null);
}
private String getMostRecentElement(ElementKind kind) {
return getMostRecentElement(kind, null);
}
/** throws IllegalComponentStateException when can not return the data in AWT. */
private String getCurrentElement(final ElementKind kind, final String[] elementSignaturePtr)
throws java.awt.IllegalComponentStateException {
return getCurrentElement(contextDispatcher.getCurrentFile(),
contextDispatcher.getCurrentEditor(),
kind, elementSignaturePtr);
}
/** throws IllegalComponentStateException when can not return the data in AWT. */
private String getMostRecentElement(final ElementKind kind, final String[] elementSignaturePtr)
throws java.awt.IllegalComponentStateException {
return getCurrentElement(contextDispatcher.getMostRecentFile(),
contextDispatcher.getMostRecentEditor(),
kind, elementSignaturePtr);
}
/** throws IllegalComponentStateException when can not return the data in AWT. */
private String getCurrentElement(FileObject fo, JEditorPane ep,
final ElementKind kind, final String[] elementSignaturePtr)
throws java.awt.IllegalComponentStateException {
if (fo == null) {
return null;
}
final int currentOffset;
final String selectedIdentifier;
if (ep != null) {
String s;
Caret caret = ep.getCaret();
if (caret == null) {
s = null;
currentOffset = 0;
} else {
s = ep.getSelectedText ();
currentOffset = ep.getCaretPosition();
if (ep.getSelectionStart() > currentOffset || ep.getSelectionEnd() < currentOffset) {
s = null; // caret outside of the selection
}
}
if (s != null && Utilities.isJavaIdentifier (s)) {
selectedIdentifier = s;
} else {
selectedIdentifier = null;
}
} else {
selectedIdentifier = null;
currentOffset = 0;
}
return EditorContextSupport.getCurrentElement(fo, currentOffset, selectedIdentifier, kind, elementSignaturePtr);
}
private static DataObject getDataObject (String url) {
FileObject file;
try {
file = URLMapper.findFileObject (new URL (url));
} catch (MalformedURLException e) {
return null;
}
if (file == null) {
return null;
}
try {
return DataObject.find (file);
} catch (DataObjectNotFoundException ex) {
return null;
}
}
private static StyledDocument findDocument(FileObject fo) {
DataObject dataObject;
try {
dataObject = DataObject.find (fo);
} catch (DataObjectNotFoundException ex) {
return null;
}
EditorCookie ec = (EditorCookie) dataObject.getLookup().lookup(EditorCookie.class);
if (ec == null) {
return null;
}
StyledDocument doc;
try {
doc = ec.openDocument();
} catch (IOException ex) {
return null;
}
return doc;
}
private static StyledDocument findDocument(DataObject dataObject) {
EditorCookie ec = (EditorCookie) dataObject.getLookup().lookup(EditorCookie.class);
if (ec == null) {
return null;
}
StyledDocument doc;
try {
doc = ec.openDocument();
} catch (IOException ex) {
return null;
}
return doc;
}
private static CompilationController retrieveController(ResultIterator resIt, StyledDocument doc) throws ParseException {
Result res = resIt.getParserResult();
CompilationController ci = res != null ? CompilationController.get(res) : null;
if (ci == null) {
ErrorManager.getDefault().log(ErrorManager.WARNING,
"Unable to get compilation controller " + doc);
}
return ci;
}
// Support classes:
private class EditorContextDispatchListener extends Object implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
pcs.firePropertyChange (org.openide.windows.TopComponent.Registry.PROP_CURRENT_NODES, null, null);
}
}
private class OperationCreationDelegateImpl implements ASTOperationCreationDelegate {
/*
public Operation createOperation(
Position startPosition,
Position endPosition,
int bytecodeIndex) {
return EditorContextImpl.this.createOperation(
startPosition,
endPosition,
bytecodeIndex);
}
*/
@Override
public Operation createMethodOperation(
Position startPosition,
Position endPosition,
Position methodStartPosition,
Position methodEndPosition,
String methodName,
String methodClassType,
int bytecodeIndex,
boolean isNative) {
return EditorContextImpl.this.createMethodOperation(
startPosition,
endPosition,
methodStartPosition,
methodEndPosition,
methodName,
methodClassType,
bytecodeIndex, isNative);
}
@Override
public Position createPosition(
int offset,
int line,
int column) {
return EditorContextImpl.this.createPosition(
offset,
line,
column);
}
@Override
public void addNextOperationTo(Operation operation, Operation next) {
EditorContextImpl.this.addNextOperationTo(operation, next);
}
}
}