/** * 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.EntryEventImpl; import org.yakindu.sct.refactoring.refactor.AbstractRefactoring; /** * This refactoring moves entry actions of a state to its incoming transitions. * <br><br> * Context: * <ul> * <li>Exactly one state</li> * </ul> * Preconditions: * <ul> * <li>At least one entry action exists.</li> * <li>No incoming transition enters a parent composite state of the context state with entry actions.</li> * </ul> * * @author thomas kutz - Initial contribution and API * */ public class UnfoldEntryActionsRefactoring extends AbstractRefactoring<State> { @Override protected void internalExecute() { unfoldEntryActions(); } /** * {@inheritDoc} */ @Override public boolean isExecutable() { return super.isExecutable() && hasAtLeastOneEntryAction() && hasAtLeastOneIncomingTransition() && noIncomingTransitionEntersCompositeWithEntryActions(); } private boolean noIncomingTransitionEntersCompositeWithEntryActions() { return !helper.oneIncomingTransitionEntersCompositeWithEntryActions(getContextObject()); } private boolean hasAtLeastOneEntryAction() { return helper.hasEntryAction(getContextObject()); } private boolean hasAtLeastOneIncomingTransition() { return !getContextObject().getIncomingTransitions().isEmpty(); } private void unfoldEntryActions() { List<Expression> actionsToUnfold = new ArrayList<Expression>( helper.extractAllLocalActionsForEventType(getContextObject(), EntryEventImpl.class)); addActionsToIncomingTransitions(actionsToUnfold); } private void addActionsToIncomingTransitions(List<Expression> actionsToAdd) { for (Transition transition : getContextObject() .getIncomingTransitions()) { addActionsToTransition(transition, EcoreUtil.copyAll(actionsToAdd)); } } private void addActionsToTransition(final Transition transition, final Collection<Expression> actionsToAdd) { Effect effect = transition.getEffect(); ReactionEffect reactionEffect; if (effect instanceof ReactionEffect) { reactionEffect = (ReactionEffect) effect; reactionEffect.getActions().addAll(actionsToAdd); } else { reactionEffect = StextFactory.eINSTANCE.createReactionEffect(); transition.setEffect(reactionEffect); } reactionEffect.getActions().addAll(actionsToAdd); } @Override protected String getCommandLabel() { return "Unfold Entry Actions"; } }