1 package org.xvsm.internal.tasks;
2
3 import java.util.List;
4
5 import org.apache.log4j.Logger;
6 import org.xvsm.core.ContainerRef;
7 import org.xvsm.core.Entry;
8 import org.xvsm.core.aspect.AspectContext;
9 import org.xvsm.core.aspect.LocalIPoint;
10 import org.xvsm.interfaces.ICapi;
11 import org.xvsm.interfaces.IContainerManager;
12 import org.xvsm.interfaces.container.IContainer;
13 import org.xvsm.internal.ContainerManager;
14 import org.xvsm.internal.EventProcessingPool;
15 import org.xvsm.internal.GlobalAspectManager;
16 import org.xvsm.internal.exceptions.AspectNotOkException;
17 import org.xvsm.internal.exceptions.AspectRescheduleException;
18 import org.xvsm.internal.exceptions.AspectSkipException;
19 import org.xvsm.internal.exceptions.ContainerFullException;
20 import org.xvsm.internal.exceptions.CountNotMetException;
21 import org.xvsm.internal.exceptions.FatalException;
22 import org.xvsm.internal.exceptions.InvalidContainerException;
23 import org.xvsm.internal.exceptions.InvalidTransactionException;
24 import org.xvsm.internal.exceptions.TransactionLockException;
25 import org.xvsm.selectors.Selector;
26 import org.xvsm.transactions.Transaction;
27 import org.xvsm.transactions.TransactionManager;
28
29 /***
30 *
31 * @author Christian Schreiber, Michael Proestler
32 *
33 */
34 public class OperationTask extends Task {
35
36 /***
37 * Auto genereated serial version uid.
38 */
39 private static final long serialVersionUID = 852362856073526398L;
40
41 /***
42 * the logger.
43 */
44 private static Logger logger = Logger.getLogger(OperationTask.class);
45
46 /***
47 * @see OperationTaskType
48 */
49 private OperationTaskType type;
50
51 /***
52 * the timeout of this operation.
53 */
54 private long timeout;
55
56 /***
57 * the time of the last update of the timeout.
58 */
59
60 private long lastTimeoutUpdate = System.currentTimeMillis();
61
62 /***
63 * @see ContainerRef
64 */
65 private ContainerRef cref;
66
67 /***
68 * @see Transaction
69 */
70 private Transaction tx;
71
72 /***
73 * @see Selector
74 */
75 private List<Selector> selectors;
76
77 /***
78 * @see Entry
79 */
80 private List<Entry> entries;
81
82 /***
83 * deleted entries.
84 */
85 private List<Entry> deleted;
86
87 /***
88 * The retrycount of this task.
89 */
90 private int retrycount = 0;
91
92 /***
93 * Constructor.
94 *
95 * @param type
96 * {@link OperationTaskType}
97 */
98 public OperationTask(OperationTaskType type) {
99 this.type = type;
100 }
101
102 /***
103 * Constructor.
104 *
105 * @param type
106 * {@link OperationTaskType}
107 * @param cref
108 * {@link ContainerRef}
109 * @param tx
110 * {@link Transaction}
111 * @param selectors
112 * {@link Selector}
113 * @param entries
114 * List of {@link Entry}s
115 * @param timeout
116 * the timeout of this operation.
117 */
118 public OperationTask(OperationTaskType type, List<Entry> entries,
119 ContainerRef cref, Transaction tx, List<Selector> selectors,
120 long timeout) {
121
122 super();
123 this.type = type;
124 this.cref = cref;
125 this.tx = tx;
126 this.selectors = selectors;
127 this.entries = entries;
128 this.timeout = timeout;
129 }
130
131 /***
132 * Constructor
133 *
134 * @param type
135 * {@link OperationTaskType}
136 * @param taskID
137 * the original ID of this task
138 * @param cref
139 * {@link ContainerRef}
140 * @param tx
141 * {@link Transaction}
142 * @param selectors
143 * {@link Selector}
144 * @param entries
145 * List of {@link Entry}s
146 * @param timeout
147 * the timeout of this operation.
148 */
149 public OperationTask(OperationTaskType type, long taskID, List<Entry> entries,
150 ContainerRef cref, Transaction tx, List<Selector> selectors,
151 long timeout) {
152
153 this(type, entries, cref, tx, selectors, timeout);
154 setTaskID(taskID);
155 }
156
157 /***
158 * {@inheritDoc}
159 */
160 public void run() {
161 Thread.currentThread().setName(this.getClass().getName());
162 if (logger.isDebugEnabled()) {
163 logger.debug("run() " + this);
164 }
165 if (this.tx != null) {
166
167
168 try {
169 if (tx.isUnderRollback()) {
170 throw new InvalidTransactionException();
171 }
172 this.tx = TransactionManager.getInstance().getTransaction(
173 this.tx.getId());
174 } catch (InvalidTransactionException e) {
175 this.setResult(e);
176 return;
177 }
178 }
179 try {
180 IContainerManager mngr = ContainerManager.getInstance();
181 IContainer c = mngr.getContainer(this.tx, cref);
182 if (logger.isDebugEnabled()) {
183 logger.debug("Received Container " + c + " cref = " + cref);
184 }
185 if (c == null) {
186 if (logger.isDebugEnabled()) {
187 logger.debug("run() Could not find the container "
188 + "-> UnknownContainerException");
189 }
190 setResult(new InvalidContainerException(cref + " is unknown."));
191
192 return;
193 }
194
195 Object result = null;
196
197 AspectContext acontext = new AspectContext(null, this.cref,
198 this.tx, this.selectors, this.entries, this.deleted,
199 this.retrycount, this.getAspectContext());
200 acontext.setTimeout(this.timeout);
201 boolean skip = false;
202 try {
203 switch (this.type) {
204 case READ:
205 acontext.setLocalIPoint(LocalIPoint.PreRead);
206 GlobalAspectManager.execute(acontext);
207 break;
208 case WRITE:
209 acontext.setLocalIPoint(LocalIPoint.PreWrite);
210 GlobalAspectManager.execute(acontext);
211 break;
212 case TAKE:
213 acontext.setLocalIPoint(LocalIPoint.PreTake);
214 GlobalAspectManager.execute(acontext);
215 break;
216 case SHIFT:
217 acontext.setLocalIPoint(LocalIPoint.PreShift);
218 GlobalAspectManager.execute(acontext);
219 break;
220 case DESTROY:
221 acontext.setLocalIPoint(LocalIPoint.PreDestroy);
222 GlobalAspectManager.execute(acontext);
223 break;
224 default:
225 }
226 } catch (AspectRescheduleException e) {
227 EventProcessingPool.getInstance().execute(this);
228 return;
229 } catch (AspectNotOkException e) {
230
231 if (this.tx != null) {
232 EventProcessingPool.getInstance().execute(
233 new TransactionTask(TransactionTaskType.ROLLBACK,
234 this.tx));
235 }
236 this.setResult(e);
237 return;
238 } catch (AspectSkipException e) {
239 skip = true;
240 }
241 try {
242 if (!skip) {
243 if (logger.isDebugEnabled()) {
244 logger.debug("run() execute task in TXLayer: "
245 + this.type + ", " + acontext.getCref() + ", "
246 + acontext.getTx() + ", "
247 + acontext.getSelectors() + ", "
248 + acontext.getEntries() + ", "
249 + acontext.getDeleted() + ", "
250 + acontext.getRetrycount() + ", "
251 + acontext.getTimeout());
252 }
253
254 this.setCref(acontext.getCref());
255 this.setTx(acontext.getTx());
256 this.setSelectors(acontext.getSelectors());
257 this.setEntries(acontext.getEntries());
258 this.setDeleted(acontext.getDeleted());
259 this.setRetrycount(acontext.getRetrycount());
260 this.setTimeout(acontext.getTimeout());
261 try {
262 result = c.execute(this);
263 } catch (AspectRescheduleException e) {
264 EventProcessingPool.getInstance().execute(this);
265 return;
266 }
267 }
268 try {
269 switch (this.type) {
270 case READ:
271 acontext.setLocalIPoint(LocalIPoint.PostRead);
272 GlobalAspectManager.execute(acontext);
273 break;
274 case WRITE:
275 acontext.setLocalIPoint(LocalIPoint.PostWrite);
276 GlobalAspectManager.execute(acontext);
277 break;
278 case TAKE:
279 acontext.setLocalIPoint(LocalIPoint.PostTake);
280 GlobalAspectManager.execute(acontext);
281 break;
282 case SHIFT:
283 acontext.setLocalIPoint(LocalIPoint.PostShift);
284 GlobalAspectManager.execute(acontext);
285 break;
286 case DESTROY:
287 acontext.setLocalIPoint(LocalIPoint.PostDestroy);
288 GlobalAspectManager.execute(acontext);
289 break;
290 default:
291 }
292 this.setResult(result);
293 } catch (Exception e) {
294 this.setResult(new FatalException(
295 "Aspect result not allowed here. " + e));
296 }
297 } catch (CountNotMetException e) {
298
299 } catch (TransactionLockException e) {
300
301 } catch (ContainerFullException e) {
302
303 }
304 } catch (Exception e) {
305 logger.error("run() Unexpected Exception occured:" + e);
306 this.setResult(new FatalException(e));
307 }
308 }
309
310 /***
311 * Get the type of this OperationTask.
312 *
313 * @return the type
314 */
315 public OperationTaskType getType() {
316 return type;
317 }
318
319 /***
320 * Set the type of this OperationTask.
321 *
322 * @param type
323 * the type to set
324 */
325 public void setType(OperationTaskType type) {
326 this.type = type;
327 }
328
329 /***
330 * Get the cref of this OperationTask.
331 *
332 * @return the cref
333 */
334 public ContainerRef getCref() {
335 return cref;
336 }
337
338 /***
339 * Set the cref of this OperationTask.
340 *
341 * @param cref
342 * the cref to set
343 */
344 public void setCref(ContainerRef cref) {
345 this.cref = cref;
346 }
347
348 /***
349 * Get the tx of this OperationTask.
350 *
351 * @return the tx
352 */
353 public Transaction getTx() {
354 return tx;
355 }
356
357 /***
358 * Set the tx of this OperationTask.
359 *
360 * @param tx
361 * the tx to set
362 */
363 public void setTx(Transaction tx) {
364 this.tx = tx;
365 }
366
367 /***
368 * Get the selectors of this OperationTask.
369 *
370 * @return the selectors
371 */
372 public List<Selector> getSelectors() {
373 return selectors;
374 }
375
376 /***
377 * Set the selectors of this OperationTask.
378 *
379 * @param selectors
380 * the selectors to set
381 */
382 public void setSelectors(List<Selector> selectors) {
383 this.selectors = selectors;
384 }
385
386 /***
387 * Get the entries of this OperationTask.
388 *
389 * @return the entries
390 */
391 public List<Entry> getEntries() {
392 return entries;
393 }
394
395 /***
396 * Set the entries of this OperationTask.
397 *
398 * @param entries
399 * the entries to set
400 */
401 public void setEntries(List<Entry> entries) {
402 this.entries = entries;
403 }
404
405 /***
406 * Get the retrycount of this OperationTask.
407 *
408 * @return the retrycount
409 */
410 public int getRetrycount() {
411 return retrycount;
412 }
413
414 /***
415 * Set the retrycount of this OperationTask.
416 *
417 * @param retrycount
418 * the retrycount to set
419 */
420 public void setRetrycount(int retrycount) {
421 this.retrycount = retrycount;
422 }
423
424 /***
425 * Get the timeout of this OperationTask.
426 *
427 * @return the timeout
428 */
429 public long getTimeout() {
430 return timeout;
431 }
432
433 /***
434 * Set the timeout of this OperationTask.
435 *
436 * @param timeout
437 * the timeout to set
438 */
439 public void setTimeout(long timeout) {
440 this.timeout = timeout;
441 }
442
443 /***
444 * Calculates the remaining timeout.
445 */
446 public void updateTimeout() {
447 if (this.timeout != ICapi.INFINITE_TIMEOUT) {
448 long now = System.currentTimeMillis();
449 long timepassed = now - this.lastTimeoutUpdate;
450 this.timeout = timeout - timepassed;
451
452
453 if (this.timeout == ICapi.INFINITE_TIMEOUT) {
454 this.timeout = 0;
455 }
456 this.lastTimeoutUpdate = now;
457 }
458 }
459
460 /***
461 * Returns <code>true</code> if the timeout of this task has been expired,
462 * otherwise <code>false</code>.
463 *
464 * @return <code>true</code> if the timeout of this task has been expired.
465 */
466 public boolean timeoutExpired() {
467 if (this.timeout == ICapi.INFINITE_TIMEOUT) {
468 return false;
469 }
470 return this.timeout <= 0;
471 }
472
473 /***
474 * {@inheritDoc}
475 *
476 * @see java.lang.Object#toString()
477 */
478 public String toString() {
479 return "[OperationTask: " + this.getType().toString() + " cref: "
480 + this.cref + " selectors " + this.selectors + " entries "
481 + this.entries + ", timeout " + this.timeout + "]";
482 }
483
484 /***
485 * Get the deleted of this OperationTask.
486 *
487 * @return the deleted
488 */
489 public List<Entry> getDeleted() {
490 return deleted;
491 }
492
493 /***
494 * Set the deleted of this OperationTask.
495 *
496 * @param deleted
497 * the deleted to set
498 */
499 public void setDeleted(List<Entry> deleted) {
500 this.deleted = deleted;
501 }
502 }