/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package vizzy.tasks; import java.awt.Desktop; import java.io.File; import java.net.URI; import javax.swing.JTextArea; import javax.swing.text.BadLocationException; import org.apache.log4j.Logger; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import vizzy.model.Conf; import vizzy.model.SettingsModel; import vizzy.model.SourceAndLine; /** * * @author sergeil */ public class HandleWordAtPosition { private static final Logger log = Logger.getLogger(HandleWordAtPosition.class); private final SettingsModel settings; public HandleWordAtPosition(SettingsModel settings) { this.settings = settings; } public JTextArea getTextArea() { return textArea; } public void setTextArea(JTextArea textArea) { this.textArea = textArea; } class MinPositionParam { public String separator; public boolean substract; public MinPositionParam(String keyword, boolean substract) { this.separator = keyword; this.substract = substract; } } public static final String HTTPS_TEMPLATE = "https://"; public static final String HTTP_TEMPLATE = "http://"; public static final String FILE_TEMPLATE = "file:///"; private String customASEditor; private boolean defaultASEditor; private JTextArea textArea; private Object highlight; private final Object lock = new Object(); public boolean findObjectAtPositionAndExecute(int offset) { if (!Desktop.isDesktopSupported()) { return false; } try { if (checkHTTPLink(offset, true) != null) { return true; } } catch (Exception ex) { // log.warn("findObjectAtPositionAndExecute() checkHTTPLink failed", ex); } try { if (checkSourceFile(offset, true) != null) { return true; } } catch (Exception ex) { // log.warn("findObjectAtPositionAndExecute() checkSourceFile failed", ex); } return false; } public void removeHighlight() { synchronized (lock) { try { if (highlight != null) { textArea.getHighlighter().removeHighlight(highlight); highlight = null; } } catch (Exception e) { // log.warn("removeHighlight()", e); } } } public void highlightSourceLine(SourceAndLine source) { removeHighlight(); if (source.startPos > -1) { synchronized (lock) { try { highlight = textArea.getHighlighter().addHighlight(source.startPos, source.startPos + source.filePath.length(), Conf.mouseOverObjectPainter); } catch (BadLocationException ex) { // log.warn("highlightSourceLine()", ex); } } } } public SourceAndLine checkHTTPLink(int offset, boolean executeIfFound) throws Exception { int startIndex; int endIndex; String currentWord; int currentIndex = offset; String text = textArea.getText(); // CHECK FOR HTTP LINK startIndex = getMinPosition(text, currentIndex, new MinPositionParam[]{ new MinPositionParam(HTTPS_TEMPLATE, false), new MinPositionParam(HTTP_TEMPLATE, false), new MinPositionParam(FILE_TEMPLATE, false), new MinPositionParam("\n", true), new MinPositionParam("\r", true), new MinPositionParam(" ", true)}, true); endIndex = getMinPosition(text, currentIndex, new MinPositionParam[]{ new MinPositionParam("\n", true), new MinPositionParam("\r", true), new MinPositionParam("\"", true), new MinPositionParam("'", true), new MinPositionParam("<", true), new MinPositionParam(">", true), new MinPositionParam(")", true), new MinPositionParam(" ", true)}, false); if (endIndex != -1 && startIndex != -1) { currentWord = text.substring(startIndex, endIndex); if (currentWord != null && (currentWord.startsWith(HTTP_TEMPLATE) || currentWord.startsWith(FILE_TEMPLATE))) { SourceAndLine source = new SourceAndLine(currentWord, -1, startIndex); highlightSourceLine(source); if (executeIfFound) { Desktop.getDesktop().browse(new URI(currentWord)); } return source; } } return null; } public SourceAndLine checkSourceFile(int offset, boolean executeIfFound) throws Exception { SourceAndLine source = extractSourceFile(offset, textArea.getText(), textArea.getLineOfOffset(offset), textArea.getLineCount()); if (source == null) { return null; } highlightSourceLine(source); if (executeIfFound) { if (defaultASEditor) { File file = new File(source.filePath); if (file.exists()) { Desktop.getDesktop().open(file); } } else if (customASEditor != null) { String command = customASEditor.replace("%file%", source.filePath).replace("%line%", String.valueOf(source.lineNum)); Runtime.getRuntime().exec(command); } } return source; } public String checkJSON(int offset) throws Exception { String selectedText = textArea.getSelectedText(); if (selectedText == null || selectedText.isEmpty()) { return null; } if (textArea.getSelectionStart() > offset || textArea.getSelectionEnd() < offset) { return null; } JSONObject parse = null; try { parse = (JSONObject) new JSONParser().parse(selectedText); } catch (Exception e) { } if (parse == null) { return null; } JSONObject.inline = 0; String toJSONString = parse.toJSONString(); return toJSONString; } private SourceAndLine extractSourceFile(int currentIndex, String text, int taLineNum, int taTotalLines) { int startIndex; int endIndex; String currentWord; startIndex = getMinPosition(text, currentIndex, new MinPositionParam[]{ new MinPositionParam("\n", true), new MinPositionParam("\r", true)}, true); endIndex = getMinPosition(text, currentIndex, new MinPositionParam[]{ new MinPositionParam("\n", true), new MinPositionParam("\r", true)}, false); if (endIndex == -1 && taLineNum == taTotalLines) { endIndex = text.length() + 10; } if (startIndex == -1 && taLineNum == 0) { startIndex = 0; } if (endIndex != -1 && startIndex != -1 && startIndex < endIndex) { currentWord = text.substring(startIndex, endIndex); // whole line // check stack trace if (currentWord != null && currentWord.startsWith("\tat ") && currentWord.endsWith("]")) { int sIndex = currentWord.indexOf("["); int eIndex = currentWord.lastIndexOf(":"); if (sIndex != -1 && eIndex != -1 && sIndex < eIndex && currentIndex > startIndex + sIndex && currentIndex < startIndex + eIndex) { sIndex = sIndex + 1; String filePath = currentWord.substring(sIndex, eIndex); if (filePath != null) { File file = new File(filePath); if (file.exists()) { int lineNum = Integer.parseInt(currentWord.substring(eIndex + 1, currentWord.length() - 1)); return new SourceAndLine(filePath, lineNum, startIndex + sIndex); } } } } // check Vizzy Plugin if (settings.getSourceLines() != null && settings.getSourceLines().containsKey(taLineNum)) { String debugLine = settings.getSourceLines().get(taLineNum); if (debugLine != null && debugLine.length() > 0) { int openBrace = debugLine.indexOf("["); if (openBrace != -1) { int semiColIndex = debugLine.lastIndexOf(":"); if (semiColIndex != -1) { int closingBrace = debugLine.indexOf("]"); if (closingBrace != -1) { return new SourceAndLine(debugLine.substring(openBrace + 1, semiColIndex).trim(), Integer.parseInt(debugLine.substring(semiColIndex + 1, closingBrace).trim()), -1); } } } } } } return null; } private int getMinPosition(String text, int currentIndex, MinPositionParam[] minPositionParam, boolean left) { int index = -1; for (MinPositionParam param : minPositionParam) { int i; if (left) i = text.lastIndexOf(param.separator, currentIndex); else i = text.indexOf(param.separator, currentIndex); if (i != -1) { if (left) { if (param.substract) i = i + param.separator.length(); if (index == -1) index = i; else if (index < i) index = i; } else { if (index == -1) index = i; else if (index > i) index = i; } } } return index; } public void setCustomASEditor(String customASEditor) { this.customASEditor = customASEditor; } public void setDefaultEditorUsed(boolean defaultASEditor) { this.defaultASEditor = defaultASEditor; } }