1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.nuiton.decorator;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import java.util.ArrayList;
28 import java.util.List;
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public abstract class DecoratorProvider {
43
44
45 private static final Log log = LogFactory.getLog(DecoratorProvider.class);
46
47
48 protected List<DecoratorContext<?>> decorators;
49
50 public DecoratorProvider() {
51 loadDecorators();
52 }
53
54
55 protected abstract void loadDecorators();
56
57
58
59
60
61
62
63
64 @SuppressWarnings({"unchecked"})
65 public <O> Decorator<O> getDecorator(O object) {
66 return getDecorator(object, null);
67 }
68
69
70
71
72
73
74
75
76
77
78 @SuppressWarnings({"unchecked"})
79 public <O> Decorator<O> getDecorator(O object, String name) {
80 Class<O> k = (Class<O>) object.getClass();
81 return getDecoratorByType(k, name);
82 }
83
84
85
86
87
88
89
90
91 public <O> Decorator<O> getDecoratorByType(Class<O> type) {
92 return getDecoratorByType(type, null);
93 }
94
95
96
97
98
99
100
101
102
103 public <O> Decorator<O> getDecoratorByType(Class<O> type, String name) {
104 DecoratorContext<O> d = getDecoratorContext(type, name);
105 return d == null ? null : d.getDecorator();
106 }
107
108 public void reload() {
109 clear();
110 loadDecorators();
111 }
112
113 public void registerPropertyDecorator(Class<?> klass,
114 String expression) {
115 registerPropertyDecorator(klass, null, expression);
116 }
117
118 public void registerJXPathDecorator(Class<?> klass, String expression) {
119 registerJXPathDecorator(klass, null, expression);
120 }
121
122 public void registerMultiJXPathDecorator(Class<?> klass,
123 String expression,
124 String separator,
125 String separatorReplacement) {
126 registerMultiJXPathDecorator(klass, null, expression, separator,
127 separatorReplacement);
128 }
129
130 public void registerPropertyDecorator(Class<?> klass,
131 String name,
132 String expression) {
133 Decorator<?> decorator =
134 DecoratorUtil.newPropertyDecorator(klass, expression);
135 registerDecorator(name, decorator);
136 }
137
138 public void registerJXPathDecorator(Class<?> klass,
139 String name,
140 String expression) {
141 Decorator<?> decorator =
142 DecoratorUtil.newJXPathDecorator(klass, expression);
143 registerDecorator(name, decorator);
144 }
145
146 public void registerMultiJXPathDecorator(Class<?> klass,
147 String name,
148 String expression,
149 String separator,
150 String separatorReplacement) {
151 Decorator<?> decorator = DecoratorUtil.newMultiJXPathDecorator(
152 klass, expression, separator, separatorReplacement
153 );
154 registerDecorator(name, decorator);
155 }
156
157 public void registerDecorator(Decorator<?> decorator) {
158 registerDecorator(null, decorator);
159 }
160
161
162
163
164
165
166
167
168 public <T> void registerDecorator(String context,
169 Decorator<T> decorator) {
170
171
172 DecoratorContext<?> result =
173 getDecoratorContext(decorator.getType(), context);
174
175 if (result != null) {
176 throw new IllegalArgumentException(
177 "there is an already register decorator with context " +
178 result);
179 }
180
181 DecoratorContext<T> decoratorContext =
182 new DecoratorContext<T>(context, decorator);
183 if (log.isDebugEnabled()) {
184 log.debug(decoratorContext);
185 }
186 getDecorators().add(decoratorContext);
187 }
188
189 public void clear() {
190 if (decorators != null) {
191 decorators.clear();
192 }
193 }
194
195 protected List<DecoratorContext<?>> getDecorators() {
196 if (decorators == null) {
197 decorators = new ArrayList<DecoratorContext<?>>();
198 }
199 return decorators;
200 }
201
202 @SuppressWarnings({"unchecked"})
203 protected <T> DecoratorContext<T> getDecoratorContext(Class<T> type,
204 String context) {
205 DecoratorContext<T> result = null;
206 if (decorators != null) {
207 for (DecoratorContext<?> d : decorators) {
208 if (type == null) {
209 if (d.accept(context)) {
210 result = (DecoratorContext<T>) d;
211 break;
212 }
213 continue;
214 }
215 if (d.accept(type, context)) {
216 result = (DecoratorContext<T>) d;
217 break;
218 }
219 }
220 }
221 return result;
222 }
223
224 public static class DecoratorContext<T> {
225
226
227 final String context;
228
229
230 final Decorator<T> decorator;
231
232 public DecoratorContext(String context, Decorator<T> decorator) {
233 this.context = context;
234 this.decorator = decorator;
235 }
236
237 public String getContext() {
238 return context;
239 }
240
241 public Decorator<T> getDecorator() {
242 return decorator;
243 }
244
245 public Class<T> getType() {
246 return decorator.getType();
247 }
248
249 public boolean accept(Class<?> type, String context) {
250 boolean accept = getType().isAssignableFrom(type) && accept(context);
251 return accept;
252 }
253
254 public boolean accept(String context) {
255 return this.context == null && context == null ||
256 this.context != null && this.context.equals(context);
257 }
258
259 @Override
260 public String toString() {
261 return super.toString() + "<type: " + getType().getName() +
262 ", context :" + context + ">";
263 }
264 }
265
266 }