Java tutorial
/* * Copyright (C) 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package interactivespaces.activity; import com.google.common.collect.Lists; import interactivespaces.activity.ActivityStateTransition.TransitionResult; import org.apache.commons.logging.Log; import java.util.Queue; /** * Run an activity through a set of state transitions. * * <p> * This class is not threadsafe! * * @author Keith M. Hughes */ public class ActivityStateTransitioner { /** * Create the queue of transitions in a syntactically pleasing way. * * @param transitions * the transitions to be queued * * @return the queue of transitions */ public static Queue<ActivityStateTransition> transitions(ActivityStateTransition... transitions) { Queue<ActivityStateTransition> result = Lists.newLinkedList(); if (transitions != null) { for (ActivityStateTransition transition : transitions) { result.add(transition); } } return result; } /** * Control for the activity. */ private ActivityControl activity; /** * The transitions which need to take place. */ private Queue<ActivityStateTransition> transitions; /** * Whether or not there was an error. */ private boolean errored; /** * Log for errors. */ private Log log; /** * @param activity * the control for the activity being transitioned * @param transitions * the transitions that should be handled */ public ActivityStateTransitioner(ActivityControl activity, Queue<ActivityStateTransition> transitions, Log log) { this.activity = activity; this.transitions = transitions; this.log = log; } /** * Transition to a new state. * * @param nextState * the state that was transitioned to * * @return the result of the transition */ public SequenceTransitionResult transition(ActivityState nextState) { if (!nextState.isTransitional()) { return SequenceTransitionResult.WORKING; } if (errored) { return SequenceTransitionResult.CANT; } ActivityStateTransition nextTransition = transitions.peek(); if (nextTransition == null) { return SequenceTransitionResult.DONE; } TransitionResult canTransition = nextTransition.canTransition(nextState); if (canTransition.equals(TransitionResult.WAIT)) { // Don't consume the transition yet. WAIT means we are on our way. return SequenceTransitionResult.WORKING; } else if (canTransition.equals(TransitionResult.OK)) { transitions.poll(); try { nextTransition.transition(activity); } catch (Exception e) { errored = true; log.error("Error during activity transition", e); return SequenceTransitionResult.ERROR; } } else { log.warn("Activity cannot transition"); return SequenceTransitionResult.CANT; } if (transitions.isEmpty()) { return SequenceTransitionResult.DONE; } else { return SequenceTransitionResult.WORKING; } } /** * Result of a transition attempt. * * @author Keith M. Hughes */ public enum SequenceTransitionResult { /** * Still working on the transitions. */ WORKING, /** * The transitions are done. */ DONE, /** * Can't transition. may be because it errored before, or the transition is * illegal. */ CANT, /** * An error occured during transition. */ ERROR } }