Package org.eclipse.jst.jsf.core.internal.contentassist.el

Source Code of org.eclipse.jst.jsf.core.internal.contentassist.el.FunctionCompletionStrategy

/*******************************************************************************
* Copyright (c) 2006 Oracle Corporation.
* 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:
*    Cameron Bateman/Oracle - initial API and implementation
*
********************************************************************************/
package org.eclipse.jst.jsf.core.internal.contentassist.el;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.symbol.IMethodSymbol;
import org.eclipse.jst.jsf.context.symbol.IObjectSymbol;
import org.eclipse.jst.jsf.context.symbol.ISymbol;
import org.eclipse.jst.jsf.context.symbol.provider.IContentProposalProvider;
import org.eclipse.jst.jsf.context.symbol.provider.ProposalCreationFactoryAdapter;
import org.eclipse.jst.jsf.context.symbol.provider.IContentProposalProvider.IProposalCreationFactory;
import org.eclipse.jst.jsf.designtime.resolver.ISymbolContextResolver;
import org.eclipse.jst.jsf.designtime.resolver.StructuredDocumentSymbolResolverFactory;
import org.eclipse.jst.jsp.core.internal.regions.DOMJSPRegionContexts;
import org.eclipse.swt.graphics.Image;

/**
* A completion strategy for function completions like:
*
* v a r .
*        ^
*
* @author cbateman
*
*/
public class FunctionCompletionStrategy extends ContentAssistStrategy
{
    /**
     * @param value
     * @param proposalStart
     */
    public FunctionCompletionStrategy(final String value, final String proposalStart)
    {
        super(ContentAssistStrategy.PREFIX_TYPE_DOT_COMPLETION, value, proposalStart);
    }

    @Override
  public List<ICompletionProposal> getProposals(final IStructuredDocumentContext context)
    {
        List<ICompletionProposal> completionList = Collections.EMPTY_LIST;
        final ISymbolContextResolver  symbolResolver =
            StructuredDocumentSymbolResolverFactory.getInstance().
                getSymbolContextResolver(context);

        final ISymbol symbol = SymbolResolveUtil.getSymbolForVariableSuffixExpr(context, getValue(), false);

        // if we get a completion symbol, get it's proposals
        if (symbol instanceof IObjectSymbol)
        {
            final List expectedMethodBindings = new ArrayList();
            final ISymbol[] suffixes = getSymbols((IObjectSymbol) symbol,
                                             context,
                                             symbolResolver,
                                             expectedMethodBindings);

            final ComposedAdapterFactory factory =
                new ComposedAdapterFactory(
                       ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
            final IProposalCreationFactory  creationInfo =
                new MyProposalFactory(context, getProposalStart().length(),
                                        expectedMethodBindings);
           
            completionList = new ArrayList<ICompletionProposal>();
            for (final ISymbol propSymbol : suffixes) {
                final Object  provider =
                  factory.adapt(propSymbol, IContentProposalProvider.class);

                if (provider instanceof IContentProposalProvider)
                {
                    final ICompletionProposal[] proposal  =
                        ((IContentProposalProvider) provider).
                            getProposals(propSymbol, creationInfo);
                    if (proposal != null)
                    {
                      addProposalsMatchingProposalStart(completionList,
                proposal);
                    }
                }
            }
        }

        return Collections.unmodifiableList(completionList);
    }

  private ISymbol[] getSymbols(final IObjectSymbol symbol,
                                 final IStructuredDocumentContext context,
                                 final ISymbolContextResolver  symbolResolver,
                                 final List   expectedMethodBindings)
    {
        final List symbols = new ArrayList();

        if (SymbolResolveUtil.isMethodBindingExpected(context, expectedMethodBindings))
        {
            symbols.addAll(Arrays.asList(
                          symbolResolver.getMethods(symbol)));
        }

        symbols.addAll(Arrays.asList(symbolResolver.getProperties(symbol)));

        return (ISymbol[]) symbols.toArray(ISymbol.EMPTY_SYMBOL_ARRAY);
    }

    private static class MyProposalFactory extends ProposalCreationFactoryAdapter
    {
        private final static int   DEFAULT_RELEVANCE = 1;

        private final static int   HIGH_RELEVANCE = 2;
        private final static int   NORMAL_RELEVANCE = 1;
        private final static int   LOW_RELEVANCE = 0;

        private final List                         _expectedMethodBindings;
        private final IStructuredDocumentContext   _context;

        /**
         * @param context
         * @param replacementLength
         * @param expectedMethodBindings
         */
        public MyProposalFactory(final IStructuredDocumentContext context, final int replacementLength,
                                    final List expectedMethodBindings) {
            super(context.getDocumentPosition() - replacementLength, replacementLength);
            _context = context;
            _expectedMethodBindings = expectedMethodBindings;
        }

        @Override
    public ICompletionProposal createProposal(final String replacementText,
                                                  final String displayText,
                                                  final String additionalText,
                                                  final Image displayImage,
                                                  final Object target)
        {
            int replacementOffset = _replacementOffset;
            int replacementLength = _replacementLength;

            // TODO: I regard this as a bit of hack, but until we write our
            // proposal implementation, it's basically the only way I can
            // see to do this
            // if it's an array, we must check if we need to replace a
            // preceding '.'
            if (replacementText.startsWith("[")) //$NON-NLS-1$
            {
                ITextRegionContextResolver textResolver =
                    IStructuredDocumentContextResolverFactory.INSTANCE.getTextRegionResolver(_context);

                if (textResolver.getRegionType().equals(DOMJSPRegionContexts.JSP_VBL_CLOSE))
                {
                    textResolver =
                        IStructuredDocumentContextResolverFactory.
                            INSTANCE.getTextRegionResolver(textResolver.getPreviousContext());
                }

                final String regionText = textResolver.getRegionText();
                final int regionStart = textResolver.getStartOffset();

                if (DOMJSPRegionContexts.JSP_VBL_CONTENT.equals(textResolver.getRegionType())
                        && regionText != null
                        && regionStart != -1
                        && regionStart < _context.getDocumentPosition())
                {
                    final int  relativeOffset = _context.getDocumentPosition() - regionStart - 1;

                    if (regionText.charAt(relativeOffset) == '.')
                    {
                        // we must replace a length of 1 (the dot)
                        // at an offset on prior
                        replacementOffset--;
                        replacementLength = 1;
                    }
                }
            }

            return createDefaultProposal(replacementText,
                                         replacementOffset,
                                         replacementLength,
                                         replacementText.length(),
                                         displayImage,
                                         displayText,
                                         null,
                                         additionalText,
                                         getRelevance(target, DEFAULT_RELEVANCE));
        }

        private int getRelevance(final Object target, final int defaultRelevance)
        {
            // if method bindings are expected, then list exact signature
            // matches top most.  Still list non-matching methods, but put
            // them at the bottom
            if (_expectedMethodBindings.size() > 0)
            {
                if (target instanceof IMethodSymbol)
                {
                    final IMethodSymbol methodSymbol = (IMethodSymbol) target;

                    for (final Iterator it = _expectedMethodBindings.iterator();
                            it.hasNext();)
                    {
                        final String methodType = (String) it.next();

                        // we have a match, so push to the top
                        if (methodType.equals(methodSymbol.getSignature()))
                        {
                            return HIGH_RELEVANCE;
                        }
                    }

                    // if we get out of the loop, then this method doesn't
                    // match the expected signature
                    return LOW_RELEVANCE;
                }

                // non-method targets have normal relevance when mb expected
                return NORMAL_RELEVANCE;
            }

            // otherwise, simply return the default for all
            return defaultRelevance;
        }
    }
}
TOP

Related Classes of org.eclipse.jst.jsf.core.internal.contentassist.el.FunctionCompletionStrategy

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.