interactivespaces.activity.ActivityStateTransitioner.java Source code

Java tutorial

Introduction

Here is the source code for interactivespaces.activity.ActivityStateTransitioner.java

Source

/*
 * 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
    }
}