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