Package tk.eclipse.plugin.jseditor.editors

Source Code of tk.eclipse.plugin.jseditor.editors.JavaScriptHyperlinkDetector$JavaScriptHyperlink

package tk.eclipse.plugin.jseditor.editors;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.ide.IGotoMarker;

import tk.eclipse.plugin.htmleditor.HTMLPlugin;
import tk.eclipse.plugin.htmleditor.HTMLProjectParams;
import tk.eclipse.plugin.htmleditor.HTMLUtil;
import tk.eclipse.plugin.jseditor.launch.JavaScriptLibraryTable;

/**
* <code>IHyperlinkDetector</code> for JavaScript.
* <p>
* This detector detects available functions and variables
* at the caret position.
*
* @author Naoki Takezoe
*/
public class JavaScriptHyperlinkDetector implements IHyperlinkDetector {

  /** Functions which are defined in the library files */
  private List<FunctionInfo> functions = new ArrayList<FunctionInfo>();
 
  /**
   * Returns hyperlinks or null.
   */
  public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
      IRegion region, boolean canShowMultipleHyperlinks) {
   
    String source = textViewer.getDocument().get();
    int offset = region.getOffset();
   
    // extracts the word at the caret position
    String word = String.valueOf(source.charAt(offset));
    int index = offset -1;
    while(index >= 0){
      char c = source.charAt(index);
      if(Character.isJavaIdentifierPart(c)){
        word = c + word;
        index--;
      } else {
        break;
      }
    }
    index = offset + 1;
    offset = offset - word.length() + 1;
    while(source.length()>index){
      char c = source.charAt(index);
      if(Character.isJavaIdentifierPart(c)){
        word = word + c;
        index++;
      } else if(c=='('){
        break;
      } else {
        return null;
      }
    }
   
    // itselfs
    JavaScriptModel model = new JavaScriptModel(source);
    JavaScriptContext context = model.getContextFromOffset(offset);
    if(context!=null){
      JavaScriptElement[] children = context.getVisibleElements();
      for(int i=0;i<children.length;i++){
        if(children[i] instanceof JavaScriptFunction){
          JavaScriptFunction function = (JavaScriptFunction)children[i];
          if(children[i].getName().equals(word)){
            IRegion hyperlinkRegion = new Region(offset, word.length());
            return new IHyperlink[]{
                new JavaScriptHyperlink(hyperlinkRegion, textViewer,
                    function.getOffset())
            };
          }
        }
      }
    }
   
    // libraries
    for(int i=0;i<functions.size();i++){
      FunctionInfo info = functions.get(i);
      if(info.function.getName().equals(word)){
        IRegion hyperlinkRegion = new Region(offset, word.length());
        return new IHyperlink[]{
            new JavaScriptHyperlink(hyperlinkRegion, info.resource,
                info.function.getOffset())
        };
      }
    }
   
    return null;
  }
 
  /**
   * Updates internal informations.
   *
   * @param file the editing file
   */
  public void update(IFile file){
    try {
      functions.clear();
     
      HTMLProjectParams params = new HTMLProjectParams(file.getProject());
      String[] javaScripts = params.getJavaScripts();
      IWorkspaceRoot wsroot = ResourcesPlugin.getWorkspace().getRoot();
     
      for(int i=0;i<javaScripts.length;i++){
        InputStream in = null;
        Object obj = null;
        if(javaScripts[i].startsWith(JavaScriptLibraryTable.PREFIX)){
          IResource resource = wsroot.findMember(javaScripts[i].substring(JavaScriptLibraryTable.PREFIX.length()));
          if(resource!=null && resource instanceof IFile && resource.exists()){
            in = ((IFile)resource).getContents();
            obj = resource;
          }
        } else {
          obj = new File(javaScripts[i]);
          in = new FileInputStream(javaScripts[i]);
        }
        String source = new String(HTMLUtil.readStream(in));
        JavaScriptModel model = new JavaScriptModel(source);
        JavaScriptElement[] elements = model.getChildren();
       
        for(int j=0;j<elements.length;j++){
          if(elements[j] instanceof JavaScriptFunction){
            FunctionInfo info = new FunctionInfo();
            info.resource = obj;
            info.function = (JavaScriptFunction)elements[j];
            functions.add(info);
          }
        }
      }
    } catch(Exception ex){
      HTMLPlugin.logException(ex);
    }
  }
 
  /**
   * An internal object to stores <code>JavaScriptFunction</code>
   * and resource which defines them.
   */
  private class FunctionInfo {
    private Object resource;
    private JavaScriptFunction function;
  }
 
  /**
   * <code>IHyperlink</code> implementation to jump the target resource.
   */
  private class JavaScriptHyperlink implements IHyperlink {
   
    private IRegion region;
    private Object resource;
    private int beginOffset;
   
    /**
     * The constructor.
     *
     * @param region the hyperlink region
     * @param resource the target resource
     *   (<code>IFile</code>, <code>ITextViewer</code> or <code>java.io.File</code>)
     * @param beginOffset the begin offset
     */
    public JavaScriptHyperlink(IRegion region, Object resource, int beginOffset){
      this.region = region;
      this.resource = resource;
      this.beginOffset = beginOffset;
    }
   
    public IRegion getHyperlinkRegion() {
      return region;
    }

    public String getTypeLabel() {
      return null;
    }

    public String getHyperlinkText() {
      return null;
    }
   
    /**
     * TODO <code>java.io.File</code> is unsupported.
     */
    public void open() {
      // IFile
      if(resource instanceof IFile){
        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
        try {
          IEditorPart editor = IDE.openEditor(page, (IFile)resource, true);
          IGotoMarker gotoMarker = (IGotoMarker)editor.getAdapter(IGotoMarker.class);
          if(gotoMarker!=null){
            IMarker marker= ((IFile)resource).createMarker(IMarker.TEXT);
            marker.setAttribute(IMarker.CHAR_START, beginOffset);
            marker.setAttribute(IMarker.CHAR_END, beginOffset);
            gotoMarker.gotoMarker(marker);
          }
        } catch (Exception ex) {
          HTMLPlugin.logException(ex);
        }
      }
      if(resource instanceof ITextViewer){
        ((ITextViewer)resource).setSelectedRange(beginOffset, 0);
      }
      // java.io.File (external file)
      if(resource instanceof File){
       
      }
    }
  }

}
TOP

Related Classes of tk.eclipse.plugin.jseditor.editors.JavaScriptHyperlinkDetector$JavaScriptHyperlink

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.