1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.seasar.cubby.plugins.s2.spi;
18
19 import java.lang.reflect.Modifier;
20 import java.util.Arrays;
21 import java.util.Collection;
22 import java.util.LinkedHashSet;
23 import java.util.Set;
24
25 import org.seasar.cubby.converter.Converter;
26 import org.seasar.cubby.plugins.s2.detector.ClassDetector;
27 import org.seasar.cubby.plugins.s2.detector.DetectClassProcessor;
28 import org.seasar.cubby.spi.impl.AbstractCachedConverterProvider;
29 import org.seasar.framework.container.S2Container;
30 import org.seasar.framework.convention.NamingConvention;
31 import org.seasar.framework.util.ClassUtil;
32 import org.seasar.framework.util.Disposable;
33 import org.seasar.framework.util.DisposableUtil;
34
35
36
37
38
39
40 public class S2ConverterProvider extends AbstractCachedConverterProvider
41 implements DetectClassProcessor, Disposable {
42
43 public static final String s2Container_BINDING = "bindingType=must";
44
45 public static final String namingConvention_BINDING = "bindingType=must";
46
47 public static final String classDetector_BINDING = "bindingType=must";
48
49
50 private S2Container s2Container;
51
52
53 private NamingConvention namingConvention;
54
55
56 private ClassDetector classDetector;
57
58
59 private boolean initialized;
60
61
62 private final Set<Converter> converters = new LinkedHashSet<Converter>();
63
64
65
66
67
68
69
70 public void setS2Container(final S2Container s2Container) {
71 this.s2Container = s2Container;
72 }
73
74
75
76
77
78
79
80 public void setNamingConvention(final NamingConvention namingConvention) {
81 this.namingConvention = namingConvention;
82 }
83
84
85
86
87
88
89
90 public void setClassDetector(final ClassDetector classDetector) {
91 this.classDetector = classDetector;
92 }
93
94 @Override
95 protected Collection<Converter> getConverters() {
96 return converters;
97 }
98
99
100
101
102 public void initialize() {
103 if (initialized) {
104 return;
105 }
106 classDetector.detect();
107
108 final Converter[] converters = (Converter[]) s2Container.getRoot()
109 .findAllComponents(Converter.class);
110 this.converters.addAll(Arrays.asList(converters));
111 DisposableUtil.add(this);
112 initialized = true;
113 }
114
115
116
117
118
119 public void dispose() {
120 this.converters.clear();
121 super.clear();
122 initialized = false;
123 }
124
125
126
127
128 @Override
129 public Converter getConverter(final Class<?> parameterType,
130 final Class<?> objectType) {
131 initialize();
132 return super.getConverter(parameterType, objectType);
133 }
134
135
136
137
138
139
140
141 public void processClass(final String packageName,
142 final String shortClassName) {
143 if (shortClassName.indexOf('$') != -1) {
144 return;
145 }
146 final String className = ClassUtil.concatName(packageName,
147 shortClassName);
148 if (!namingConvention.isTargetClassName(className)) {
149 return;
150 }
151 if (!className.endsWith(namingConvention.getConverterSuffix())) {
152 return;
153 }
154 final Class<?> clazz = ClassUtil.forName(className);
155 if (namingConvention.isSkipClass(clazz)) {
156 return;
157 }
158 if ((clazz.getModifiers() & Modifier.ABSTRACT) != 0) {
159 return;
160 }
161 if (!Converter.class.isAssignableFrom(clazz)) {
162 return;
163 }
164 final Converter converter = (Converter) s2Container.getRoot()
165 .getComponent(clazz);
166 this.converters.add(converter);
167 }
168
169 }