/** * Copyright (c) 2013 committers of YAKINDU and others. * 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: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.sct.refactoring.refactor.impl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.emf.ecore.util.EcoreUtil; import org.yakindu.base.expressions.expressions.Expression; import org.yakindu.sct.model.sgraph.Effect; import org.yakindu.sct.model.sgraph.State; import org.yakindu.sct.model.sgraph.Transition; import org.yakindu.sct.model.stext.stext.ReactionEffect; import org.yakindu.sct.model.stext.stext.StextFactory; import org.yakindu.sct.model.stext.stext.impl.ExitEventImpl; import org.yakindu.sct.refactoring.refactor.AbstractRefactoring; /** * This refactoring moves exit actions of a state to its outgoing transitions. * <br><br> * Context: * <ul> * <li>Exactly one state</li> * </ul> * Preconditions: * <ul> * <li>At least one exit action exists.</li> * <li>At least one outgoing transition exists.</li> * <li>No outgoing transition leaves a parent composite state of the context state with exit actions.</li> * </ul> * * @author thomas kutz - Initial contribution and API * */ public class UnfoldExitActionsRefactoring extends AbstractRefactoring<State> { @Override protected void internalExecute() { unfoldExitActions(); } /** * {@inheritDoc} */ @Override public boolean isExecutable() { return super.isExecutable() && hasAtLeastOneExitAction() && hasAtLeastOneOutgoingTransition() && noOutgoingTransitionLeavesCompositeWithExitActions(); } private boolean hasAtLeastOneExitAction() { return helper.hasExitAction(getContextObject()); } private boolean noOutgoingTransitionLeavesCompositeWithExitActions() { return !helper.oneOutgoingTransitionLeavesCompositeWithExitActions(getContextObject()); } private boolean hasAtLeastOneOutgoingTransition() { return !getContextObject().getOutgoingTransitions().isEmpty(); } private void unfoldExitActions() { List<Expression> actionsToUnfold = new ArrayList<Expression>( helper.extractAllLocalActionsForEventType(getContextObject(), ExitEventImpl.class)); addActionsToOutgoingTransitions(actionsToUnfold); } private void addActionsToOutgoingTransitions(List<Expression> actionsToAdd) { for (Transition transition : getContextObject() .getOutgoingTransitions()) { addActionsToTransition(transition, EcoreUtil.copyAll(actionsToAdd)); } } private void addActionsToTransition(final Transition transition, final Collection<Expression> actionsToAdd) { Effect effect = transition.getEffect(); if (effect instanceof ReactionEffect) { ReactionEffect reactionEffect = (ReactionEffect) effect; reactionEffect.getActions().addAll(0, actionsToAdd); } else { ReactionEffect reactionEffect = StextFactory.eINSTANCE .createReactionEffect(); transition.setEffect(reactionEffect); reactionEffect.getActions().addAll(actionsToAdd); } } @Override protected String getCommandLabel() { return "Unfold Exit Actions"; } }