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 */ 019 package org.apache.wiki.workflow; 020 021 import java.io.Serializable; 022 023 /** 024 * Resolution of a workflow Step, such as "approve," "deny," "hold," "task 025 * error," or other potential resolutions. 026 * 027 * @since 2.5 028 */ 029 public final class Outcome implements Serializable 030 { 031 032 private static final long serialVersionUID = -338361947886288073L; 033 034 /** Complete workflow step (without errors) */ 035 public static final Outcome STEP_COMPLETE = new Outcome( "outcome.step.complete", true ); 036 037 /** Terminate workflow step (without errors) */ 038 public static final Outcome STEP_ABORT = new Outcome( "outcome.step.abort", true ); 039 040 /** Continue workflow step (without errors) */ 041 public static final Outcome STEP_CONTINUE = new Outcome( "outcome.step.continue", false ); 042 043 /** Acknowlege the Decision. */ 044 public static final Outcome DECISION_ACKNOWLEDGE = new Outcome( "outcome.decision.acknowledge", true ); 045 046 /** Approve the Decision (and complete the step). */ 047 public static final Outcome DECISION_APPROVE = new Outcome( "outcome.decision.approve", true ); 048 049 /** Deny the Decision (and complete the step). */ 050 public static final Outcome DECISION_DENY = new Outcome( "outcome.decision.deny", true ); 051 052 /** Put the Decision on hold (and pause the step). */ 053 public static final Outcome DECISION_HOLD = new Outcome( "outcome.decision.hold", false ); 054 055 /** Reassign the Decision to another actor (and pause the step). */ 056 public static final Outcome DECISION_REASSIGN = new Outcome( "outcome.decision.reassign", false ); 057 058 private static final Outcome[] OUTCOMES = new Outcome[] { STEP_COMPLETE, STEP_ABORT, STEP_CONTINUE, DECISION_ACKNOWLEDGE, 059 DECISION_APPROVE, DECISION_DENY, DECISION_HOLD, DECISION_REASSIGN }; 060 061 private final String m_key; 062 063 private final boolean m_completion; 064 065 /** 066 * Private constructor to prevent direct instantiation. 067 * 068 * @param key 069 * message key for the Outcome 070 * @param completion 071 * whether this Outcome should be interpreted as the logical 072 * completion of a Step. 073 */ 074 private Outcome( String key, boolean completion ) 075 { 076 if ( key == null ) 077 { 078 throw new IllegalArgumentException( "Key cannot be null." ); 079 } 080 m_key = key; 081 m_completion = completion; 082 } 083 084 /** 085 * Returns <code>true</code> if this Outcome represents a completion 086 * condition for a Step. 087 * 088 * @return the result 089 */ 090 public boolean isCompletion() 091 { 092 return m_completion; 093 } 094 095 /** 096 * The i18n key for this outcome, which is prefixed by <code>outcome.</code>. 097 * If calling classes wish to return a locale-specific name for this task 098 * (such as "approve this request"), they can use this method to obtain the 099 * correct key suffix. 100 * 101 * @return the i18n key for this outcome 102 */ 103 public String getMessageKey() 104 { 105 return m_key; 106 } 107 108 /** 109 * The hashcode of an Outcome is identical to the hashcode of its message 110 * key, multiplied by 2 if it is a "completion" Outcome. 111 * @return the hash code 112 */ 113 public int hashCode() 114 { 115 return m_key.hashCode() * ( m_completion ? 1 : 2 ); 116 } 117 118 /** 119 * Two Outcome objects are equal if their message keys are equal. 120 * @param obj the object to test 121 * @return <code>true</code> if logically equal, <code>false</code> if not 122 */ 123 public boolean equals( Object obj ) 124 { 125 if (!(obj instanceof Outcome)) 126 { 127 return false; 128 } 129 return m_key.equals( ( (Outcome) obj ).getMessageKey() ); 130 } 131 132 /** 133 * Returns a named Outcome. If an Outcome matching the supplied key is not 134 * found, this method throws a {@link NoSuchOutcomeException}. 135 * 136 * @param key 137 * the name of the outcome 138 * @return the Outcome 139 * @throws NoSuchOutcomeException 140 * if an Outcome matching the key isn't found. 141 */ 142 public static Outcome forName( String key ) throws NoSuchOutcomeException 143 { 144 if ( key != null ) 145 { 146 for (int i = 0; i < OUTCOMES.length; i++) 147 { 148 if ( OUTCOMES[i].m_key.equals( key ) ) 149 { 150 return OUTCOMES[i]; 151 } 152 } 153 } 154 throw new NoSuchOutcomeException( "Outcome " + key + " not found." ); 155 } 156 157 /** 158 * {@inheritDoc} 159 */ 160 public String toString() 161 { 162 return "[Outcome:" + m_key + "]"; 163 } 164 165 }