Java tutorial
/******************************************************************************* * 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; } }