1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.oxclient.aspects.retry;
17
18 import java.util.HashMap;
19 import java.util.Map;
20
21 import org.aspectj.lang.ProceedingJoinPoint;
22 import org.aspectj.lang.annotation.Around;
23 import org.aspectj.lang.annotation.Aspect;
24 import org.aspectj.lang.annotation.Pointcut;
25
26
27
28
29
30 @Aspect()
31 public class RetryHandler {
32
33 private int retries = 3;
34 private int delay = 200;
35
36 private final Map<ParameterSaveType, IParameterSaver> parameterSaverMap;
37
38
39
40
41
42
43
44
45 public RetryHandler(
46 final Map<ParameterSaveType, IParameterSaver> parameterSaverMap) {
47 super();
48 this.parameterSaverMap = parameterSaverMap;
49 }
50
51
52
53 public RetryHandler() {
54 super();
55 this.parameterSaverMap = new HashMap<ParameterSaveType, IParameterSaver>();
56 this.parameterSaverMap.put(ParameterSaveType.REFERENCE, new ReferenceSaver());
57 }
58
59
60
61 @Pointcut(value="@annotation(retry) " +
62 "&& execution(public * *(..))")
63 public void shouldRetry(@SuppressWarnings("unused") final RetryIt retry) {
64
65 }
66
67 @Around("shouldRetry(retry)")
68 public Object doWithRetry(final ProceedingJoinPoint pjp, final RetryIt retry) throws Throwable {
69 final ParameterSaveType saveType = retry.saverType();
70 final IParameterSaver parameterSaver =
71 this.parameterSaverMap.get(saveType);
72 final Object[] origArgs = pjp.getArgs();
73 parameterSaver.saveOriginalParameters(origArgs);
74
75 try {
76
77
78 return pjp.proceed(origArgs);
79 } catch (final Throwable th) {
80 final Class<? extends Throwable>[] retryFor = retry.retryFor();
81 if (shouldHandel(th, retryFor)) {
82 return retryProceed(pjp, retry, parameterSaver, retryFor);
83 }
84 throw th;
85 }
86 }
87
88
89 private Object retryProceed(
90 final ProceedingJoinPoint pjp,
91 final RetryIt retry,
92 final IParameterSaver parameterSaver,
93 final Class<? extends Throwable>[] retryFor) throws Throwable {
94 final boolean useglobal = retry.useGlobalSettings();
95 final int myDelay = this.delay;
96 final int myRetries = this.retries;
97 int mytries = 0;
98 Throwable lasThrowable = null;
99 do {
100
101 Thread.sleep(myDelay);
102 try {
103
104 return pjp.proceed(parameterSaver.loadOriginalParameters());
105 } catch (final Throwable th) {
106 if (shouldHandel(th, retryFor)) {
107 mytries++;
108 lasThrowable = th;
109 } else {
110 throw th;
111 }
112 }
113 } while (mytries < myRetries);
114 throw lasThrowable;
115 }
116
117 private boolean shouldHandel(final Throwable th, final Class<? extends Throwable>[] retryFor) {
118 for (final Class<? extends Throwable> clazz : retryFor) {
119 if (clazz.isInstance(th)) {
120 return true;
121 }
122 }
123 return false;
124 }
125
126
127
128 public int getRetries() {
129 return this.retries;
130 }
131
132 public void setRetries(final int retries) {
133 this.retries = retries;
134 }
135
136 public int getDelay() {
137 return this.delay;
138 }
139
140 public void setDelay(final int delay) {
141 this.delay = delay;
142 }
143 }