package de.cismet.beanmill;
import com.traxel.lumbermill.event.Event;
import com.traxel.lumbermill.event.Table;
import org.apache.log4j.Logger;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.classpath.GlobalPathRegistry;
import org.netbeans.api.java.queries.SourceForBinaryQuery;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.netbeans.spi.java.classpath.support.ClassPathSupport;
import org.openide.ErrorManager;
import org.openide.cookies.EditCookie;
import org.openide.cookies.EditorCookie;
import org.openide.cookies.OpenCookie;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.nodes.Node;
import org.openide.text.NbDocument;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.NbPreferences;
import org.openide.util.WeakListeners;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.CharArrayWriter;
import java.io.Serializable;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.swing.JEditorPane;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkEvent.EventType;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.JTextComponent;
import javax.swing.text.StyledDocument;
private static final transient Logger LOG = Logger.getLogger(LoggingTopComponent.class);
static final String ICON_PATH = "de/cismet/beanmill/res/log.png";
private static final String PREFERRED_ID = "LoggingTopComponent";
private static LoggingTopComponent instance;
BeanMillPane bmp = null;
private MySelectionListener mySelectionListener = new MySelectionListener();
private String editedJavaSourceFullPath = null;
private int editedSelectionFrom = -1;
private int editedSelectionTo = -1;
initComponents();
TopComponent.getRegistry().addPropertyChangeListener(new PropertyChangeListener() {
@Override
try {
if (evt.getPropertyName().equals("activated")) {
final Node[] nodes = TopComponent.getRegistry().getActivatedNodes();
if ((nodes == null) || (nodes.length == 0)) {
return;
}
final EditorCookie ec = nodes[0].getCookie(EditorCookie.class);
JEditorPane editor = null;
final FileObject fo = NbEditorUtilities.getFileObject(ec.getDocument());
final ClassPath sourceCP = ClassPath.getClassPath(fo, ClassPath.SOURCE);
final String fullName = sourceCP.getResourceName(fo, '.', false);
if (ec != null) {
final JEditorPane[] panes = ec.getOpenedPanes();
if (panes != null) {
final TopComponent activetc = TopComponent.getRegistry().getActivated();
for (int i = 0; i < panes.length; i++) {
if (activetc.isAncestorOf(panes[i])) {
editor = panes[i];
}
}
}
}
if (editor != null) {
mySelectionListener.setEditor(editor);
mySelectionListener.setFullName(fullName);
fireSelectionChange(editor, fullName);
editor.addMouseMotionListener(
WeakListeners.create(MouseMotionListener.class, mySelectionListener, editor));
editor.addCaretListener(
WeakListeners.create(CaretListener.class, mySelectionListener, editor));
}
}
} catch (final Exception ex) {
LOG.warn("cannot process property change: " + evt, ex);
}
}
});
setName(NbBundle.getMessage(LoggingTopComponent.class, "CTL_LoggingTopComponent"));
setToolTipText(NbBundle.getMessage(LoggingTopComponent.class, "HINT_LoggingTopComponent"));
setIcon(ImageUtilities.loadImage(ICON_PATH, true));
try {
final int port = NbPreferences.forModule(LoggingTopComponent.class)
.getInt(NetbeansPanel.PROP_LISTENER_PORT, 4445);
bmp = new BeanMillPane(port);
bmp.setActiveSelectionCheckBoxEnabled(true);
bmp.getEventTable().addMouseListener(new MouseListener() {
@Override
if (e.getClickCount() == 2) {
final int row = bmp.getEventTable().getSelectedRow();
final Event logEvent = ((Table)bmp.getEventTable().getModel()).getEvent(row);
if (logEvent != null) {
final String location = logEvent.getLocation();
final String nameSplit = location.split("\\(")[0];
final String fullname = nameSplit.substring(0, nameSplit.lastIndexOf('.'));
final int linenumber = new Integer(location.split("java:")[1].split("\\)")[0]);
openJava(fullname, linenumber);
}
}
}
@Override
}
@Override
}
@Override
}
@Override
}
});
bmp.getDetailPanel().addHyperlinkListener(new HyperlinkListener() {
@Override
if (e.getEventType().equals(EventType.ACTIVATED)) {
try {
final String line = e.getDescription();
final String[] ar = line.split(":");
final String path = ar[0];
final String linenumber = ar[1];
final int lNo = new Integer(linenumber);
openJava(path, lNo);
} catch (Exception ex) {
ErrorManager.getDefault().notify(ex);
}
}
}
});
bmp.getLogActiveStateView().getClearButton().addActionListener(new ActionListener() {
@Override
bmp.getDetailPanel().setText("");
}
});
this.add(bmp, BorderLayout.CENTER);
} catch (final Exception e) {
LOG.error("cannot initialise logging top component", e);
ErrorManager.getDefault().notify(e);
}
}
return bmp;
}
final int fromPos = editor.getSelectionStart();
final int toPos = editor.getSelectionEnd();
final StyledDocument doc = (StyledDocument)editor.getDocument();
int from = org.openide.text.NbDocument.findLineNumber(doc, fromPos) + 1;
int to = org.openide.text.NbDocument.findLineNumber(doc, toPos) + 1;
if (!(fullName.equals(editedJavaSourceFullPath) && (editedSelectionFrom == from) && (editedSelectionTo
== to))) {
if (fromPos == toPos) {
from = -1;
to = -1;
}
bmp.setSelection(fullName, from, to);
editedJavaSourceFullPath = fullName;
editedSelectionFrom = from;
editedSelectionTo = to;
}
}
public void openJava(
final String fullName,
final int lineNumber) {
final String[] ar = fullName.split("\\.");
final String className = ar[ar.length - 1];
final FileObject fo = findResource(fullName, 0);
if (fo != null) {
openSourceFO(fo);
final EditorCookie ec = TopComponent.getRegistry().getActivatedNodes()[0].getCookie(EditorCookie.class);
JEditorPane editor = null;
if (ec != null) {
final JEditorPane[] panes = ec.getOpenedPanes();
if (panes != null) {
final TopComponent activetc = TopComponent.getRegistry().getActivated();
for (int i = 0; i < panes.length; i++) {
if (activetc.isAncestorOf(panes[i])) {
editor = panes[i];
}
}
}
}
if (editor != null) {
try {
gotoLine(editor, lineNumber);
} catch (Exception ex) {
LOG.warn("cannot goto line: " + lineNumber, ex);
gotoLine(editor, 1);
}
}
}
}
private static void gotoLine(
final JTextComponent txt,
final int line) {
final StyledDocument doc = (StyledDocument)txt.getDocument();
txt.setCaretPosition(0);
int caretPos = 0;
for (; (NbDocument.findLineNumber(doc, caretPos) + 1) < line; ++caretPos) {
}
txt.setCaretPosition(caretPos);
}
private FileObject
findResource(
final String fullName,
int order) {
final HashMap alreadyTested = new HashMap();
final String name = fullName.replace('.', '/') + ".java";
final Set set = GlobalPathRegistry.getDefault().getPaths(ClassPath.SOURCE);
Iterator it = set.iterator();
while (it.hasNext()) {
final ClassPath cp = (ClassPath)it.next();
if (alreadyTested.get(cp) != null) {
continue;
}
alreadyTested.put(cp, cp);
final FileObject fo = cp.findResource(name);
if (fo != null) {
if (order == 0) {
return fo;
} else {
order--;
}
} else {
}
}
final ArrayList<ClassPath> list = new ArrayList<ClassPath>(GlobalPathRegistry.getDefault().getPaths(
ClassPath.COMPILE));
list.addAll(GlobalPathRegistry.getDefault().getPaths(ClassPath.BOOT));
it = list.iterator();
while (it.hasNext()) {
final ClassPath cp = (ClassPath)it.next();
if (alreadyTested.get(cp) != null) {
continue;
}
alreadyTested.put(cp, cp);
final Iterator it2 = cp.entries().iterator();
while (it2.hasNext()) {
final ClassPath.Entry entry = (ClassPath.Entry)it2.next();
final FileObject[] sroots = SourceForBinaryQuery.findSourceRoots(entry.getURL()).getRoots();
final List ll = Arrays.asList(sroots);
if (alreadyTested.get(ll) != null) {
continue;
}
alreadyTested.put(ll, ll);
if (sroots.length > 0) {
final ClassPath sources = ClassPathSupport.createClassPath(sroots);
final FileObject fo = sources.findResource(name);
if (fo != null) {
if (order == 0) {
return fo;
} else {
order--;
}
}
}
}
final FileObject fo = cp.findResource(name);
if (fo != null) {
if (order == 0) {
return fo;
} else {
order--;
}
}
}
return null;
}
DataObject dob;
try {
dob = DataObject.find(fo);
} catch (final DataObjectNotFoundException e) {
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
dob = null;
}
if (dob != null) {
final EditCookie ec = dob.getCookie(EditCookie.class);
if (ec != null) {
ec.edit();
} else {
final OpenCookie oc = dob.getCookie(OpenCookie.class);
if (oc != null) {
oc.open();
} else {
Toolkit.getDefaultToolkit().beep();
}
}
}
}
setLayout(new java.awt.BorderLayout());
}
public static synchronized LoggingTopComponent
getDefault() {
if (instance == null) {
instance = new LoggingTopComponent();
}
return instance;
}
public static synchronized LoggingTopComponent
findInstance() {
final TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
if (win == null) {
ErrorManager.getDefault()
.log(
ErrorManager.WARNING,
"Cannot find Logging component. It will not be located properly in the window system.");
return getDefault();
}
if (win instanceof LoggingTopComponent) {
return (LoggingTopComponent)win;
}
ErrorManager.getDefault()
.log(
ErrorManager.WARNING,
"There seem to be multiple components with the '"
+ PREFERRED_ID
+ "' ID. That is a potential source of errors and unexpected behavior.");
return getDefault();
}
@Override
return TopComponent.PERSISTENCE_ALWAYS;
}
@Override
}
@Override
}
@Override
final Element e = bmp.getAllFilters();
final XMLOutputter xout = new XMLOutputter();
final CharArrayWriter charw = new CharArrayWriter();
String s = "";
try {
xout.output(e, charw);
s = new String(charw.toCharArray());
} catch (final Exception ex) {
LOG.error("cannot write top component", ex);
}
return new ResolvableHelper(s, bmp.getSplitPaneDividerLocation());
}
@Override
return PREFERRED_ID;
}
private JEditorPane editor = null;
private String fullName = "";
this.fullName = fullName;
}
public void setEditor(
final JEditorPane editor) {
this.editor = editor;
}
@Override
fireSelectionChange(editor, fullName);
}
@Override
fireSelectionChange(editor, fullName);
}
@Override
fireSelectionChange(editor, fullName);
}
}
private static final long serialVersionUID = 1L;
private final String storeString;
private final int dividerLocation;
this.storeString = storeString;
if (dividerLocation == 0) {
this.dividerLocation = 30;
} else {
this.dividerLocation = dividerLocation;
}
}
final LoggingTopComponent ltc = LoggingTopComponent.getDefault();
try {
final SAXBuilder sb = new SAXBuilder();
final org.jdom.Document result = sb.build(new StringReader(storeString));
ltc.bmp.setAllFilters(result.getRootElement());
} catch (final Exception ex) {
LOG.error("cannot read top component", ex);
}
ltc.bmp.setSplitPaneDividerLocation(dividerLocation);
return ltc;
}
}
}