Source code file content
incubator / nbplugins / trunk / ahrefhyperlink.revamped / src / com / wp / nbguru / ahrefhyperlink / revamped / OpenThreadImpl.java
Size: 11311 bytes, 1 line
package com.wp.nbguru.ahrefhyperlink.revamped;
// <editor-fold defaultstate="collapsed" desc="Java APIs Imports..">
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JEditorPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.StyledDocument;
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="NetBeans APIs Imports..">
import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.openide.awt.StatusDisplayer;
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.Line;
import org.openide.windows.TopComponent;
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Static Imports..">
import static java.awt.EventQueue.*;
import static org.netbeans.editor.Utilities.*;
import static org.openide.cookies.EditorCookie.Observable;
// </editor-fold>
/**
* Class which implements the second phase of this module, i.e. onClick kind of
* events are handled here.
*
* @author Geertjan Wielenga, Varun Nischal
* @version 1.1
*/
public class OpenThreadImpl implements Runnable {
// <editor-fold defaultstate="collapsed" desc="Variables & Constructor">
private static StyledDocument document;
private static String oldIdentifier;
private String[] args;
private String anchorName;
private final Logger logger =
Logger.getLogger(OpenThreadImpl.class.getName());
private final StatusDisplayer statusBar =
StatusDisplayer.getDefault();
public OpenThreadImpl() {
oldIdentifier = null;
document = null;
args = null;
anchorName = null;
}
private boolean editorFlag = true;
private void setEditorFlag(boolean flag) {
this.editorFlag = flag;
}
// </editor-fold>
/**
*
* @param doc
* @param id
*/
public void assignMembers(Document doc, String id) {
document = (StyledDocument) doc;
oldIdentifier = id;
}
/**
* Implements Runnable Interface to open HTML document in editor,
* if exists..
*/
public void run() {
String newIdentifier;
if (oldIdentifier.indexOf("/") >= 0) {
args = oldIdentifier.split("/");
newIdentifier = args[args.length - 1];
} else {
newIdentifier = oldIdentifier;
}
if (newIdentifier.contains("#")) {
int index = newIdentifier.indexOf("#") + 1;
anchorName = newIdentifier.substring(index);
if (newIdentifier.charAt(0) == '#') {
// Anchor Exists Within Same Webpage...
final JTextComponent editor =
EditorRegistry.lastFocusedComponent();
runInEventDispatchThread(new Runnable() {
public void run() {
setPosition(editor.getDocument());
}
});
} else {
// Anchor Exists In External Webpage...
verifyHyperlinkStatus(newIdentifier);
}
} else {
// Anchor Doesn't Exist...
verifyHyperlinkStatus(newIdentifier);
}
}
/**
* Finds the {@link FileObject} of the referenced HTML file,
* if it has a relative path, also takes care of the
* anchor's presence in identifier. Also, implemented the case
* when such files can't be found.
*
* @return htmlFileObj
*/
private FileObject findDocument() {
FileObject htmlFileObj = null;
// Here we're working out whether we're dealing with a
// relative link or not..
if (oldIdentifier.charAt(0) == '/' || oldIdentifier.contains("\\") ||
oldIdentifier.startsWith("../")) {
htmlFileObj = null;
} else {
final String htmlFileName =
oldIdentifier.split("#")[0];
final FileObject fileObj =
NbEditorUtilities.getFileObject(document);
if (oldIdentifier.contains("/")) {
String fullPath = fileObj.getPath();
try {
URI htmlFileURI = new File(fullPath).toURI();
htmlFileURI = htmlFileURI.resolve(htmlFileName);
final URL htmlFile = htmlFileURI.toURL();
htmlFileObj = URLMapper.findFileObject(htmlFile);
} catch (MalformedURLException exception) {
logger.log(Level.SEVERE, null, exception);
}
} else {
htmlFileObj = fileObj.getParent();
htmlFileObj = htmlFileObj.getFileObject(htmlFileName);
}
}
return htmlFileObj;
}
/**
* This lets you open the editor, basically <code>findHTML()</code>
* and <code>openEditor()</code> were earlier a part of <code>run()</code>
* method, however I have splitted it into various reusable methods.
*
* @param dataObj
*/
private void openEditor(DataObject dataObj) {
final Observable ec = (Observable) dataObj.getCookie(Observable.class);
if (ec != null) {
runInEventDispatchThread(new Runnable() {
public void run() {
final JEditorPane[] panes = ec.getOpenedPanes();
if ((panes != null) && (panes.length > 0)) {
setPosition(panes[0].getDocument());
} else {
ec.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (Observable.PROP_OPENED_PANES.equals(evt.getPropertyName())) {
final JEditorPane[] panes = ec.getOpenedPanes();
if ((panes != null) && (panes.length > 0)) {
setPosition(panes[0].getDocument());
}
ec.removePropertyChangeListener(this);
}
}
});
ec.open();
}
}
});
}
}
/**
* Makes use of {@link NbEditorUtilities} to show the exact line
* of the referred <code>anchorName</code>, or <code>body</code> tag.
*
* @param doc
* @param identifier
*/
private void setPosition(Document doc) {//, String identifier) {
try {
//Gets the content of the document-
String text = doc.getText(0, doc.getLength() - 1);
//Finds starting position of "body" tag..
int index = text.indexOf("<body>");
if (anchorName != null && index > 0) {
if ((index = text.indexOf("<a name=\"" + anchorName + "\">",
index)) < 0) {
index = text.indexOf("<body>");
}
}
if (index > 0) {
NbEditorUtilities.getLine(doc, index,
true).show(Line.SHOW_GOTO);
}
} catch (BadLocationException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
/**
* This basically checks that the identifier present in the hyperlink,
* if the file exists in relative path, then is it open or not?
* If not, then opens it, also takes care of the anchors presence, in the
* <code>newIdentifier</code>.
*
* @param newIdentifier
*/
private void verifyHyperlinkStatus(String newIdentifier) {
try {
//<editor-fold desc="Verfying Status...">
final Set<TopComponent> setOfWindows =
TopComponent.getRegistry().getOpened();
final TopComponent[] windows =
setOfWindows.toArray(new TopComponent[0]);
for (int pos = 0; pos < windows.length; pos++) {
final EditorCookie editor =
windows[pos].getLookup().lookup(EditorCookie.class);
if (editor != null) {
DataObject dataObj =
windows[pos].getLookup().lookup(DataObject.class);
if (dataObj != null) {
final FileObject fileObj = dataObj.getPrimaryFile();
final String[] hyperLink = newIdentifier.split("#");
if (hyperLink[0].equals(fileObj.getNameExt())) {
invokeAndWait(new Runnable() {
public void run() {
JEditorPane[] panes =
editor.getOpenedPanes();
if (hyperLink.length <= 1) {
anchorName = null;
}
if (panes != null) {
setPosition(panes[0].getDocument());
setEditorFlag(false);
}
}
});
if (editorFlag == false) {
break;
}
}
}
}
}
//</editor-fold>
if (editorFlag) {
try {
FileObject htmlFileObj = findDocument();
if (htmlFileObj != null) {
DataObject dataObj = DataObject.find(htmlFileObj);
// Open HTML Editor..
openEditor(dataObj);
} else {
// Handle HTML File Not Found..
statusBar.setStatusText("Either file doesn't exist, " +
"or it can't be found...");
}
} catch (DataObjectNotFoundException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
} catch (InterruptedException ex) {
logger.log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
}





