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
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 int length = beanType.length() + 1 + rendererType.length();
199 StringBuilder typeKeyBuilder = new StringBuilder(length);
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 static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(FacesBeanFactory.class);
224 static private Map<Object, Object> _TYPES_MAP;
225 static private Map<String, Class<?>> _TYPES_CLASS = new ConcurrentHashMap<String, Class<?>>();
226
227 static
228 {
229 _initializeBeanTypes();
230 }
231 }