Package org.springframework.ide.eclipse.beans.ui.editor.util

Source Code of org.springframework.ide.eclipse.beans.ui.editor.util.BeansJavaCompletionUtils

/*******************************************************************************
* Copyright (c) 2007, 2013 Spring IDE Developers
* 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:
*     Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.beans.ui.editor.util;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.corext.util.TypeFilter;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal;
import org.eclipse.jdt.internal.ui.text.java.LazyJavaCompletionProposal;
import org.eclipse.jdt.internal.ui.text.java.LazyJavaTypeCompletionProposal;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.text.java.CompletionProposalComparator;
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.IContentAssistContext;
import org.springframework.ide.eclipse.beans.ui.editor.contentassist.IContentAssistProposalRecorder;
import org.springframework.ide.eclipse.core.SpringCore;
import org.springframework.ide.eclipse.core.java.JdtUtils;

/**
* Utility class provides methods to trigger content assist for package and class content assist requests.
* @author Christian Dupuis
* @author Torsten Juergeleit
* @since 1.3.6
*/
@SuppressWarnings("restriction")
public class BeansJavaCompletionUtils {

  public static final int FLAG_INTERFACE = 1 << 2;

  public static final int FLAG_CLASS = 1 << 3;

  public static final int FLAG_PACKAGE = 1 << 4;

  private static final String CLASS_NAME = "_xxx";

  private static final String CLASS_SOURCE_END = "\n" + "    }\n" + "}";

  private static final String CLASS_SOURCE_START = "public class " + CLASS_NAME + " {\n"
      + "    public void main(String[] args) {\n" + "        ";

  private static CompletionProposalComparator COMPARATOR = new CompletionProposalComparator();

  private static ILabelProvider JAVA_LABEL_PROVIDER = new JavaElementLabelProvider(
      JavaElementLabelProvider.SHOW_DEFAULT | JavaElementLabelProvider.SHOW_POST_QUALIFIED);

  /**
   * Add class and package content assist proposals that match the given <code>prefix</code>.
   */
  public static void addClassValueProposals(IContentAssistContext context, IContentAssistProposalRecorder recorder) {
    addClassValueProposals(context, recorder, FLAG_PACKAGE | FLAG_CLASS);
  }

  /**
   * Add interface content assist proposals that match the given <code>prefix</code>.
   */
  public static void addInterfaceValueProposals(IContentAssistContext context, IContentAssistProposalRecorder recorder) {
    addClassValueProposals(context, recorder, FLAG_PACKAGE | FLAG_INTERFACE);
  }

  /**
   * Add package content assist proposals that match the given <code>prefix</code>.
   */
  public static void addPackageValueProposals(IContentAssistContext context, IContentAssistProposalRecorder recorder) {
    addClassValueProposals(context, recorder, FLAG_PACKAGE);
  }

  /**
   * Add class and package content assist proposals that match the given <code>prefix</code>.
   */
  public static void addClassValueProposals(IContentAssistContext context, IContentAssistProposalRecorder recorder,
      int flags) {
    String prefix = context.getMatchString();

    if (prefix == null || prefix.length() == 0) {
      return;
    }

    try {
      IFile file = context.getFile();
      if (file != null && file.exists()) {
        ICompilationUnit unit = createSourceCompilationUnit(file, prefix);
 
        char enclosingChar = (prefix.lastIndexOf('$') > 0 ? '$' : '.');
        prefix = prefix.replace('$', '.');
 
        // Code completion below only provides public and protected inner classes; therefore
        // we manually add the private inner classes if possible
        if (prefix.lastIndexOf('.') > 0) {
          String rootClass = prefix.substring(0, prefix.lastIndexOf('.'));
          IType type = JdtUtils.getJavaType(file.getProject(), rootClass);
          if (type != null) {
            for (IType innerType : type.getTypes()) {
              if (Flags.isPrivate(innerType.getFlags())
                  && innerType.getFullyQualifiedName('.').startsWith(prefix)) {
                recorder.recordProposal(JAVA_LABEL_PROVIDER.getImage(innerType), 10, JAVA_LABEL_PROVIDER
                    .getText(innerType), innerType.getFullyQualifiedName(enclosingChar), innerType);
              }
            }
          }
        }
 
        String sourceStart = CLASS_SOURCE_START + prefix;
        String packageName = null;
        int dot = prefix.lastIndexOf('.');
        if (dot > -1) {
          packageName = prefix.substring(0, dot);
          sourceStart = "package " + packageName + ";\n" + sourceStart;
        }
        String source = sourceStart + CLASS_SOURCE_END;
        setContents(unit, source);
 
        BeansJavaCompletionProposalCollector collector = new BeansJavaCompletionProposalCollector(unit, flags);
        unit.codeComplete(sourceStart.length(), collector, DefaultWorkingCopyOwner.PRIMARY);
 
        IJavaCompletionProposal[] props = collector.getJavaCompletionProposals();
 
        ICompletionProposal[] proposals = order(props);
        for (ICompletionProposal comProposal : proposals) {
          processJavaCompletionProposal(recorder, comProposal, packageName, enclosingChar);
        }
      }
    }
    catch (Exception e) {
      // do nothing
    }
  }

  /**
   * Add class assist proposals that match the given <code>prefix</code> and are part of the sub class hierarchy of
   * the given <code>typeName</code>.
   * @param request the {@link ContentAssistRequest} to add the proposals
   * @param prefix the prefix
   * @param typeName the super class of the request proposals
   */
  public static void addTypeHierachyAttributeValueProposals(IContentAssistContext context,
      IContentAssistProposalRecorder recorder, String typeName, int flags) {
    final String prefix = context.getMatchString();
    if (prefix == null || prefix.length() == 0) {
      return;
    }

    IFile file = context.getFile();
    if (file != null && file.exists()) {
      IType type = JdtUtils.getJavaType(file.getProject(), typeName);
      try {
        if (type != null && file.getProject().hasNature(JavaCore.NATURE_ID)) {
 
          // Make sure that JDT's type filter preferences are applied
          if (!TypeFilter.isFiltered(type)) {
            ITypeHierarchy hierachy = type.newTypeHierarchy(JavaCore.create(file.getProject()),
                new NullProgressMonitor());
            IType[] types = hierachy.getAllSubtypes(type);
            Map<String, IType> sortMap = new HashMap<String, IType>();
            for (IType foundType : types) {
              if ((foundType.getFullyQualifiedName().startsWith(prefix) || foundType.getElementName()
                  .startsWith(prefix))
                  && !sortMap.containsKey(foundType.getFullyQualifiedName())
                  && !Flags.isAbstract(foundType.getFlags())) {
 
                boolean accepted = false;
                if ((flags & BeansJavaCompletionUtils.FLAG_CLASS) != 0
                    && !Flags.isInterface(foundType.getFlags())) {
                  accepted = true;
                }
                else if ((flags & BeansJavaCompletionUtils.FLAG_INTERFACE) != 0
                    && Flags.isInterface(foundType.getFlags())) {
                  accepted = true;
                }
                if (accepted) {
                  recorder.recordProposal(JavaPluginImages.get(JavaPluginImages.IMG_OBJS_CLASS), 10,
                      foundType.getElementName() + " - "
                          + foundType.getPackageFragment().getElementName(), foundType
                          .getFullyQualifiedName(), foundType);
                  sortMap.put(foundType.getFullyQualifiedName(), foundType);
                }
              }
            }
          }
        }
      }
      catch (JavaModelException e) {
      }
      catch (CoreException e) {
      }
    }
  }

  @SuppressWarnings("deprecation")
  private static ICompilationUnit createSourceCompilationUnit(IFile file, String prefix) throws JavaModelException {
    IProgressMonitor progressMonitor = BeansEditorUtils.getProgressMonitor();
    IJavaProject project = JavaCore.create(file.getProject());
    IPackageFragment root = getPackageFragment(project, prefix);
    ICompilationUnit unit = root.getCompilationUnit("_xxx.java").getWorkingCopy(
        CompilationUnitHelper.getInstance().getWorkingCopyOwner(),
        CompilationUnitHelper.getInstance().getProblemRequestor(), progressMonitor);
    progressMonitor.done();
    return unit;
  }

  private static IPackageFragment getPackageFragment(IJavaProject project, String prefix) throws JavaModelException {
    int dot = prefix.lastIndexOf('.');
    if (dot > -1) {
      String packageName = prefix.substring(0, dot);
      for (IPackageFragmentRoot root : project.getPackageFragmentRoots()) {
        IPackageFragment p = root.getPackageFragment(packageName);
        if (p != null && p.exists()) {
          return p;
        }
      }
      IPackageFragment[] packages = project.getPackageFragments();
      for (IPackageFragment p : packages) {
        if (p.getElementName().equals(packageName))
          return p;
      }
    }
    else {
      for (IPackageFragmentRoot p : project.getAllPackageFragmentRoots()) {
        if (p.getKind() == IPackageFragmentRoot.K_SOURCE) {
          return p.getPackageFragment("");
        }
      }
    }
    return project.getPackageFragments()[0];
  }

  /**
   * Order the given proposals.
   */
  @SuppressWarnings("unchecked")
  private static ICompletionProposal[] order(ICompletionProposal[] proposals) {
    Arrays.sort(proposals, COMPARATOR);
    return proposals;
  }

  private static void processJavaCompletionProposal(IContentAssistProposalRecorder recorder,
      ICompletionProposal comProposal, String packageName, char enclosingChar) {
    if (comProposal instanceof JavaCompletionProposal) {
      JavaCompletionProposal prop = (JavaCompletionProposal) comProposal;
      recorder.recordProposal(prop.getImage(), prop.getRelevance(), prop.getDisplayString(), prop
          .getReplacementString(), prop.getJavaElement());
    }
    else if (comProposal instanceof LazyJavaTypeCompletionProposal) {
      LazyJavaTypeCompletionProposal prop = (LazyJavaTypeCompletionProposal) comProposal;

      if (prop.getQualifiedTypeName().equals(packageName + "." + CLASS_NAME)
          || prop.getQualifiedTypeName().equals(CLASS_NAME)) {
        return;
      }

      if (prop.getJavaElement() instanceof IType) {
        // Make sure that JDT's type filter preferences are applied
        if (TypeFilter.isFiltered((IType) prop.getJavaElement())) {
          return;
        }

        String replacementString = ((IType) prop.getJavaElement()).getFullyQualifiedName(enclosingChar);

        recorder.recordProposal(prop.getImage(), prop.getRelevance(), prop.getDisplayString(),
            replacementString, prop.getJavaElement());
      }
    }
    else if (comProposal instanceof LazyJavaCompletionProposal) {
      LazyJavaCompletionProposal prop = (LazyJavaCompletionProposal) comProposal;
      recorder.recordProposal(prop.getImage(), prop.getRelevance(), prop.getDisplayString(), prop
          .getReplacementString(), prop.getJavaElement());
    }
  }

  /**
   * Set contents of the compilation unit to the translated jsp text.
   * @param the ICompilationUnit on which to set the buffer contents
   */
  private static void setContents(ICompilationUnit cu, String source) {
    if (cu == null)
      return;

    synchronized (cu) {
      IBuffer buffer;
      try {

        buffer = cu.getBuffer();
      }
      catch (JavaModelException e) {
        SpringCore.log(e);
        buffer = null;
      }

      if (buffer != null)
        buffer.setContents(source);
    }
  }

}
TOP

Related Classes of org.springframework.ide.eclipse.beans.ui.editor.util.BeansJavaCompletionUtils

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.