1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.bean;
20
21 import java.io.InputStream;
22 import java.io.IOException;
23 import java.net.URL;
24
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.Enumeration;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Properties;
32 import java.util.concurrent.ConcurrentHashMap;
33
34 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
35 import org.apache.myfaces.trinidad.util.ThreadLocalUtils;
36
37
38
39
40
41
42 public class FacesBeanFactory
43 {
44
45
46
47
48 static public FacesBean createFacesBean(
49 Class<?> ownerClass,
50 String rendererType)
51 {
52 if (ownerClass == null)
53 return null;
54
55 String className = ownerClass.getName();
56 FacesBean bean = createFacesBean(className, rendererType);
57
58 if (bean == null && rendererType != null)
59 {
60 bean = createFacesBean(className, null);
61 _cacheFacesBeanClass(bean, className, rendererType);
62 }
63
64 if (bean == null)
65 {
66 bean = createFacesBean(ownerClass.getSuperclass(), rendererType);
67 _cacheFacesBeanClass(bean, className, rendererType);
68 }
69
70 return bean;
71 }
72
73 static public FacesBean createFacesBean(
74 String beanType,
75 String rendererType)
76 {
77 String typeKey = _buildTypeKey(beanType, rendererType);
78
79 Class<?> type = _TYPES_CLASS.get(typeKey);
80
81 if(type == null)
82 {
83 String className = (String) _TYPES_MAP.get(typeKey);
84 if (className == null)
85 return null;
86
87
88
89
90
91 try
92 {
93 type = _getClassLoader().loadClass(className);
94 _TYPES_CLASS.put(typeKey, type);
95 }
96 catch (ClassNotFoundException cnfe)
97 {
98 _LOG.severe("CANNOT_FIND_FACESBEAN", className);
99 _LOG.severe(cnfe);
100 }
101 }
102
103 try
104 {
105 return (FacesBean) type.newInstance();
106 }
107 catch (IllegalAccessException iae)
108 {
109 _LOG.severe("CANNOT_CREATE_FACESBEAN_INSTANCE", type.getName());
110 _LOG.severe(iae);
111 }
112 catch (InstantiationException ie)
113 {
114 _LOG.severe("CANNOT_CREATE_FACESBEAN_INSTANCE", type.getName());
115 _LOG.severe(ie);
116 }
117
118 return null;
119 }
120
121 static private void _initializeBeanTypes()
122 {
123 _TYPES_MAP = new HashMap<Object, Object>();
124
125 List<URL> list = new ArrayList<URL>();
126 try
127 {
128 Enumeration<URL> en = _getClassLoader().getResources(
129 "META-INF/faces-bean.properties");
130 while (en.hasMoreElements())
131 {
132 list.add(en.nextElement());
133 }
134
135 Collections.reverse(list);
136 }
137 catch (IOException ioe)
138 {
139 _LOG.severe(ioe);
140 return;
141 }
142
143 if (list.isEmpty())
144 {
145 if (_LOG.isInfo())
146 _LOG.info("NO_FACES_BEAN_PROPERTIES_FILES_LOCATED");
147 }
148
149 for(URL url : list)
150 {
151 _initializeBeanTypes(url);
152 }
153 }
154
155 static private void _initializeBeanTypes(URL url)
156 {
157 try
158 {
159 Properties properties = new Properties();
160 InputStream is = url.openStream();
161 try
162 {
163 properties.load(is);
164 if (_LOG.isFine())
165 _LOG.fine("Loading bean factory info from " + url);
166
167 _TYPES_MAP.putAll(properties);
168 }
169 finally
170 {
171 is.close();
172 }
173 }
174 catch (IOException ioe)
175 {
176 _LOG.severe("CANNOT_LOAD_URL", url);
177 _LOG.severe(ioe);
178 }
179 }
180
181
182 static private ClassLoader _getClassLoader()
183 {
184 ClassLoader loader = Thread.currentThread().getContextClassLoader();
185 if (loader == null)
186 loader = FacesBeanFactory.class.getClassLoader();
187 return loader;
188 }
189
190
191
192
193 static private String _buildTypeKey(
194 String beanType,
195 String rendererType)
196 {
197 if (rendererType != null)
198 {
199 StringBuilder typeKeyBuilder = _getSharedStringBuilder();
200
201 typeKeyBuilder.append(beanType).append('|').append(rendererType);
202
203 return typeKeyBuilder.toString();
204 }
205 else
206 return beanType;
207
208 }
209
210 static private void _cacheFacesBeanClass(
211 FacesBean bean,
212 String beanType,
213 String rendererType)
214 {
215
216 if(bean != null)
217 {
218 String typeKey = _buildTypeKey(beanType, rendererType);
219 _TYPES_CLASS.put(typeKey, bean.getClass());
220 }
221 }
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256 static private StringBuilder _getSharedStringBuilder()
257 {
258 StringBuilder sb = _STRING_BUILDER.get();
259
260 if (sb == null)
261 {
262 sb = new StringBuilder();
263 _STRING_BUILDER.set(sb);
264 }
265
266
267 sb.setLength(0);
268
269 return sb;
270 }
271
272 static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(FacesBeanFactory.class);
273 static private Map<Object, Object> _TYPES_MAP;
274 static private Map<String, Class<?>> _TYPES_CLASS = new ConcurrentHashMap<String, Class<?>>();
275 static private final ThreadLocal<StringBuilder> _STRING_BUILDER =
276 ThreadLocalUtils.newRequestThreadLocal();
277
278 static
279 {
280 _initializeBeanTypes();
281 }
282 }