org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2013 THALES GLOBAL SERVICES.
 * 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:
 *    Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.common.ui.tools.internal.interpreter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
import org.eclipse.sirius.common.tools.internal.interpreter.FeatureInterpreter;
import org.eclipse.sirius.common.ui.Messages;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

/**
 * A {@link IProposalProvider} to provide completion for the feature
 * interpreter.
 * 
 * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
 */
public class FeatureProposalProvider implements IProposalProvider {

    private static final String SEPARATOR_1 = ":"; //$NON-NLS-1$

    private static final String SEPARATOR_2 = " - "; //$NON-NLS-1$

    private static final String SEPARATOR_3 = "[0..*]"; //$NON-NLS-1$

    @Override
    public ContentProposal getNewEmtpyExpression() {
        return new ContentProposal(FeatureInterpreter.PREFIX, FeatureInterpreter.PREFIX,
                Messages.FeatureProposalProvider_newFeatureExpression, FeatureInterpreter.PREFIX.length());
    }

    @Override
    public List<ContentProposal> getProposals(IInterpreter interpreter, ContentContext context) {
        final List<ContentProposal> proposals;
        if (context == null || !(interpreter instanceof FeatureInterpreter)) {
            proposals = Collections.emptyList();
        } else if (context.getContents() == null || context.getContents().length() == 0) {
            proposals = Collections.singletonList(getNewEmtpyExpression());
        } else {
            Set<ContentProposal> intersectingProposals = null;
            IInterpreterContext interpreterContext = context.getInterpreterContext();
            for (TypeName type : interpreterContext.getTargetType().getPossibleTypes()) {
                for (EClass possibleEClass : Iterables
                        .filter(type.search(interpreterContext.getAvailableEPackages()), EClass.class)) {
                    Set<ContentProposal> proposalsForThisType = Sets.newLinkedHashSet(
                            getProposals(context.getContents(), context.getPosition(), possibleEClass));
                    if (intersectingProposals == null) {
                        intersectingProposals = proposalsForThisType;
                    } else {
                        intersectingProposals = Sets.intersection(intersectingProposals, proposalsForThisType);
                    }
                }
            }

            if (intersectingProposals != null) {
                proposals = Lists.newArrayList(intersectingProposals);
            } else {
                proposals = Collections.<ContentProposal>emptyList();
            }
        }
        return proposals;
    }

    @Override
    public List<ContentProposal> getProposals(IInterpreter interpreter, ContentInstanceContext context) {
        final List<ContentProposal> proposals;
        if (context == null || !(interpreter instanceof FeatureInterpreter)) {
            proposals = Collections.emptyList();
        } else if (context.getCurrentSelected() == null) {
            proposals = Collections.singletonList(getNewEmtpyExpression());
        } else {
            proposals = getProposals(context.getTextSoFar(), context.getCursorPosition(),
                    context.getCurrentSelected().eClass());
        }
        return proposals;
    }

    /**
     * Evaluates the content proposals for a given expression and returns the
     * result as a list.
     * 
     * @param writtenExpression
     *            The complete expression with feature: prefix.
     * @param cursorPosition
     *            The current cursor position to consider only characters before
     *            it.
     * @param currentElementType
     *            The current element type in the context.
     * @return content proposal list.
     */
    private List<ContentProposal> getProposals(String writtenExpression, int cursorPosition,
            EClass currentElementType) {
        final List<ContentProposal> proposals = new ArrayList<ContentProposal>();

        // Keep only characters before cursor
        String featureNamePrefix = writtenExpression.substring(0, cursorPosition);
        // Remove not needed space characters.
        featureNamePrefix = featureNamePrefix.trim();
        // Remove "feature:" prefix if the cursor position is after the prefix
        // If the cursor position is before the prefix, there is no proposal
        // returned.
        if (featureNamePrefix.length() >= FeatureInterpreter.PREFIX.length()) {
            featureNamePrefix = featureNamePrefix.trim().substring(FeatureInterpreter.PREFIX.length());

            String eObjectName = EObject.class.getSimpleName();

            String eContainerFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[0];
            if (eContainerFeatureName.startsWith(featureNamePrefix)) {
                String displayedName = eContainerFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_2
                        + eObjectName;
                proposals.add(new ContentProposal(eContainerFeatureName, displayedName, displayedName));
            }

            String eContentsFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[1];
            if (eContentsFeatureName.startsWith(featureNamePrefix)) {
                String displayedName = eContentsFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3 + SEPARATOR_2
                        + eObjectName;
                proposals.add(new ContentProposal(eContentsFeatureName, displayedName, displayedName));
            }

            String eAllContentsFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[2];
            if (eAllContentsFeatureName.startsWith(featureNamePrefix)) {
                String displayedName = eAllContentsFeatureName + SEPARATOR_1 + "TreeIterator" + SEPARATOR_2 //$NON-NLS-1$
                        + eObjectName;
                proposals.add(new ContentProposal(eAllContentsFeatureName, displayedName, displayedName));
            }

            String eClassFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[3];
            if (eClassFeatureName.startsWith(featureNamePrefix)) {
                String displayedName = eClassFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3 + SEPARATOR_2
                        + EClass.class.getSimpleName();
                proposals.add(new ContentProposal(eClassFeatureName, displayedName, displayedName));
            }

            String eReferencesFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[4];
            if (eReferencesFeatureName.startsWith(featureNamePrefix)) {
                String displayedName = eReferencesFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3
                        + SEPARATOR_2 + eObjectName;
                proposals.add(new ContentProposal(eReferencesFeatureName, displayedName, displayedName));
            }

            if (currentElementType != null) {
                for (EStructuralFeature eStructuralFeature : currentElementType.getEAllStructuralFeatures()) {
                    if (eStructuralFeature.getName().startsWith(featureNamePrefix)) {
                        String displayedName = eStructuralFeature.getName()
                                + (eStructuralFeature.isMany() ? "[" + eStructuralFeature.getLowerBound() + ".." //$NON-NLS-1$//$NON-NLS-2$
                                        + (eStructuralFeature.getUpperBound() == -1 ? "*" //$NON-NLS-1$
                                                : eStructuralFeature.getUpperBound())
                                        + "]" : "") //$NON-NLS-1$ //$NON-NLS-2$
                                + (eStructuralFeature.getEType() != null
                                        ? SEPARATOR_1 + eStructuralFeature.getEType().getName()
                                        : "") //$NON-NLS-1$
                                + SEPARATOR_2 + eStructuralFeature.getEContainingClass().getName();
                        proposals.add(
                                new ContentProposal(eStructuralFeature.getName(), displayedName, displayedName));
                    }
                }
            }
        }
        return proposals;
    }

}