/***************************************************************************** * 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: * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.uml.tools.extendedtypes.providers; import java.util.List; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.transaction.util.TransactionUtil; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.common.core.command.CompositeCommand; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.gmf.runtime.common.core.command.UnexecutableCommand; import org.eclipse.gmf.runtime.common.core.service.AbstractProvider; import org.eclipse.gmf.runtime.common.core.service.IOperation; import org.eclipse.gmf.runtime.emf.type.core.EditHelperContext; import org.eclipse.gmf.runtime.emf.type.core.IClientContext; import org.eclipse.gmf.runtime.emf.type.core.commands.EditElementCommand; import org.eclipse.gmf.runtime.emf.type.core.requests.AbstractEditCommandRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest; import org.eclipse.papyrus.infra.extendedtypes.ActionConfiguration; import org.eclipse.papyrus.infra.extendedtypes.providers.GetAllExtendedElementTypeActionProvidersOperation; import org.eclipse.papyrus.infra.extendedtypes.providers.GetExtendedElementTypeActionProviderOperation; import org.eclipse.papyrus.infra.extendedtypes.providers.IExtendedElementTypeActionProvider; import org.eclipse.papyrus.uml.tools.extendedtypes.Activator; import org.eclipse.papyrus.uml.tools.extendedtypes.applystereotypeactionconfiguration.ApplyStereotypeActionConfiguration; import org.eclipse.papyrus.uml.tools.extendedtypes.applystereotypeactionconfiguration.StereotypeToApply; import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.Profile; import org.eclipse.uml2.uml.Stereotype; /** * Provider for Action that applies stereotypes to an element on creation */ public class ApplyStereotypeActionProvider extends AbstractProvider implements IExtendedElementTypeActionProvider { /** * {@inheritDoc} */ public boolean provides(IOperation operation) { if(operation instanceof GetAllExtendedElementTypeActionProvidersOperation) { return true; } if(operation instanceof GetExtendedElementTypeActionProviderOperation) { return (((GetExtendedElementTypeActionProviderOperation)operation).getActionConfiguration() instanceof ApplyStereotypeActionConfiguration); } return false; } /** * {@inheritDoc} */ public ICommand getICommand(List<? extends Object> elementsToEdit, ActionConfiguration configuration) { // try to create the command that will apply the stereotypes if(!(configuration instanceof ApplyStereotypeActionConfiguration)) { Activator.INSTANCE.log("Trying to configure a stereotype action configuration with a configuration which is not a stereotype one: " + configuration); return UnexecutableCommand.INSTANCE; } CompositeCommand compositeCommand = new CompositeCommand("Apply Stereotypes"); ApplyStereotypeActionConfiguration stereotypeActionConfiguration = (ApplyStereotypeActionConfiguration)configuration; // for each object in the list of eobjects to edit, create the stereotype apply command for(Object objectToEdit : elementsToEdit) { if(objectToEdit instanceof Element) { //1. retrieve the list of stereotypes for(StereotypeToApply stereotypeToApply : stereotypeActionConfiguration.getStereotypesToApply()) { String qualifiedName = stereotypeToApply.getStereotypeQualifiedName(); ICommand command = new ApplyStereotypeCommand((Element)objectToEdit, new ApplyStereotypeRequest(TransactionUtil.getEditingDomain(objectToEdit), (Element)objectToEdit, qualifiedName)); compositeCommand.add(command); } } else { Activator.INSTANCE.log("Impossible to cast the element to edit into an Element, trying to apply a stereotype on it"); } } return compositeCommand; } /** * {@inheritDoc} */ public ICommand getBeforeCreateValidationCommand(List<? extends Object> elementsToEdit, ActionConfiguration configuration) { // here, element to edit should be the parent of the created element on which the stereotype is applied. ApplyStereotypeActionConfiguration stereotypeActionConfiguration = (ApplyStereotypeActionConfiguration)configuration; for(Object objectToEdit : elementsToEdit) { for(StereotypeToApply stereotypeToApply : stereotypeActionConfiguration.getStereotypesToApply()) { // compare this list to accessible profiles from container. if(objectToEdit instanceof Element) { Element elementToEdit = ((Element)objectToEdit); org.eclipse.uml2.uml.Package ownerPackage = elementToEdit.getNearestPackage(); if(ownerPackage == null) { return UnexecutableCommand.INSTANCE; } for(String requiredProfileName : stereotypeToApply.getRequiredProfiles()) { Profile profile = ownerPackage.getAppliedProfile(requiredProfileName, true); if(profile == null) { return UnexecutableCommand.INSTANCE; } } } } } // returns a null command, which means it is possible to apply the stereotype return null; } /** * {@inheritDoc} */ public void setConfiguration(IConfigurationElement element) { // something to do here ? } /** * Command to apply stereotypes and set stereotype application properties values */ public class ApplyStereotypeCommand extends EditElementCommand { /** * Create a new {@link ApplyStereotypeCommand}. * * @param elementToEdit * element to edit * @param request * the request used to modify the model */ protected ApplyStereotypeCommand(Element elementToEdit, IEditCommandRequest request) { super("Apply Stereotype Command", elementToEdit, request); } /** * {@inheritDoc} */ @Override protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { // retrieve the stereotype Stereotype stereotypeToApply = getElementToEdit().getApplicableStereotype(getRequest().getStereotypeQualifiedName()); if(stereotypeToApply == null) { return CommandResult.newErrorCommandResult("Impossible to find the stereotype " + getRequest().getStereotypeQualifiedName() + " for the element " + getElementToEdit()); } EObject result = getElementToEdit().applyStereotype(stereotypeToApply); if(result != null) { return CommandResult.newOKCommandResult(); } return CommandResult.newErrorCommandResult("Impossible to apply the stereotype " + stereotypeToApply + " for the element " + getElementToEdit()); } /** * {@inheritDoc} */ @Override public boolean canExecute() { // check the stereotype is present and can be applied Stereotype stereotypeToApply = getElementToEdit().getApplicableStereotype(getRequest().getStereotypeQualifiedName()); if(stereotypeToApply == null) { return false; } return super.canExecute(); } /** * {@inheritDoc} */ @Override protected Element getElementToEdit() { return (Element)super.getElementToEdit(); } /** * {@inheritDoc} */ @Override protected ApplyStereotypeRequest getRequest() { return (ApplyStereotypeRequest)super.getRequest(); } } /** * Request to apply stereotype on an element */ public class ApplyStereotypeRequest extends AbstractEditCommandRequest { /** element to edit */ private final Element elementToEdit; /** stererotype qualified name */ private final String stereotypeQualifiedName; /** * Constructor. * * @param editingDomain * editing domain in which the command will be executed * @param elementToEdit * element on which the stereotype should be applied * @param stereotypeQualifiedName * qualified name of the stereotype to apply */ protected ApplyStereotypeRequest(TransactionalEditingDomain editingDomain, Element elementToEdit, String stereotypeQualifiedName) { super(editingDomain); this.elementToEdit = elementToEdit; this.stereotypeQualifiedName = stereotypeQualifiedName; } /** * {@inheritDoc} */ public Object getEditHelperContext() { IClientContext context = getClientContext(); if(context == null) { return getElementToEdit(); } else { return new EditHelperContext(getElementToEdit(), context); } } /** * Returns the element to edit * * @return the element to edit */ public Element getElementToEdit() { return elementToEdit; } /** * Returns the qualified name of the stereotype to apply * * @return the qualified name of the stereotype to apply */ public String getStereotypeQualifiedName() { return stereotypeQualifiedName; } } }