1
2
3
4
5 package org.rcfaces.core.internal.component;
6
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.HashSet;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14
15 import javax.el.ValueExpression;
16 import javax.faces.FacesException;
17 import javax.faces.component.UIComponentBase;
18 import javax.faces.context.FacesContext;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.rcfaces.core.internal.util.ClassLocator;
23 import org.rcfaces.core.internal.util.StateHolderTools;
24
25
26
27
28
29
30 public class BasicDeltaPropertiesAccessor extends AbstractPropertiesAccessor
31 implements IDeltaPropertiesAccessor {
32 private static final String REVISION = "$Revision: 1.17 $";
33
34 private static final Log LOG = LogFactory
35 .getLog(BasicDeltaPropertiesAccessor.class);
36
37 private static final int PROPERTY_INITIAL_SIZE = 8;
38
39 private static final boolean CLONE_VALUE = true;
40
41 private static final Object UNDEFINED = new Object();
42
43 private final IPropertiesAccessor parent;
44
45 private Map properties;
46
47
48 private static IUnproxifyValueExpression unproxifyValueExpression = null;
49
50 static {
51 try {
52 ClassLocator.load("org.apache.jasper.el.JspValueExpression", BasicDeltaPropertiesAccessor.class, null);
53
54 Class cl =ClassLocator.load("org.rcfaces.core.internal.jasper.JasperUnproxifyValueExpression", BasicDeltaPropertiesAccessor.class, null);
55 unproxifyValueExpression= (IUnproxifyValueExpression) cl.newInstance();
56
57 } catch (ClassNotFoundException ex) {
58 LOG.error(ex.getMessage());
59 } catch (Throwable ex) {
60 LOG.error(ex.getMessage());
61 }
62 }
63
64
65 public BasicDeltaPropertiesAccessor(IPropertiesAccessor parent) {
66 this.parent = parent;
67 }
68
69 public void commitProperties(FacesContext context) {
70 if (hasModifiedProperties() == false) {
71 return;
72 }
73
74 parent.putAll(context, properties.entrySet(), UNDEFINED);
75 }
76
77 public boolean isPropertySetted(String propertyName) {
78 if (properties != null) {
79 Object value = properties.get(propertyName);
80 if (value != null) {
81 if (value == UNDEFINED) {
82 return false;
83 }
84
85 return true;
86 }
87 }
88
89 return parent.isPropertySetted(propertyName);
90 }
91
92 public Object getProperty(String propertyName) {
93 if (properties != null && properties.isEmpty() == false) {
94 Object ret = properties.get(propertyName);
95 if (ret != null) {
96 if (ret == UNDEFINED) {
97 return null;
98 }
99
100 return ret;
101 }
102 }
103
104 Object value = parent.getProperty(propertyName);
105
106 if (CLONE_VALUE && value != null) {
107 Object original = value;
108
109 if (value instanceof Map) {
110 value = new HashMap((Map) value);
111
112 } else if (value instanceof List) {
113 value = new ArrayList((List) value);
114
115 } else if (value instanceof Set) {
116 value = new HashSet((Set) value);
117 }
118
119 if (original != value) {
120 setProperty(null, propertyName, value);
121 }
122 }
123
124 return value;
125 }
126
127 public Object setProperty(FacesContext facesContext, String propertyName,
128 Object value) {
129
130 Object initialValue = parent.getProperty(propertyName);
131
132
133 if (initialValue == value
134 || (initialValue != null && initialValue.equals(value))) {
135
136 if (properties != null) {
137 return properties.remove(propertyName);
138 }
139
140
141 return initialValue;
142 }
143
144
145 if (value == null) {
146 value = UNDEFINED;
147 }
148
149 if (properties == null) {
150 properties = createMap(PROPERTY_INITIAL_SIZE);
151 }
152
153 Object old = properties.put(propertyName, value);
154 if (old == UNDEFINED) {
155 return initialValue;
156 }
157
158 return old;
159 }
160
161 public void setProperty(FacesContext facesContext, String propertyName,
162 ValueExpression valueExpression) {
163
164 Object initialValue = parent.getProperty(propertyName);
165
166 if (unproxifyValueExpression!=null) {
167 valueExpression = unproxifyValueExpression.process(valueExpression);
168 }
169
170 if (initialValue != null && initialValue.equals(valueExpression)) {
171 return;
172 }
173
174 LOG.error("Can not change a ValueExpression property '" + propertyName
175 + "' valueExpression=" + valueExpression + " original='"
176 + initialValue + "'.");
177
178 throw new FacesException(
179 "Can not set a ValueExpression while a delta phase.");
180 }
181
182 public Object removeProperty(FacesContext facesContext, String propertyName) {
183
184 Object initialValue = parent.getProperty(propertyName);
185 if (initialValue != null) {
186
187
188 if (properties == null) {
189 properties = createMap(PROPERTY_INITIAL_SIZE);
190 }
191
192
193 Object old = properties.put(propertyName, UNDEFINED);
194
195 if (old == UNDEFINED) {
196
197 return null;
198 }
199
200 if (old != null) {
201
202 return old;
203 }
204
205
206 return initialValue;
207 }
208
209
210
211
212 Object old = properties.put(propertyName, UNDEFINED);
213 if (old == UNDEFINED) {
214
215 return null;
216 }
217
218 return old;
219 }
220
221 public Object saveState(FacesContext context) {
222 if (hasModifiedProperties() == false) {
223 return null;
224 }
225
226 Object rets[] = new Object[properties.size() * 2];
227 int i = 0;
228 for (Iterator it = properties.entrySet().iterator(); it.hasNext();) {
229 Map.Entry entry = (Map.Entry) it.next();
230
231 rets[i++] = entry.getKey();
232
233 Object value = entry.getValue();
234 if (value == UNDEFINED || value == null) {
235 i++;
236 continue;
237 }
238
239 if (StateHolderTools.isPrimitive(value) == false) {
240 rets[i++] = UIComponentBase.saveAttachedState(context, value);
241
242 continue;
243 }
244
245 rets[i++] = value;
246 }
247
248 return rets;
249 }
250
251 public void restoreState(FacesContext context, Object state) {
252 if (state == null) {
253 return;
254 }
255
256 if ((state instanceof Object[]) == false) {
257 throw new FacesException(
258 "Bad serialized format ! (not an objects array !)");
259 }
260
261 Object datas[] = (Object[]) state;
262
263 properties = new HashMap(datas.length / 2);
264
265 for (int i = 0; i < datas.length;) {
266 String key = (String) datas[i++];
267 Object value = datas[i++];
268
269 if (StateHolderTools.isPrimitive(value) == false) {
270 value = UIComponentBase.restoreAttachedState(context, value);
271 }
272
273 setProperty(context, key, value);
274 }
275 }
276
277 public void release() {
278 properties = null;
279 }
280
281 public Set keySet() {
282 Set l = parent.keySet();
283 if (properties == null || properties.isEmpty()) {
284
285 return l;
286 }
287
288 Set v = new HashSet(l.size() + properties.size());
289 v.addAll(l);
290
291 for (Iterator it = properties.entrySet().iterator(); it.hasNext();) {
292 Map.Entry entry = (Map.Entry) it.next();
293
294 String key = (String) entry.getKey();
295 Object value = entry.getValue();
296
297 if (value == UNDEFINED) {
298 v.remove(key);
299 continue;
300 }
301
302 v.add(key);
303 }
304
305 return v;
306 }
307
308 public boolean hasModifiedProperties() {
309 return properties != null && properties.size() > 0;
310 }
311
312 public int size() {
313 if (hasModifiedProperties() == false) {
314 return parent.size();
315 }
316
317 Set l = parent.keySet();
318
319 int cnt = l.size();
320 for (Iterator it = properties.entrySet().iterator(); it.hasNext();) {
321 Map.Entry entry = (Map.Entry) it.next();
322
323 String key = (String) entry.getKey();
324 Object value = entry.getValue();
325
326 boolean contains = l.contains(key);
327 if (contains) {
328 if (value == UNDEFINED) {
329
330 cnt--;
331 }
332
333 continue;
334 }
335
336 if (value == UNDEFINED) {
337
338 continue;
339 }
340
341
342 cnt++;
343 }
344
345 return cnt;
346 }
347
348 public String toString() {
349 if (hasModifiedProperties() == false) {
350 return "{Delta: NONE}";
351 }
352
353 Set keys = keySet();
354
355 String s = "{Delta: ";
356
357 boolean first = true;
358 for (Iterator it = keys.iterator(); it.hasNext();) {
359 String key = (String) it.next();
360
361 if (first) {
362 first = false;
363 } else {
364 s += ",";
365 }
366
367 if (properties.containsKey(key)) {
368 s += "(D)";
369 }
370 s += key + "=";
371
372 Object obj = getProperty(key);
373 if (obj instanceof ValueExpression) {
374 s += "'" + ((ValueExpression) obj).getExpressionString() + "'";
375
376 } else if (obj != null) {
377 s += "'" + obj + "'";
378
379 } else {
380 s += obj;
381 }
382 }
383
384 s += "}";
385
386 return s;
387 }
388 }