Package org.eclipse.jst.jsp.ui.internal.contentassist

Source Code of org.eclipse.jst.jsp.ui.internal.contentassist.JSPELCompletionProposalComputer

/*******************************************************************************
* Copyright (c) 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsp.ui.internal.contentassist;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jst.jsp.core.internal.contentmodel.TaglibController;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.CMDocumentImpl;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TLDCMDocumentManager;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.TaglibTracker;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDFunction;
import org.eclipse.jst.jsp.core.internal.java.JSPTranslation;
import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParserConstants;
import org.eclipse.jst.jsp.core.internal.java.jspel.JSPELParserTokenManager;
import org.eclipse.jst.jsp.core.internal.java.jspel.SimpleCharStream;
import org.eclipse.jst.jsp.core.internal.java.jspel.Token;
import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.internal.Workbench;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer;
import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;

/**
* <p>
* Compute JSP EL completion proposals
* </p>
*/
public class JSPELCompletionProposalComputer extends
    JSPJavaCompletionProposalComputer {

  private String partenerFile = null;
  private ArrayList<String> propList = new ArrayList<String>();
  private ArrayList<String> methodList = new ArrayList<String>();

  /**
   * @see org.eclipse.jst.jsp.ui.internal.contentassist.JSPJavaCompletionProposalComputer#computeCompletionProposals(org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext,
   *      org.eclipse.core.runtime.IProgressMonitor)
   */
  public List computeCompletionProposals(
      CompletionProposalInvocationContext context,
      IProgressMonitor monitor) {

    ITextViewer viewer = context.getViewer();
    int documentPosition = context.getInvocationOffset();

    // get results from JSP completion processor
    // 3 for the "get" at the beginning of the java proposal
    List results = new ArrayList(computeJavaCompletionProposals(viewer,
        documentPosition, 3));

    // get the function proposals for syntax like: ${ fn:| }
    IStructuredDocumentRegion flat = ContentAssistUtils
        .getStructuredDocumentRegion(viewer, documentPosition);
    if (flat != null) {
      ITextRegion cursorRegion = flat
          .getRegionAtCharacterOffset(documentPosition);
      String elText;
      int startOffset = -1;
      // if container then need to get inner region
      // else can use flat region
      if (cursorRegion instanceof ITextRegionContainer) {
        ITextRegionContainer container = (ITextRegionContainer) cursorRegion;
        cursorRegion = container
            .getRegionAtCharacterOffset(documentPosition);
        elText = container.getText(cursorRegion);
        startOffset = container.getStartOffset(cursorRegion);
      } else {
        elText = flat.getText(cursorRegion);
        startOffset = flat.getStartOffset(cursorRegion);
      }

      // sanity check that we are actually in EL region
      if (cursorRegion.getType() == DOMJSPRegionContexts.JSP_EL_CONTENT) {
        String prefix = getPrefix(documentPosition - startOffset,
            elText);
        if (null != prefix) {
          List proposals = getFunctionProposals(prefix, viewer,
              documentPosition);
          results.addAll(proposals);
        }
      }

      // Add Tapestry content assist
      if (startOffset > -1) {
        IEditorPart editorPart = Workbench.getInstance()
            .getActiveWorkbenchWindow().getActivePage()
            .getActiveEditor();
        if (editorPart != null) {
          IFileEditorInput input = (IFileEditorInput) editorPart
              .getEditorInput();
          IFile file = input.getFile();
          String fileName = file.getFullPath().toString();
          if (fileName.endsWith(".tml")) {
            String aimFileName = null;
            String aimNameShort = null;
            IProject activeProject = file.getProject();
            aimFileName = fileName.substring(0,
                fileName.length() - 4) + ".java";
            IResource res = null;
            if (aimFileName.indexOf("/") > -1)
              aimNameShort = aimFileName.substring(aimFileName
                  .lastIndexOf("/") + 1);
            res = activeProject.findMember(aimFileName
                .substring(("/" + activeProject.getName())
                    .length()));
            if (res == null) {
              searchPartenerFile(activeProject, aimNameShort);
              if (this.partenerFile != null) {
                res = activeProject.findMember(partenerFile
                    .substring(("/" + activeProject
                        .getName()).length()));
              }
            }

            if (res != null && res.getType() == IResource.FILE)
              results.addAll(getTapestryPropProposals("", viewer,
                  startOffset, getTapestryImage(),
                  elText.length(), 0, res.getFullPath()));
          }
        }
      }
    }

    return results;
  }

  private void searchPartenerFile(IProject project, String fileName) {
    IResource[] fileList = null;
    try {
      fileList = project.members(false);
      travelAllFolder(fileList, fileName);
    } catch (CoreException e) {
      e.printStackTrace();
    }
  }

  private void travelAllFolder(IResource[] fileList, String fileName)
      throws CoreException {
    for (int i = 0; i < fileList.length; i++) {
      IResource eachFile = fileList[i];
      if (eachFile.getType() == IResource.FILE
          && eachFile.getName().equals(fileName)) {
        this.partenerFile = eachFile.getFullPath().toString();
      } else if (eachFile.getType() == IResource.FOLDER) {
        IFolder file = (IFolder) eachFile;
        travelAllFolder(file.members(), fileName);
      }
    }
  }

  private String extracted(ITextRegion cursorRegion) {
    return cursorRegion.getType();
  }

  /**
   * @see org.eclipse.jst.jsp.ui.internal.contentassist.JSPJavaCompletionProposalComputer#getProposalCollector(org.eclipse.jdt.core.ICompilationUnit,
   *      org.eclipse.jst.jsp.core.internal.java.JSPTranslation)
   */
  protected JSPProposalCollector getProposalCollector(ICompilationUnit cu,
      JSPTranslation translation) {

    return new JSPELProposalCollector(cu, translation);
  }

  /**
   * <p>
   * Gets the EL prefix from the relative position and the given EL text
   * </p>
   *
   * @param relativePosition
   * @param elText
   * @return
   */
  private String getPrefix(int relativePosition, String elText) {
    java.io.StringReader reader = new java.io.StringReader(elText);
    JSPELParserTokenManager scanner = new JSPELParserTokenManager(
        new SimpleCharStream(reader, 1, 1));
    Token curToken = null, lastIdentifier = null;
    while (JSPELParserConstants.EOF != (curToken = scanner.getNextToken()).kind) {
      if (JSPELParserConstants.COLON == curToken.kind
          && curToken.endColumn == relativePosition
          && null != lastIdentifier) {
        return (lastIdentifier.image);
      }

      if (JSPELParserConstants.IDENTIFIER == curToken.kind) {
        lastIdentifier = curToken;
      } else {
        lastIdentifier = null;
      }
    }
    return null;
  }

  /**
   * <p>
   * Get the EL function proposals, ex: ${fn:| }
   * </p>
   *
   * @param prefix
   * @param viewer
   * @param offset
   * @return
   */
  private List getFunctionProposals(String prefix, ITextViewer viewer,
      int offset) {
    TLDCMDocumentManager docMgr = TaglibController
        .getTLDCMDocumentManager(viewer.getDocument());
    ArrayList completionList = new ArrayList();
    if (docMgr == null)
      return null;

    Iterator taglibs = docMgr.getCMDocumentTrackers(offset).iterator();
    while (taglibs.hasNext()) {
      TaglibTracker tracker = (TaglibTracker) taglibs.next();
      if (tracker.getPrefix().equals(prefix)) {
        CMDocumentImpl doc = (CMDocumentImpl) tracker.getDocument();

        List functions = doc.getFunctions();
        for (Iterator it = functions.iterator(); it.hasNext();) {
          TLDFunction function = (TLDFunction) it.next();
          CustomCompletionProposal proposal = new CustomCompletionProposal(
              function.getName() + "()", //$NON-NLS-1$
              offset,
              0,
              function.getName().length() + 1,
              null,
              function.getName()
                  + " - " + function.getSignature(), null, null, 1); //$NON-NLS-1$

          completionList.add(proposal);
        }
      }
    }
    return completionList;
  }

  private Image getTapestryImage() {
    return ImageDescriptor.createFromURL(
        Platform.getBundle("org.eclipse.jst.tapestry.ui").getEntry(
            "icons/tapestry.gif")).createImage();
  }

  private List getTapestryPropProposals(String prefix, ITextViewer viewer,
      int offset, Image image, int replacementLength, int cursorPosition,
      IPath classFile) {
    ArrayList completionList = new ArrayList();
    try {
      propList.clear();
      methodList.clear();
      goThroughClass(inputStream2String(ResourcesPlugin.getWorkspace()
          .getRoot().getFile(classFile).getContents()));
    } catch (CoreException e) {
      e.printStackTrace();
    }
    sortList(propList);
    sortList(methodList);
    for(int i=0; i<propList.size(); i++){
      String prop = propList.get(i);
      CustomCompletionProposal each = new CustomCompletionProposal( "prop:"+prop, offset, replacementLength,replacementLength, image, prop, null,
          "variable "+prop, 1);
      completionList.add(each);
    }
    for(int i=0; i<methodList.size(); i++){
      String method = methodList.get(i);
      CustomCompletionProposal each = new CustomCompletionProposal( "prop:"+method, offset, replacementLength,replacementLength, image, method, null,
          "method "+method, 1);
      completionList.add(each);
    }
    return completionList;
  }

  private void sortList(ArrayList<String> list){
    for(int i=0;i<list.size();i++){
      for(int j=i+1;j<list.size();j++){
        String strI = list.get(i);
        String strJ = list.get(j);
        if(strJ.compareTo(strI) < 0){
          list.set(i, strJ);
          list.set(j, strI);
        }
      }
    }
  }
  private void goThroughClass(String ClassContent) {
    ASTParser parser = ASTParser.newParser(AST.JLS3);
    parser.setSource(ClassContent.toCharArray());
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
    cu.accept(new ASTVisitor() {
      public boolean visit(VariableDeclarationFragment node) {
        SimpleName name = node.getName();
        addIfNotExist(name.toString(),propList);
        return false;
      }

      public boolean visit(MethodDeclaration node){
        SimpleName name = node.getName();
        String methodName = name.toString();
        if(node.getModifiers() == Modifier.PUBLIC && methodName.startsWith("get") && methodName.length()>3){
          String propName = methodName.substring(3).toLowerCase();
          addIfNotExist(propName,propList);
          methodList.add(methodName+"()");
        }
        return false;
      }
    });
  }
 
  private void addIfNotExist(String newItem, List<String> list){
    for(int i=0; i<list.size(); i++)
      if(list.get(i).trim().equals(newItem.trim())){
        return;
      }
    list.add(newItem);
  }

  private String inputStream2String(InputStream ins) {
    String all_content = null;
    try {
      all_content = new String();
      ByteArrayOutputStream outputstream = new ByteArrayOutputStream();
      byte[] str_b = new byte[1024];
      int i = -1;
      while ((i = ins.read(str_b)) > 0) {
        outputstream.write(str_b, 0, i);
      }
      all_content = outputstream.toString();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return all_content;
  }
}
TOP

Related Classes of org.eclipse.jst.jsp.ui.internal.contentassist.JSPELCompletionProposalComputer

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.