001 /* 002 * Copyright 1999-2001,2004 The Apache Software Foundation. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.apache.commons.workflow.util; 018 019 020 import java.util.Map; 021 import org.apache.commons.workflow.Context; 022 import org.apache.commons.workflow.ContextEvent; 023 import org.apache.commons.workflow.ContextListener; 024 import org.apache.commons.workflow.Step; 025 import org.apache.commons.workflow.StepException; 026 027 028 /** 029 * <strong>ContextSupport</strong> is a convenience class for managing the 030 * firing of <code>ContextEvents</code> to registered 031 * <code>ContextListeners</code>. 032 * 033 * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $ 034 * @author Craig R. McClanahan 035 */ 036 037 public class ContextSupport { 038 039 040 // ----------------------------------------------------------- Constructors 041 042 043 /** 044 * Construct a new ContextSupport object associated with the 045 * specified Context. 046 * 047 * @param context Context for whom we will fire events 048 */ 049 public ContextSupport(Context context) { 050 051 super(); 052 this.context = context; 053 054 } 055 056 057 // ----------------------------------------------------- Instance Variables 058 059 060 /** 061 * The set of registered <code>ContextListener</code> event listeners. 062 */ 063 protected ContextListener listeners[] = new ContextListener[0]; 064 065 066 /** 067 * The <code>Context</code> for whom we will fire events. 068 */ 069 protected Context context = null; 070 071 072 // ------------------------------------------------- Event Listener Methods 073 074 075 /** 076 * Add a listener that is notified each time beans are added, 077 * replaced, or removed in this context. 078 * 079 * @param listener The ContextListener to be added 080 */ 081 public void addContextListener(ContextListener listener) { 082 083 synchronized (listeners) { 084 ContextListener results[] = 085 new ContextListener[listeners.length + 1]; 086 System.arraycopy(listeners, 0, results, 0, listeners.length); 087 results[listeners.length] = listener; 088 listeners = results; 089 } 090 091 } 092 093 094 /** 095 * Remove a listener that is notified each time beans are added, 096 * replaced, or removed in this context. 097 * 098 * @param listener The ContextListener to be removed 099 */ 100 public void removeContextListener(ContextListener listener) { 101 102 synchronized (listeners) { 103 int n = -1; 104 for (int i = 0; i < listeners.length; i++) { 105 if (listeners[i] == listener) { 106 n = i; 107 break; 108 } 109 } 110 if (n < 0) 111 return; 112 ContextListener results[] = 113 new ContextListener[listeners.length - 1]; 114 int j = 0; 115 for (int i = 0; i < listeners.length; i++) { 116 if (i != n) 117 results[j++] = listeners[i]; 118 } 119 listeners = results; 120 } 121 122 } 123 124 125 // --------------------------------------------------- Event Firing Methods 126 127 128 /** 129 * Fire a <code>afterActivity</code> event to all registered listeners. 130 * 131 * @param step Step that was executed last 132 */ 133 public void fireAfterActivity(Step step) { 134 135 if (listeners.length == 0) 136 return; 137 ContextEvent event = new ContextEvent(context, step); 138 ContextListener interested[] = null; 139 synchronized (listeners) { 140 interested = (ContextListener[]) listeners.clone(); 141 } 142 for (int i = 0; i < interested.length; i++) 143 interested[i].afterActivity(event); 144 145 } 146 147 148 /** 149 * Fire a <code>afterActivity</code> event to all registered listeners. 150 * 151 * @param step Step that was executed last 152 * @param exception StepException thrown by the last Step 153 */ 154 public void fireAfterActivity(Step step, StepException exception) { 155 156 if (listeners.length == 0) 157 return; 158 ContextEvent event = new ContextEvent(context, step, exception); 159 ContextListener interested[] = null; 160 synchronized (listeners) { 161 interested = (ContextListener[]) listeners.clone(); 162 } 163 for (int i = 0; i < interested.length; i++) 164 interested[i].afterActivity(event); 165 166 } 167 168 169 /** 170 * Fire a <code>afterStep</code> event to all registered listeners. 171 * 172 * @param step Step that was executed 173 */ 174 public void fireAfterStep(Step step) { 175 176 if (listeners.length == 0) 177 return; 178 ContextEvent event = new ContextEvent(context, step); 179 ContextListener interested[] = null; 180 synchronized (listeners) { 181 interested = (ContextListener[]) listeners.clone(); 182 } 183 for (int i = 0; i < interested.length; i++) 184 interested[i].afterStep(event); 185 186 } 187 188 189 /** 190 * Fire a <code>afterStep</code> event to all registered listeners. 191 * 192 * @param step Step that was executed 193 * @param exception StepException thrown by the executed step 194 */ 195 public void fireAfterStep(Step step, StepException exception) { 196 197 if (listeners.length == 0) 198 return; 199 ContextEvent event = new ContextEvent(context, step, exception); 200 ContextListener interested[] = null; 201 synchronized (listeners) { 202 interested = (ContextListener[]) listeners.clone(); 203 } 204 for (int i = 0; i < interested.length; i++) 205 interested[i].afterStep(event); 206 207 } 208 209 210 /** 211 * Fire a <code>beforeActivity</code> event to all registered listeners. 212 * 213 * @param step Step that will be executed first 214 */ 215 public void fireBeforeActivity(Step step) { 216 217 if (listeners.length == 0) 218 return; 219 ContextEvent event = new ContextEvent(context, step); 220 ContextListener interested[] = null; 221 synchronized (listeners) { 222 interested = (ContextListener[]) listeners.clone(); 223 } 224 for (int i = 0; i < interested.length; i++) 225 interested[i].beforeActivity(event); 226 227 } 228 229 230 /** 231 * Fire a <code>beforeStep</code> event to all registered listeners. 232 * 233 * @param step Step that is about to be executed 234 */ 235 public void fireBeforeStep(Step step) { 236 237 if (listeners.length == 0) 238 return; 239 ContextEvent event = new ContextEvent(context, step); 240 ContextListener interested[] = null; 241 synchronized (listeners) { 242 interested = (ContextListener[]) listeners.clone(); 243 } 244 for (int i = 0; i < interested.length; i++) 245 interested[i].beforeStep(event); 246 247 } 248 249 250 }