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.util.beans;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.Set;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class BinderFactory {
64
65
66 private static final Log log = LogFactory.getLog(BinderFactory.class);
67
68
69 protected static BindelModelEntryMap binderModels;
70
71
72
73
74
75
76
77
78
79 public static <S> Binder<S, S> newBinder(Class<S> sourceType) {
80 return newBinder0(sourceType, sourceType, null, Binder.class);
81 }
82
83
84
85
86
87
88
89
90
91
92 public static <S> Binder<S, S> newBinder(Class<S> sourceType,
93 String contextName) {
94 return newBinder0(sourceType, sourceType, contextName, Binder.class);
95 }
96
97
98
99
100
101
102
103
104
105
106 public static <S, T> Binder<S, T> newBinder(Class<S> sourceType,
107 Class<T> targetType) {
108 return newBinder0(sourceType, targetType, null, Binder.class);
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122 public static <S, T> Binder<S, T> newBinder(Class<S> sourceType,
123 Class<T> targetType,
124 String contextName) {
125 return newBinder0(sourceType, targetType, contextName, Binder.class);
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public static <S, T, B extends Binder<S, T>> B newBinder(Class<S> sourceType,
141 Class<T> targetType,
142 String contextName,
143 Class<B> binderType) {
144 B binder = (B) newBinder0(sourceType, targetType, contextName, binderType);
145 return binder;
146 }
147
148 public static <S, T> Binder.BinderModel<S, T> registerBinderModel(BinderModelBuilder<S, T> binderModelBuilder) throws IllegalArgumentException {
149 Binder.BinderModel<S, T> model = registerBinderModel(binderModelBuilder, null);
150 return model;
151 }
152
153 public static <S, T> Binder.BinderModel<S, T> registerBinderModel(Binder<S, T> binder) throws IllegalArgumentException {
154 Binder.BinderModel<S, T> model = registerBinderModel(binder, null);
155 return model;
156 }
157
158 public static <S, T> Binder.BinderModel<S, T> registerBinderModel(Binder.BinderModel<S, T> model) throws IllegalArgumentException {
159
160 registerBinderModel(model, null);
161 return model;
162 }
163
164 public static <S, T> Binder.BinderModel<S, T> registerBinderModel(BinderModelBuilder<S, T> binderModelBuilder,
165 String contextName) throws IllegalArgumentException {
166 Binder.BinderModel<S, T> model = binderModelBuilder.getModel();
167 registerBinderModel(model, contextName);
168 return model;
169 }
170
171 public static <S, T> Binder.BinderModel<S, T> registerBinderModel(Binder<S, T> binder,
172 String contextName) throws IllegalArgumentException {
173 Binder.BinderModel<S, T> model = binder.getModel();
174 registerBinderModel(model, contextName);
175 return model;
176 }
177
178 public static <S, T> Binder.BinderModel<S, T> registerBinderModel(Binder.BinderModel<S, T> model,
179 String contextName) throws IllegalArgumentException {
180
181
182 Binder.BinderModel<S, T> registredModel =
183 getBinderModels().get(model, contextName);
184
185
186 BinderModelEntry key = new BinderModelEntry(model, contextName);
187
188 if (registredModel != null) {
189
190
191 if (log.isWarnEnabled()) {
192 log.warn("Remove existing binder model from cache : " +
193 toString(registredModel, contextName));
194 }
195 }
196
197
198 getBinderModels().put(key, model);
199 return model;
200 }
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 public static <S, T, B extends Binder<S, T>> B newBinder(Binder.BinderModel<S, T> model,
219 Class<B> binderType) {
220
221 B binder;
222 try {
223 binder = binderType.getConstructor().newInstance();
224 } catch (Exception e) {
225 throw new IllegalStateException(
226 "Could not instanciate binder of type " + binderType, e);
227 }
228
229 binder.setModel(model);
230 return binder;
231 }
232
233
234
235
236
237
238
239 public static void clear() {
240 if (binderModels != null) {
241 binderModels.clear();
242 binderModels = null;
243 }
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257 public static <S, T> boolean isBinderModelExists(Class<S> sourceType,
258 Class<T> targetType,
259 String contextName) {
260 Binder.BinderModel<S, T> model =
261 getBinderModels().get(sourceType, targetType, contextName);
262 return model != null;
263 }
264
265
266
267
268
269
270
271
272
273
274
275 public static <S, T> Binder.BinderModel<S, T> getCachedBinderModel(Class<S> sourceType,
276 Class<T> targetType,
277 String contextName) {
278 Binder.BinderModel<S, T> model =
279 getBinderModels().get(sourceType, targetType, contextName);
280 return model;
281 }
282
283 protected static BindelModelEntryMap getBinderModels() {
284 if (binderModels == null) {
285 binderModels = new BindelModelEntryMap();
286 }
287 return binderModels;
288 }
289
290 protected static String toString(Binder.BinderModel<?, ?> model, String contextName) {
291 return toString(model.getSourceType(), model.getTargetType(), contextName);
292 }
293
294 protected static String toString(Class<?> sourceType, Class<?> targetType, String contextName) {
295 return "<" + sourceType.getName() + " - " + targetType.getName() + " > [" + contextName + "] ";
296 }
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 protected static <S, T, B extends Binder<S, T>> Binder<S, T> newBinder0(Class<S> sourceType,
314 Class<T> targetType,
315 String contextName,
316 Class<B> binderType) {
317
318
319 Binder.BinderModel<S, T> model =
320 getBinderModels().get(sourceType, targetType, contextName);
321
322 if (model == null) {
323
324
325
326 if (log.isInfoEnabled()) {
327 log.info("No binder model found for " +
328 toString(sourceType, targetType, contextName) +
329 ", will create a new default one.");
330 }
331
332 BinderModelBuilder<S, T> builder =
333 BinderModelBuilder.newDefaultBuilder(sourceType, targetType);
334
335
336 model = registerBinderModel(builder, contextName);
337 }
338
339 B binder = newBinder(model, binderType);
340 return binder;
341 }
342
343 public static class BindelModelEntryMap implements Map<BinderModelEntry, Binder.BinderModel<?, ?>> {
344
345 protected final Map<BinderModelEntry, Binder.BinderModel<?, ?>> delegate;
346
347 public BindelModelEntryMap() {
348 delegate = new HashMap<BinderModelEntry, Binder.BinderModel<?, ?>>();
349 }
350
351 public <S, T> Binder.BinderModel<S, T> get(Class<S> source,
352 Class<T> target,
353 String contextName) {
354 Binder.BinderModel<S, T> result = null;
355
356 for (BinderModelEntry key : binderModels.keySet()) {
357 if (!key.getSourceType().equals(source)) {
358 continue;
359 }
360 if (!key.getTargetType().equals(target)) {
361 continue;
362 }
363
364 if (key.getName() == null) {
365 if (contextName != null) {
366 continue;
367 }
368 } else {
369 if (!key.getName().equals(contextName)) {
370 continue;
371 }
372 }
373
374 result = (Binder.BinderModel<S, T>) binderModels.get(key);
375 break;
376 }
377 return result;
378 }
379
380 public <S, T> Binder.BinderModel<S, T> get(Binder.BinderModel<S, T> model,
381 String contextName) {
382
383 Class<S> source = model.getSourceType();
384 Class<T> target = model.getTargetType();
385 Binder.BinderModel<S, T> result = get(source, target, contextName);
386 return result;
387 }
388
389 @Override
390 public int size() {
391 return delegate.size();
392 }
393
394 @Override
395 public boolean isEmpty() {
396 return delegate.isEmpty();
397 }
398
399 @Override
400 public boolean containsKey(Object key) {
401 return delegate.containsKey(key);
402 }
403
404 @Override
405 public boolean containsValue(Object value) {
406 return delegate.containsValue(value);
407 }
408
409 @Override
410 public Binder.BinderModel<?, ?> get(Object key) {
411 return delegate.get(key);
412 }
413
414 public Binder.BinderModel<?, ?> put(BinderModelEntry key, Binder.BinderModel<?, ?> value) {
415 return delegate.put(key, value);
416 }
417
418 @Override
419 public Binder.BinderModel<?, ?> remove(Object key) {
420 return delegate.remove(key);
421 }
422
423 public void putAll(Map<? extends BinderModelEntry, ? extends Binder.BinderModel<?, ?>> m) {
424 delegate.putAll(m);
425 }
426
427 @Override
428 public void clear() {
429 delegate.clear();
430 }
431
432 @Override
433 public Set<BinderModelEntry> keySet() {
434 return delegate.keySet();
435 }
436
437 @Override
438 public Collection<Binder.BinderModel<?, ?>> values() {
439 return delegate.values();
440 }
441
442 @Override
443 public Set<Entry<BinderModelEntry, Binder.BinderModel<?, ?>>> entrySet() {
444 return delegate.entrySet();
445 }
446
447 }
448
449
450
451
452
453
454
455 public static class BinderModelEntry {
456
457 protected final Class<?> sourceType;
458
459 protected final Class<?> targetType;
460
461 protected final String name;
462
463 public BinderModelEntry(Class<?> sourceType,
464 Class<?> targetType,
465 String name) {
466 this.sourceType = sourceType;
467 this.targetType = targetType;
468 this.name = name;
469 }
470
471 public BinderModelEntry(Binder.BinderModel<?, ?> model, String contextName) {
472 this(model.getSourceType(), model.getTargetType(), contextName);
473 }
474
475 public Class<?> getSourceType() {
476 return sourceType;
477 }
478
479 public Class<?> getTargetType() {
480 return targetType;
481 }
482
483 public String getName() {
484 return name;
485 }
486
487 @Override
488 public boolean equals(Object o) {
489 if (this == o) {
490 return true;
491 }
492 if (o == null || getClass() != o.getClass()) {
493 return false;
494 }
495
496 BinderModelEntry that = (BinderModelEntry) o;
497
498 return (name == null ? that.name == null : name.equals(that.name)) &&
499 sourceType.equals(that.sourceType) &&
500 targetType.equals(that.targetType);
501 }
502
503 @Override
504 public int hashCode() {
505 int result = sourceType.hashCode();
506 result = 31 * result + targetType.hashCode();
507 result = 31 * result + (name != null ? name.hashCode() : 0);
508 return result;
509 }
510
511 @Override
512 public String toString() {
513 StringBuilder buffer = new StringBuilder("<");
514 buffer.append(super.toString());
515 buffer.append(", sourceType: ").append(getSourceType()).append(',');
516 buffer.append(" targetType: ").append(getTargetType()).append(',');
517 buffer.append(" name: ").append(getName()).append('>');
518
519 return buffer.toString();
520 }
521 }
522 }