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

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

/*******************************************************************************
* Copyright (c) 2005, 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.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportContainer;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.internal.ui.text.java.ProposalContextInformation;
import org.eclipse.jdt.ui.text.java.CompletionProposalCollector;
import org.eclipse.jdt.ui.text.java.CompletionProposalComparator;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jst.jsp.core.internal.java.JSPTranslation;
import org.eclipse.jst.jsp.ui.internal.JSPUIPlugin;
import org.eclipse.jst.jsp.ui.internal.preferences.JSPUIPreferenceNames;
import org.eclipse.swt.graphics.Image;

/**
* Passed into ICodeComplete#codeComplete(int offset, CompletionRequestor requestor).
* Adapts IJavaCompletionProposals to JSPCompletion proposals.
* This includes:
*  - translating offsets
*  - "fixing" up display strings
*  - filtering some unwanted proposals
*
* @plannedfor 1.0
*/
public class JSPProposalCollector extends CompletionProposalCollector {

  private JSPTranslation fTranslation;
  private Comparator fComparator;
  private IImportContainer fImportContainer;

  public JSPProposalCollector(ICompilationUnit cu, JSPTranslation translation) {
    super(cu);
 
    if(translation == null)
      throw new IllegalArgumentException("JSPTranslation cannot be null"); //$NON-NLS-1$
   
    fTranslation = translation;
    fImportContainer = cu.getImportContainer();
  }

  /**
   * Ensures that we only return JSPCompletionProposals.
   * @return an array of JSPCompletionProposals
   */
  public JSPCompletionProposal[] getJSPCompletionProposals() {
    List results = new ArrayList();
    IJavaCompletionProposal[] javaProposals = getJavaCompletionProposals();
    // need to filter out non JSPCompletionProposals
    // because their offsets haven't been translated
    for (int i = 0; i < javaProposals.length; i++) {
      if(javaProposals[i] instanceof JSPCompletionProposal)
        results.add(javaProposals[i]);
    }
    Collections.sort(results, getComparator());
    return (JSPCompletionProposal[])results.toArray(new JSPCompletionProposal[results.size()]);
  }
 
  private Comparator getComparator() {
    if(fComparator == null)
      fComparator = new CompletionProposalComparator();
    return fComparator;
  }
 
  /**
   * Overridden to:
   *  - translate Java -> JSP offsets
   *  - fix cursor-position-after
   *  - fix mangled servlet name in display string
   *  - remove unwanted proposals (servlet constructor)
   */
  protected IJavaCompletionProposal createJavaCompletionProposal(CompletionProposal proposal) {
   
    JSPCompletionProposal jspProposal = null;
   
    // ignore constructor proposals (they're not relevant for our JSP proposal list)
    if(!proposal.isConstructor()) {
      int kind = proposal.getKind();
      if(proposal.getKind() == CompletionProposal.TYPE_REF && JSPUIPlugin.getDefault().getPreferenceStore().getBoolean(JSPUIPreferenceNames.AUTO_IMPORT_INSERT)) {
        String signature = String.valueOf(proposal.getDeclarationSignature());
        String completion = String.valueOf(proposal.getCompletion());
        if(completion.indexOf(signature + ".") != -1) { //$NON-NLS-1$
          jspProposal = createAutoImportProposal(proposal);     
        }
      }
      else if (kind == CompletionProposal.METHOD_REF) {
        jspProposal = createMethodProposal(proposal);
      }
     
      // default behavior
      if(jspProposal == null)
        jspProposal = createJspProposal(proposal);   
    }
    return jspProposal;
  }

  /**
   * Retrieves the type name from the string <code>fullName</code>
   * @param fullName the fully qualified Java name
   * @return the type name
   */
  private String getTypeName(String fullName) {
    int index = fullName.lastIndexOf('.');
    return (index != -1) ? fullName.substring(index + 1) : fullName;
  }

  private JSPCompletionProposal createAutoImportProposal(CompletionProposal proposal) {
   
    JSPCompletionProposal jspProposal = null;

    String completion = new String(proposal.getCompletion());
   
    // it's fully qualified so we should
    // add an import statement
    // create an autoimport proposal
    String newCompletion = getTypeName(completion);
   
    // java offset
    int offset = proposal.getReplaceStart();
    // replacement length
    int length = proposal.getReplaceEnd() - offset;
    // translate offset from Java > JSP
    offset = fTranslation.getJspOffset(offset);
    // cursor position after must be calculated
    int positionAfter = calculatePositionAfter(proposal, newCompletion, offset);
   
    // from java proposal
    IJavaCompletionProposal javaProposal = super.createJavaCompletionProposal(proposal);
    proposal.getDeclarationSignature();
    Image image = javaProposal.getImage();
    String displayString = javaProposal.getDisplayString();
    displayString = getTranslation().fixupMangledName(displayString);
    IContextInformation contextInformation = javaProposal.getContextInformation();
    // don't do this, it's slow
    // String additionalInfo = javaProposal.getAdditionalProposalInfo();
    int relevance = javaProposal.getRelevance();
   
    boolean updateLengthOnValidate = true;
   
    jspProposal = new AutoImportProposal(completion, fImportContainer, newCompletion, offset, length, positionAfter, image, displayString, contextInformation, null, relevance, updateLengthOnValidate);
   
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=124483
    // set wrapped java proposal so additional info can be calculated on demand
    jspProposal.setJavaCompletionProposal(javaProposal);
   
    return jspProposal;
  }

  private JSPCompletionProposal createJspProposal(CompletionProposal proposal) {
   
    JSPCompletionProposal jspProposal;
    String completion = String.valueOf(proposal.getCompletion());
    // java offset
    int offset = proposal.getReplaceStart();
    // replacement length
    int length = proposal.getReplaceEnd() - offset;
    // translate offset from Java > JSP
    offset = fTranslation.getJspOffset(offset);
    // cursor position after must be calculated
    int positionAfter = calculatePositionAfter(proposal, completion, offset);
   
    // from java proposal
    IJavaCompletionProposal javaProposal = super.createJavaCompletionProposal(proposal);
    proposal.getDeclarationSignature();
    Image image = javaProposal.getImage();
    String displayString = javaProposal.getDisplayString();
    displayString = getTranslation().fixupMangledName(displayString);
    IContextInformation contextInformation = javaProposal.getContextInformation();
    // String additionalInfo = javaProposal.getAdditionalProposalInfo();
   
    /* the context information is calculated with respect to the java document
     * thus it needs to be updated in respect of the JSP document.
     */
    if(contextInformation instanceof ProposalContextInformation) {
      ProposalContextInformation proposalInfo = (ProposalContextInformation)contextInformation;
      int contextInfoJSPOffset = fTranslation.getJspOffset(proposalInfo.getContextInformationPosition());
      proposalInfo.setContextInformationPosition(contextInfoJSPOffset);
    }
   
    int relevance = javaProposal.getRelevance();
   
    boolean updateLengthOnValidate = true;
   
    jspProposal = new JSPCompletionProposal(completion, offset, length, positionAfter, image, displayString, contextInformation, null, relevance, updateLengthOnValidate);
   
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=124483
    // set wrapped java proposal so additional info can be calculated on demand
    jspProposal.setJavaCompletionProposal(javaProposal);
   
    return jspProposal;
  }

  private JSPCompletionProposal createMethodProposal(CompletionProposal proposal) {
   
    JSPCompletionProposal jspProposal;
    String completion = String.valueOf(proposal.getCompletion());
    // java offset
    int offset = proposal.getReplaceStart();
    // replacement length
    int length = proposal.getReplaceEnd() - offset;
    // translate offset from Java > JSP
    offset = fTranslation.getJspOffset(offset);
    // cursor position after must be calculated
    int positionAfter = calculatePositionAfter(proposal, completion, offset);
   
    // from java proposal
    IJavaCompletionProposal javaProposal = super.createJavaCompletionProposal(proposal);
    proposal.getDeclarationSignature();
    Image image = javaProposal.getImage();
    String displayString = javaProposal.getDisplayString();
    displayString = getTranslation().fixupMangledName(displayString);
    IContextInformation contextInformation = javaProposal.getContextInformation();
    // String additionalInfo = javaProposal.getAdditionalProposalInfo();
   
    /* the context information is calculated with respect to the java document
     * thus it needs to be updated in respect of the JSP document.
     */
    if(contextInformation instanceof ProposalContextInformation) {
      ProposalContextInformation proposalInfo = (ProposalContextInformation)contextInformation;
      int contextInfoJSPOffset = fTranslation.getJspOffset(proposalInfo.getContextInformationPosition());
      proposalInfo.setContextInformationPosition(contextInfoJSPOffset);
    }
   
    int relevance = javaProposal.getRelevance();
   
    boolean updateLengthOnValidate = true;
   
    jspProposal = new JSPMethodCompletionProposal(proposal, fTranslation.getJavaProject(), completion, offset, length, positionAfter, image, displayString, contextInformation, null, relevance, updateLengthOnValidate);
   
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=124483
    // set wrapped java proposal so additional info can be calculated on demand
    jspProposal.setJavaCompletionProposal(javaProposal);
   
    return jspProposal;
  }

  /**
   * Cacluates the where the cursor should be after applying this proposal.
   * eg. method(|) if the method proposal chosen had params.
   *
   * @param proposal
   * @param completion
   * @param currentCursorOffset
   * @return
   */
  private int calculatePositionAfter(CompletionProposal proposal, String completion, int currentCursorOffset) {
    // calculate cursor position after
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=118398
    //int positionAfter = currentCursorOffset+completion.length();
    int positionAfter = completion.length();
   
    int kind = proposal.getKind();
   
    // may need better logic here...
    // put cursor inside parenthesis if there's params
    // only checking for any kind of declaration
    if(kind == CompletionProposal.ANONYMOUS_CLASS_DECLARATION || kind == CompletionProposal.METHOD_DECLARATION || kind == CompletionProposal.POTENTIAL_METHOD_DECLARATION || kind == CompletionProposal.METHOD_REF) {
      String[] params = Signature.getParameterTypes(String.valueOf(proposal.getSignature()));
      if(completion.length() > 0 && params.length > 0)
        positionAfter--;
    }
    return positionAfter;
  }
 
  static char[] getTypeTriggers() {
    return TYPE_TRIGGERS;
  }

  public JSPTranslation getTranslation() {
    return fTranslation;
  }
 
}
TOP

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

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.