    001/*
    002    Licensed to the Apache Software Foundation (ASF) under one
    003    or more contributor license agreements.  See the NOTICE file
    004    distributed with this work for additional information
    005    regarding copyright ownership.  The ASF licenses this file
    006    to you under the Apache License, Version 2.0 (the
    007    "License"); you may not use this file except in compliance
    008    with the License.  You may obtain a copy of the License at
    009
    010       http://www.apache.org/licenses/LICENSE-2.0
    011
    012    Unless required by applicable law or agreed to in writing,
    013    software distributed under the License is distributed on an
    014    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015    KIND, either express or implied.  See the License for the
    016    specific language governing permissions and limitations
    017    under the License.
    018 */
    019package org.apache.wiki.workflow;
    020
    021import java.io.Serializable;
    022
    023/**
    024 * Resolution of a workflow Step, such as "approve," "deny," "hold," "task error," or other potential resolutions.
    025 *
    026 * @since 2.5
    027 */
    028public final class Outcome implements Serializable {
    029
    030    private static final long serialVersionUID = -338361947886288073L;
    031
    032    /** Complete workflow step (without errors) */
    033    public static final Outcome STEP_COMPLETE = new Outcome( "outcome.step.complete", true );
    034
    035    /** Terminate workflow step (without errors) */
    036    public static final Outcome STEP_ABORT = new Outcome( "outcome.step.abort", true );
    037
    038    /** Continue workflow step (without errors) */
    039    public static final Outcome STEP_CONTINUE = new Outcome( "outcome.step.continue", false );
    040
    041    /** Acknowlege the Decision. */
    042    public static final Outcome DECISION_ACKNOWLEDGE = new Outcome( "outcome.decision.acknowledge", true );
    043
    044    /** Approve the Decision (and complete the step). */
    045    public static final Outcome DECISION_APPROVE = new Outcome( "outcome.decision.approve", true );
    046
    047    /** Deny the Decision (and complete the step). */
    048    public static final Outcome DECISION_DENY = new Outcome( "outcome.decision.deny", true );
    049
    050    /** Put the Decision on hold (and pause the step). */
    051    public static final Outcome DECISION_HOLD = new Outcome( "outcome.decision.hold", false );
    052
    053    /** Reassign the Decision to another actor (and pause the step). */
    054    public static final Outcome DECISION_REASSIGN = new Outcome( "outcome.decision.reassign", false );
    055
    056    private static final Outcome[] OUTCOMES = new Outcome[] { STEP_COMPLETE, STEP_ABORT, STEP_CONTINUE, DECISION_ACKNOWLEDGE,
    057                                                              DECISION_APPROVE, DECISION_DENY, DECISION_HOLD, DECISION_REASSIGN };
    058
    059    private final String m_key;
    060
    061    private final boolean m_completion;
    062
    063    /**
    064     * Private constructor to prevent direct instantiation.
    065     *
    066     * @param key message key for the Outcome
    067     * @param completion whether this Outcome should be interpreted as the logical completion of a Step.
    068     */
    069    private Outcome( final String key, final boolean completion ) {
    070        if ( key == null ) {
    071            throw new IllegalArgumentException( "Key cannot be null." );
    072        }
    073        m_key = key;
    074        m_completion = completion;
    075    }
    076
    077    /**
    078     * Returns <code>true</code> if this Outcome represents a completion condition for a Step.
    079     *
    080     * @return the result
    081     */
    082    public boolean isCompletion() {
    083        return m_completion;
    084    }
    085
    086    /**
    087     * The i18n key for this outcome, which is prefixed by <code>outcome.</code>. If calling classes wish to return a locale-specific
    088     * name for this task (such as "approve this request"), they can use this method to obtain the correct key suffix.
    089     *
    090     * @return the i18n key for this outcome
    091     */
    092    public String getMessageKey() {
    093        return m_key;
    094    }
    095
    096    /**
    097     * The hashcode of an Outcome is identical to the hashcode of its message key, multiplied by 2 if it is a "completion" Outcome.
    098     *
    099     * @return the hash code
    100     */
    101    public int hashCode() {
    102        return m_key.hashCode() * ( m_completion ? 1 : 2 );
    103    }
    104
    105    /**
    106     * Two Outcome objects are equal if their message keys are equal.
    107     *
    108     * @param obj the object to test
    109     * @return <code>true</code> if logically equal, <code>false</code> if not
    110     */
    111    public boolean equals( final Object obj ) {
    112        if( !( obj instanceof Outcome ) ) {
    113            return false;
    114        }
    115        return m_key.equals( ( ( Outcome )obj ).getMessageKey() );
    116    }
    117
    118    /**
    119     * Returns a named Outcome. If an Outcome matching the supplied key is not found, this method throws a {@link NoSuchOutcomeException}.
    120     *
    121     * @param key the name of the outcome
    122     * @return the Outcome
    123     * @throws NoSuchOutcomeException if an Outcome matching the key isn't found.
    124     */
    125    public static Outcome forName( final String key ) throws NoSuchOutcomeException {
    126        if( key != null ) {
    127            for( final Outcome outcome : OUTCOMES ) {
    128                if( outcome.m_key.equals( key ) ) {
    129                    return outcome;
    130                }
    131            }
    132        }
    133        throw new NoSuchOutcomeException( "Outcome " + key + " not found." );
    134    }
    135
    136    /**
    137     * {@inheritDoc}
    138     */
    139    public String toString() {
    140        return "[Outcome:" + m_key + "]";
    141    }
    142
    143}