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
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.HashMap;
31 import java.util.Locale;
32 import java.util.Map;
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public abstract class DecoratorMulti18nProvider {
47
48
49 private static final Log log = LogFactory.getLog(DecoratorProvider.class);
50
51
52
53
54
55
56
57 protected Map<Locale, Collection<DecoratorContext<?>>> decoratorContexts;
58
59
60
61
62
63
64
65 protected abstract void loadDecorators(Locale locale);
66
67
68
69
70
71
72
73
74
75
76 @SuppressWarnings({"unchecked"})
77 public <O> Decorator<O> getDecorator(Locale locale, O object) {
78 return getDecorator(locale, object, null);
79 }
80
81
82
83
84
85
86
87
88
89
90
91 @SuppressWarnings({"unchecked"})
92 public <O> Decorator<O> getDecorator(Locale locale,
93 O object,
94 String name) {
95 Class<O> k = (Class<O>) object.getClass();
96 return getDecoratorByType(locale, k, name);
97 }
98
99
100
101
102
103
104
105
106
107 public <O> Decorator<O> getDecoratorByType(Locale locale,
108 Class<O> type) {
109 return getDecoratorByType(locale, type, null);
110 }
111
112
113
114
115
116
117
118
119
120
121
122 public <O> Decorator<O> getDecoratorByType(Locale locale,
123 Class<O> type,
124 String name) {
125 DecoratorContext<O> d = getDecoratorContext(locale, type, name, true);
126 return d == null ? null : d.getDecorator();
127 }
128
129 public void registerPropertyDecorator(Locale locale,
130 Class<?> klass,
131 String expression) {
132 registerPropertyDecorator(locale, klass, null, expression);
133 }
134
135 public void registerJXPathDecorator(Locale locale,
136 Class<?> klass, String expression) {
137 registerJXPathDecorator(locale, klass, null, expression);
138 }
139
140 public void registerMultiJXPathDecorator(Locale locale,
141 Class<?> klass,
142 String expression,
143 String separator,
144 String separatorReplacement) {
145 registerMultiJXPathDecorator(locale, klass, null, expression, separator,
146 separatorReplacement);
147 }
148
149 public void registerPropertyDecorator(Locale locale,
150 Class<?> klass,
151 String name,
152 String expression) {
153 Decorator<?> decorator =
154 DecoratorUtil.newPropertyDecorator(klass, expression);
155 registerDecorator(locale, name, decorator);
156 }
157
158 public void registerJXPathDecorator(Locale locale,
159 Class<?> klass,
160 String name,
161 String expression) {
162 Decorator<?> decorator =
163 DecoratorUtil.newJXPathDecorator(klass, expression);
164 registerDecorator(locale, name, decorator);
165 }
166
167 public void registerMultiJXPathDecorator(Locale locale,
168 Class<?> klass,
169 String name,
170 String expression,
171 String separator,
172 String separatorReplacement) {
173 Decorator<?> decorator = DecoratorUtil.newMultiJXPathDecorator(
174 klass, expression, separator, separatorReplacement
175 );
176 registerDecorator(locale, name, decorator);
177 }
178
179 public void registerDecorator(Locale locale,
180 Decorator<?> decorator) {
181 registerDecorator(locale, null, decorator);
182 }
183
184
185
186
187
188
189
190
191
192 public <T> void registerDecorator(Locale locale,
193 String context,
194 Decorator<T> decorator) {
195
196
197 DecoratorContext<?> result =
198 getDecoratorContext(locale,
199 decorator.getType(),
200 context,
201 false
202 );
203
204 if (result != null) {
205 throw new IllegalArgumentException(
206 "there is an already register decorator with context " +
207 result);
208 }
209
210 DecoratorContext<T> decoratorContext =
211 new DecoratorContext<T>(context, decorator);
212 if (log.isDebugEnabled()) {
213 log.debug(decoratorContext);
214 }
215 getDecoratorContexts(locale, false).add(decoratorContext);
216 }
217
218 public void clear() {
219 if (decoratorContexts != null) {
220 decoratorContexts.clear();
221 }
222 }
223
224 protected Map<Locale, Collection<DecoratorContext<?>>> getDecoratorContexts() {
225 if (decoratorContexts == null) {
226 decoratorContexts = new HashMap<Locale, Collection<DecoratorContext<?>>>();
227 }
228 return decoratorContexts;
229 }
230
231 protected Collection<DecoratorContext<?>> getDecoratorContexts(Locale locale,
232 boolean doLoad) {
233
234 Collection<DecoratorContext<?>> decoratorContexts =
235 getDecoratorContexts().get(locale);
236
237 if (decoratorContexts == null) {
238 decoratorContexts = new ArrayList<DecoratorContext<?>>();
239 getDecoratorContexts().put(locale, decoratorContexts);
240 if (doLoad) {
241 loadDecorators(locale);
242 }
243 }
244 return decoratorContexts;
245 }
246
247 @SuppressWarnings({"unchecked"})
248 protected <T> DecoratorContext<T> getDecoratorContext(Locale locale,
249 Class<T> type,
250 String context,
251 boolean doLoad) {
252 DecoratorContext<T> result = null;
253
254 Collection<DecoratorContext<?>> decoratorContexts =
255 getDecoratorContexts(locale, doLoad);
256
257 if (decoratorContexts != null) {
258 for (DecoratorContext<?> d : decoratorContexts) {
259 if (type == null) {
260 if (d.accept(context)) {
261 result = (DecoratorContext<T>) d;
262 break;
263 }
264 continue;
265 }
266 if (d.accept(type, context)) {
267 result = (DecoratorContext<T>) d;
268 break;
269 }
270 }
271 }
272 return result;
273 }
274
275 public static class DecoratorContext<T> {
276
277
278 final String context;
279
280
281 final Decorator<T> decorator;
282
283 public DecoratorContext(String context, Decorator<T> decorator) {
284 this.context = context;
285 this.decorator = decorator;
286 }
287
288 public String getContext() {
289 return context;
290 }
291
292 public Decorator<T> getDecorator() {
293 return decorator;
294 }
295
296 public Class<T> getType() {
297 return decorator.getType();
298 }
299
300 public boolean accept(Class<?> type, String context) {
301 boolean accept = getType().isAssignableFrom(type) && accept(context);
302 return accept;
303 }
304
305 public boolean accept(String context) {
306 return this.context == null && context == null ||
307 this.context != null && this.context.equals(context);
308 }
309
310 @Override
311 public String toString() {
312 return super.toString() + "<type: " + getType().getName() +
313 ", context :" + context + ">";
314 }
315 }
316 }