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 public class FacesBeanFactory
42 {
43
44
45
46
47 static public FacesBean createFacesBean(
48 Class<?> ownerClass,
49 String rendererType)
50 {
51 if (ownerClass == null)
52 return null;
53
54 String className = ownerClass.getName();
55 FacesBean bean = createFacesBean(className, rendererType);
56
57 if (bean == null && rendererType != null)
58 {
59 bean = createFacesBean(className, null);
60 _cacheFacesBeanClass(bean, className, rendererType);
61 }
62
63 if (bean == null)
64 {
65 bean = createFacesBean(ownerClass.getSuperclass(), rendererType);
66 _cacheFacesBeanClass(bean, className, rendererType);
67 }
68
69 return bean;
70 }
71
72 static public FacesBean createFacesBean(
73 String beanType,
74 String rendererType)
75 {
76 String typeKey = _buildTypeKey(beanType, rendererType);
77
78 Class<?> type = _TYPES_CLASS.get(typeKey);
79
80 if(type == null)
81 {
82 String className = (String) _TYPES_MAP.get(typeKey);
83 if (className == null)
84 return null;
85
86
87
88
89
90 try
91 {
92 type = _getClassLoader().loadClass(className);
93 _TYPES_CLASS.put(typeKey, type);
94 }
95 catch (ClassNotFoundException cnfe)
96 {
97 _LOG.severe("CANNOT_FIND_FACESBEAN", className);
98 _LOG.severe(cnfe);
99 }
100 }
101
102 try
103 {
104 return (FacesBean) type.newInstance();
105 }
106 catch (IllegalAccessException iae)
107 {
108 _LOG.severe("CANNOT_CREATE_FACESBEAN_INSTANCE", type.getName());
109 _LOG.severe(iae);
110 }
111 catch (InstantiationException ie)
112 {
113 _LOG.severe("CANNOT_CREATE_FACESBEAN_INSTANCE", type.getName());
114 _LOG.severe(ie);
115 }
116
117 return null;
118 }
119
120 static private void _initializeBeanTypes()
121 {
122 _TYPES_MAP = new HashMap<Object, Object>();
123
124 List<URL> list = new ArrayList<URL>();
125 try
126 {
127 Enumeration<URL> en = _getClassLoader().getResources(
128 "META-INF/faces-bean.properties");
129 while (en.hasMoreElements())
130 {
131 list.add(en.nextElement());
132 }
133
134 Collections.reverse(list);
135 }
136 catch (IOException ioe)
137 {
138 _LOG.severe(ioe);
139 return;
140 }
141
142 if (list.isEmpty())
143 {
144 if (_LOG.isInfo())
145 _LOG.info("NO_FACES_BEAN_PROPERTIES_FILES_LOCATED");
146 }
147
148 for(URL url : list)
149 {
150 _initializeBeanTypes(url);
151 }
152 }
153
154 static private void _initializeBeanTypes(URL url)
155 {
156 try
157 {
158 Properties properties = new Properties();
159 InputStream is = url.openStream();
160 try
161 {
162 properties.load(is);
163 if (_LOG.isFine())
164 _LOG.fine("Loading bean factory info from " + url);
165
166 _TYPES_MAP.putAll(properties);
167 }
168 finally
169 {
170 is.close();
171 }
172 }
173 catch (IOException ioe)
174 {
175 _LOG.severe("CANNOT_LOAD_URL", url);
176 _LOG.severe(ioe);
177 }
178 }
179
180
181 static private ClassLoader _getClassLoader()
182 {
183 ClassLoader loader = Thread.currentThread().getContextClassLoader();
184 if (loader == null)
185 loader = FacesBeanFactory.class.getClassLoader();
186 return loader;
187 }
188
189
190
191
192 static private String _buildTypeKey(
193 String beanType,
194 String rendererType)
195 {
196 if (rendererType != null)
197 {
198 StringBuilder typeKeyBuilder = _getSharedStringBuilder();
199
200 typeKeyBuilder.append(beanType).append('|').append(rendererType);
201
202 return typeKeyBuilder.toString();
203 }
204 else
205 return beanType;
206
207 }
208
209 static private void _cacheFacesBeanClass(
210 FacesBean bean,
211 String beanType,
212 String rendererType)
213 {
214
215 if(bean != null)
216 {
217 String typeKey = _buildTypeKey(beanType, rendererType);
218 _TYPES_CLASS.put(typeKey, bean.getClass());
219 }
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 static private StringBuilder _getSharedStringBuilder()
256 {
257 StringBuilder sb = _STRING_BUILDER.get();
258
259 if (sb == null)
260 {
261 sb = new StringBuilder();
262 _STRING_BUILDER.set(sb);
263 }
264
265
266 sb.setLength(0);
267
268 return sb;
269 }
270
271 static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(FacesBeanFactory.class);
272 static private Map<Object, Object> _TYPES_MAP;
273 static private Map<String, Class<?>> _TYPES_CLASS = new ConcurrentHashMap<String, Class<?>>();
274 static private final ThreadLocal<StringBuilder> _STRING_BUILDER =
275 ThreadLocalUtils.newRequestThreadLocal();
276
277 static
278 {
279 _initializeBeanTypes();
280 }
281 }