1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.cdi.model;
21
22 import java.lang.reflect.Constructor;
23 import java.lang.reflect.InvocationTargetException;
24 import java.util.Collections;
25 import java.util.Map;
26 import java.util.concurrent.ConcurrentHashMap;
27 import javax.enterprise.context.ApplicationScoped;
28 import javax.faces.FacesException;
29 import javax.faces.context.FacesContext;
30 import javax.faces.model.DataModel;
31
32
33
34
35 @ApplicationScoped
36 public class FacesDataModelClassBeanHolder extends DataModelBuilder
37 {
38 private volatile Map<Class<?>,Class<? extends DataModel>>
39 classInstanceToDataModelWrapperClassMap = new ConcurrentHashMap<Class<?>, Class<? extends DataModel>>();
40 private Map<Class<?>,Class<? extends DataModel>> umclassInstanceToDataModelWrapperClassMap = null;
41
42
43
44
45 public Map<Class<?>,Class<? extends DataModel>> getClassInstanceToDataModelWrapperClassMap()
46 {
47 if (umclassInstanceToDataModelWrapperClassMap == null)
48 {
49 umclassInstanceToDataModelWrapperClassMap =
50 Collections.unmodifiableMap(classInstanceToDataModelWrapperClassMap);
51 }
52 return umclassInstanceToDataModelWrapperClassMap;
53 }
54
55 public void addFacesDataModel(Class<?> forClass, Class<? extends DataModel> dataModelClass)
56 {
57 classInstanceToDataModelWrapperClassMap.put(forClass, dataModelClass);
58 }
59
60 @Override
61 public DataModel createDataModel(FacesContext facesContext, Class<?> forClass, Object value)
62 {
63 Class<? extends DataModel> dataModelClass = getClassInstanceToDataModelWrapperClassMap().get(forClass);
64 if (dataModelClass != null)
65 {
66 return createDataModel(forClass, value, dataModelClass);
67 }
68 else
69 {
70
71 Class<?> entryForClass = null;
72 Class<? extends DataModel> valueForClass = null;
73 for (Map.Entry<Class<?>,Class<? extends DataModel>> entry :
74 getClassInstanceToDataModelWrapperClassMap().entrySet())
75 {
76 if (entry.getKey().isAssignableFrom(forClass))
77 {
78 if (entryForClass != null)
79 {
80
81
82 if (entryForClass.isAssignableFrom(entry.getKey()))
83 {
84 entryForClass = entry.getKey();
85 valueForClass = entry.getValue();
86 }
87 }
88 else
89 {
90 entryForClass = entry.getKey();
91 valueForClass = entry.getValue();
92 }
93 }
94 }
95 if(entryForClass != null)
96 {
97 return createDataModel(forClass, value, valueForClass);
98 }
99 }
100 return null;
101 }
102
103 private DataModel createDataModel(Class<?> forClass, Object value,
104 Class<? extends DataModel> dataModelClass)
105 {
106 try
107 {
108 Constructor selectedConstructor = null;
109 boolean equalsFound = false;
110 for (Constructor constructor : dataModelClass.getConstructors())
111 {
112 if (constructor.getParameterCount() == 1)
113 {
114 if (constructor.getParameterTypes()[0].equals(forClass))
115 {
116 selectedConstructor = constructor;
117 equalsFound = true;
118 }
119 else if (constructor.getParameterTypes()[0].isAssignableFrom(forClass))
120 {
121 if (!equalsFound)
122 {
123 selectedConstructor = constructor;
124 }
125 }
126 }
127 }
128
129 Constructor constructor = null;
130 if (selectedConstructor != null)
131 {
132 constructor = selectedConstructor;
133 return (DataModel) constructor.newInstance(value);
134 }
135 else
136 {
137 constructor = dataModelClass.getConstructor();
138 DataModel dm = (DataModel) constructor.newInstance();
139 dm.setWrappedData(value);
140 return dm;
141 }
142 }
143 catch (NoSuchMethodException ex)
144 {
145 throw new FacesException(
146 "Cannot find constructor of DataModel with "+forClass.getName()+" as parameter", ex);
147 }
148 catch (SecurityException ex)
149 {
150 throw new FacesException(
151 "Cannot access constructor of DataModel with "+forClass.getName()+" as parameter", ex);
152 }
153 catch (InstantiationException ex)
154 {
155 throw new FacesException(
156 "Cannot access constructor of DataModel with "+forClass.getName()+" as parameter", ex);
157 }
158 catch (IllegalAccessException ex)
159 {
160 throw new FacesException(
161 "Cannot access constructor of DataModel with "+forClass.getName()+" as parameter", ex);
162 }
163 catch (IllegalArgumentException ex)
164 {
165 throw new FacesException(
166 "Cannot find constructor of DataModel with "+forClass.getName()+" as parameter", ex);
167 }
168 catch (InvocationTargetException ex)
169 {
170 throw new FacesException(
171 "Cannot find constructor of DataModel with "+forClass.getName()+" as parameter", ex);
172 }
173 }
174 }