/***************************************************************************** * Copyright (c) 2010 CEA LIST. * * * 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: * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.textedit.parameter.xtext.ui.contentassist; import java.util.ArrayList; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.papyrus.uml.textedit.common.xtext.umlCommon.TypeRule; import org.eclipse.papyrus.uml.textedit.parameter.xtext.ui.contributions.UMLParameterEditorUtil; import org.eclipse.papyrus.uml.textedit.parameter.xtext.umlParameter.ModifierSpecification; import org.eclipse.papyrus.uml.textedit.parameter.xtext.umlParameter.ModifiersRule; import org.eclipse.papyrus.uml.textedit.parameter.xtext.umlParameter.ParameterRule; import org.eclipse.uml2.uml.Namespace; import org.eclipse.uml2.uml.Type; import org.eclipse.xtext.Assignment; import org.eclipse.xtext.Keyword; import org.eclipse.xtext.RuleCall; import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext; import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor; /** * see http://www.eclipse.org/Xtext/documentation/latest/xtext.html#contentAssist on how to customize content assistant */ public class UmlParameterProposalProvider extends AbstractUmlParameterProposalProvider { /** * Provides custom completion for the specifying the type of a {@link Parameter} * * @param model * @param assignment * @param context * @param acceptor */ @Override public void completeParameterRule_Type(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { // the customization consists in proposing nothing. Proposals are handled by other methods. List<Type> allType = new ArrayList<Type>(); allType.addAll(getRecursivelyOwnedType(getModel())); allType.addAll(getRecursivelyImportedType(getModel())); for(Type c : allType) { if(c.getName().contains(context.getPrefix())) { String displayString = c.getQualifiedName(); String completionString = UMLParameterEditorUtil.getTypeLabel(c, getModel()); ICompletionProposal completionProposal = createCompletionProposalWithReplacementOfPrefix(c, completionString, displayString, context); acceptor.accept(completionProposal); } } completeRuleCall(((RuleCall)assignment.getTerminal()), context, acceptor); } /** * * @see org.eclipse.papyrus.uml.textedit.common.xtext.ui.contentassist.UmlCommonProposalProvider#completeTypeRule_Type(org.eclipse.emf.ecore.EObject, * org.eclipse.xtext.Assignment, org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext, * org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor) * * @param model * @param assignment * @param context * @param acceptor */ @Override public void completeTypeRule_Type(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { if(!(model instanceof ParameterRule)) { return; } else { super.completeTypeRule_Type(model, assignment, context, acceptor); } } /** * * @see org.eclipse.papyrus.uml.textedit.parameter.xtext.ui.contentassist.AbstractUmlParameterProposalProvider#complete_MultiplicityRule(org.eclipse.emf.ecore.EObject, * org.eclipse.xtext.RuleCall, org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext, * org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor) * * @param model * @param ruleCall * @param context * @param acceptor */ @Override public void complete_MultiplicityRule(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { //we complete the multiplicity only when a type is specified if(model instanceof ParameterRule) { if(!typeExists((ParameterRule)model)) { return; } } super.complete_MultiplicityRule(model, ruleCall, context, acceptor); } /** * Provides custom completion for keywords, in the context of "modifiers" specification * * @see org.eclipse.xtext.ui.editor.contentassist.AbstractJavaBasedContentProposalProvider#completeKeyword(org.eclipse.xtext.Keyword, * org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext, org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor) */ @Override public void completeKeyword(Keyword keyword, ContentAssistContext contentAssistContext, ICompletionProposalAcceptor acceptor) { // TODO Auto-generated method stub EObject model = contentAssistContext.getCurrentModel(); if(!(model instanceof ModifiersRule)) { if(model instanceof ParameterRule) { if("::".equals(keyword.getValue())) {// :: is proposed only if the Type is a Namespace and if this namespace contains possible element to type the parameter //$NON-NLS-1$ TypeRule typeRule = ((ParameterRule)model).getType(); Type type = null; if(typeRule != null) { type = typeRule.getType(); } if(type != null && typeExists((ParameterRule)model)) { if(type instanceof Namespace) { List<Type> includedType = getRecursivelyOwnedType((Namespace)type); includedType.addAll(getRecursivelyImportedType((Namespace)type)); if(includedType.isEmpty()) { return; } } } } else if("[".equals(keyword.getValue())) { //$NON-NLS-1$ if(!typeExists((ParameterRule)model)) { return; } } else if("]".equals(keyword.getValue())) { //$NON-NLS-1$ if(!typeExists((ParameterRule)model)) { return; } } else if("{".equals(keyword.getValue())) { //$NON-NLS-1$ if(!typeExists((ParameterRule)model)) { return; } } } super.completeKeyword(keyword, contentAssistContext, acceptor); return; } ModifiersRule modifiersRule = (ModifiersRule)model; boolean isOrdered = false; boolean isException = false; boolean isStream = false; boolean isUnique = false; for(ModifierSpecification spec : modifiersRule.getValues()) { if(spec.getValue() != null) { switch(spec.getValue()) { case ORDERED: isOrdered = true; break; case EXCEPTION: isException = true; break; case STREAM: isStream = true; break; case UNIQUE: isUnique = true; break; default: break; } } } String value = keyword.getValue(); if(value.equals("ordered")) { //$NON-NLS-1$ if(!isOrdered) super.completeKeyword(keyword, contentAssistContext, acceptor); } else if(value.equals("exception")) { //$NON-NLS-1$ if(!isException) super.completeKeyword(keyword, contentAssistContext, acceptor); } else if(value.equals("unique")) { //$NON-NLS-1$ if(!isUnique) super.completeKeyword(keyword, contentAssistContext, acceptor); } else if(value.equals("stream")) { //$NON-NLS-1$ if(!isStream) super.completeKeyword(keyword, contentAssistContext, acceptor); } else super.completeKeyword(keyword, contentAssistContext, acceptor); } /** * Tests if the type of the {@link ParameterRule} is set * * @param parameterRule * ( a {@link ParameterRule}) to complete) * @return * <code>true</code> if the type of the parameter is specified, <code>false</code> if not */ protected boolean typeExists(ParameterRule parameterRule) { if(parameterRule instanceof ParameterRule) { ParameterRule currentModel = parameterRule; TypeRule ruleType = currentModel.getType(); if(ruleType == null) { return true; //<Undefined> } Type type = ruleType.getType(); if(type == null) { return false; } if(type.eContainer() == null && type.getName() == null) { return false; } } return true; } }