1 package org.oddjob.structural; 2 3 import java.io.PrintStream ; 4 import java.util.HashMap ; 5 import java.util.Iterator ; 6 import java.util.Map ; 7 8 import org.oddjob.Stateful; 9 import org.oddjob.state.JobState; 10 import org.oddjob.state.JobStateEvent; 11 import org.oddjob.state.JobStateHandler; 12 import org.oddjob.state.JobStateListener; 13 14 19 20 public class StatefulChildHelper extends ChildHelper 21 implements Stateful { 22 23 24 private boolean initialised; 25 26 29 private final Map listeners = new HashMap (); 30 31 35 private final Map jobStates = new HashMap (); 36 37 private final JobStateHandler stateHandler = new JobStateHandler(this); 38 39 40 public StatefulChildHelper(Object source) { 41 super(source); 42 } 43 44 public void initialise() { 45 initialised = true; 46 } 47 48 56 private void addStateListener(Object child) { 57 if (child instanceof Stateful) { 58 synchronized (jobStates) { 59 ChildStateListener l = new ChildStateListener(child); 60 listeners.put(child, l); 61 ((Stateful) child).addJobStateListener(l); 62 } 63 } 64 } 65 66 72 public void addChild(Object child) { 73 if (child == null) { 74 throw new NullPointerException ("Attempt to add a null child."); 75 } 76 addStateListener(child); 77 super.addChild(child); 78 } 79 80 public void insertChild(int index, Object child) { 81 if (child == null) { 82 throw new NullPointerException ("Attempt to add a null child."); 83 } 84 85 addStateListener(child); 86 super.insertChild(index, child); 87 } 88 89 94 private void removeStateListenerAt(int index) { 95 synchronized (jobStates) { 96 Object child = getChildAt(index); 97 if (child instanceof Stateful) { 98 ChildStateListener l = (ChildStateListener) listeners.remove(child); 99 ((Stateful) child).removeJobStateListener(l); 100 jobStates.remove(child); 101 } 102 } 103 } 104 105 112 public Object removeChildAt(int index) { 113 removeStateListenerAt(index); 114 return super.removeChildAt(index); 115 } 116 117 private void removeStateListener(Object child) { 118 synchronized (jobStates) { 119 if (child instanceof Stateful) { 120 ChildStateListener l = (ChildStateListener) listeners.remove(child); 121 ((Stateful) child).removeJobStateListener(l); 122 jobStates.remove(child); 123 } 124 } 125 } 126 127 133 public void removeChild(Object child) { 134 removeStateListener(child); 135 super.removeChild(child); 136 } 137 138 public void softResetChildren() { 139 if (jobStates.size() > 0) { 140 super.softResetChildren(); 141 } 142 else { 143 stateHandler.setJobStateReady(); 144 } 145 } 146 147 public void hardResetChildren() { 148 if (jobStates.size() > 0) { 149 super.hardResetChildren(); 150 } 151 else { 152 stateHandler.setJobStateReady(); 153 } 154 } 155 156 162 163 public OddjobChildException anyExceptions() { 164 synchronized (jobStates) { 165 for (Iterator it = jobStates.entrySet().iterator(); it.hasNext(); ) { 166 Map.Entry entry = (Map.Entry ) it.next(); 167 JobStateEvent event = (JobStateEvent) entry.getValue(); 168 if (event.getJobState() == JobState.EXCEPTION) { 169 return new OddjobChildException("Exception in child [" + entry.getKey() + "]", 170 event.getException()); 171 } 172 } 173 } 174 return null; 175 } 176 177 182 public boolean anyNotComplete() { 183 synchronized (jobStates) { 184 for (Iterator it = jobStates.entrySet().iterator(); it.hasNext(); ) { 185 Map.Entry entry = (Map.Entry ) it.next(); 186 JobStateEvent event = (JobStateEvent) entry.getValue(); 187 if (event.getJobState() == JobState.NOT_COMPLETE) { 188 return true; 189 } 190 } 191 } 192 return false; 193 } 194 195 200 public boolean allComplete() { 201 synchronized (jobStates) { 202 for (Iterator it = jobStates.entrySet().iterator(); it.hasNext(); ) { 203 Map.Entry entry = (Map.Entry ) it.next(); 204 JobStateEvent event = (JobStateEvent) entry.getValue(); 205 if (event.getJobState() != JobState.COMPLETE) { 206 return false; 207 } 208 } 209 } 210 return true; 211 } 212 213 218 public boolean anyReady() { 219 synchronized (jobStates) { 220 for (Iterator it = jobStates.entrySet().iterator(); it.hasNext(); ) { 221 Map.Entry entry = (Map.Entry ) it.next(); 222 JobStateEvent event = (JobStateEvent) entry.getValue(); 223 if (event.getJobState() == JobState.READY) { 224 return true; 225 } 226 } 227 } 228 return false; 229 } 230 231 public void refreshState() { 232 if (size() == 0) { 235 stateHandler.setJobStateReady(); 236 return; 237 } 238 239 Exception e = anyExceptions(); 240 if (e != null) { 241 stateHandler.setJobStateException(e); 242 } 243 else if (anyNotComplete()) { 244 stateHandler.setJobStateNotComplete(); 245 } 246 else if (allComplete()) { 247 stateHandler.setJobStateComplete(); 248 } 249 else if (anyReady()) { 250 stateHandler.setJobStateReady(); 251 } 252 } 253 254 public void destroyAll() { 255 super.destroyAll(); 256 refreshState(); 259 initialised = false; 260 } 261 262 266 public class ChildStateListener implements JobStateListener { 267 268 final Object key; 269 270 public ChildStateListener(Object key) { 271 if (key == null) { 272 throw new NullPointerException ("Child key can't be null!"); 273 } 274 this.key = key; 275 } 276 277 public void jobStateChange(JobStateEvent event) { 278 synchronized (jobStates) { 279 if (event == null) { 280 throw new NullPointerException ("Event can't be null!"); 281 } 282 jobStates.put(key, event); 283 if (!initialised) { 284 return; 285 } 286 refreshState(); 287 } 288 } 289 } 290 291 294 public void addJobStateListener(JobStateListener listener) { 295 stateHandler.addJobStateListener(listener); 296 } 297 298 301 public void removeJobStateListener(JobStateListener listener){ 302 stateHandler.removeJobStateListener(listener); 303 } 304 305 public void dump(PrintStream out) { 306 for (Iterator it = jobStates.entrySet().iterator(); it.hasNext(); ) { 307 Map.Entry entry = (Map.Entry ) it.next(); 308 JobStateEvent event = (JobStateEvent) entry.getValue(); 309 out.println(entry.getKey() + "=" + event); 310 } 311 312 } 313 314 } 315
| Popular Tags
|