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 }