001 package org.apache.commons.workflow.core;
002
003 import org.apache.commons.workflow.Context;
004 import org.apache.commons.workflow.Descriptor;
005 import org.apache.commons.workflow.Step;
006 import org.apache.commons.workflow.StepException;
007
008
009 /**
010 * <p>Evaluate properties specified by the associated Descriptors, and
011 * transfer control to the specified step if ALL of them are
012 * <code>false</code> (if boolean) or null (if Object).
013 *
014 * <b>This is the exact opposite of AndStep</b>
015 *
016 * To avoid non-deterministic evaluation stack behavior, all of the
017 * specified Descriptors are always evaluated.</p>
018 *
019 * <p>Supported Attributes:</p>
020 * <ul>
021 * <li><strong>step</strong> - Identifier of the Step to which control
022 * should be transferred if the condition is not met.</li>
023 * </ul>
024 *
025 * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
026 * @author Preston Sheldon
027 */
028
029 public class NotAndStep extends GotoStep {
030
031
032 // ----------------------------------------------------------= Constructors
033
034
035 /**
036 * Construct a default instance of this Step.
037 */
038 public NotAndStep() {
039
040 super();
041
042 }
043 /**
044 * Construct an instance of this Step with the specified identifier.
045 *
046 * @param id Step identifier
047 */
048 public NotAndStep(String id) {
049
050 this(id, null, null);
051
052 }
053 /**
054 * Construct a fully configured instance of this Step.
055 *
056 * @param id Step identifier of this step
057 * @param step Step identifier to which control should be redirected
058 */
059 public NotAndStep(String id, String step) {
060
061 this(id, step, null);
062
063 }
064 /**
065 * Construct a fully configured instance of this Step.
066 *
067 * @param id Step identifier of this step
068 * @param step Step identifier to which control should be redirected
069 * @param descriptor Initial descriptor to be added
070 */
071 public NotAndStep(String id, String step, Descriptor descriptor) {
072
073 super();
074 setId(id);
075 setStep(step);
076 addDescriptor(descriptor);
077
078 }
079 // --------------------------------------------------------- Public Methods
080
081
082 /**
083 * Perform the executable actions related to this Step, in the context of
084 * the specified Context.
085 *
086 * @param context The Context that is tracking our execution state
087 *
088 * @exception StepException if a processing error has occurred
089 */
090 public void execute(Context context) throws StepException {
091
092 // Process all associated descriptors
093 boolean condition = true;
094 Descriptor descriptors[] = findDescriptors();
095 for (int i = 0; i < descriptors.length; i++) {
096 Object value = descriptors[i].get(context);
097 if (value == null)
098 condition = false;
099 else if ((value instanceof Boolean) &&
100 !((Boolean) value).booleanValue())
101 condition = false;
102 }
103
104 // Conditionally forward control to the specified step
105 if (!condition) {
106 Step next = getOwner().findStep(this.step);
107 if (next == null)
108 throw new StepException("Cannot find step '" + step + "'",
109 this);
110 context.setNextStep(next);
111 }
112
113 }
114 }