1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.view.facelets;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.ObjectInputStream;
26 import java.io.ObjectOutputStream;
27 import java.io.OutputStream;
28 import java.io.Serializable;
29 import java.security.AccessController;
30 import java.security.PrivilegedActionException;
31 import java.security.PrivilegedExceptionAction;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.logging.Level;
37 import java.util.logging.Logger;
38 import java.util.zip.GZIPInputStream;
39 import java.util.zip.GZIPOutputStream;
40
41 import javax.faces.context.ExternalContext;
42 import javax.faces.context.FacesContext;
43
44 import org.apache.commons.collections.map.AbstractReferenceMap;
45 import org.apache.commons.collections.map.ReferenceMap;
46 import org.apache.myfaces.shared.renderkit.RendererUtils;
47 import org.apache.myfaces.shared.util.MyFacesObjectInputStream;
48
49
50
51
52
53
54
55
56
57
58
59 @Deprecated
60 class DefaultFaceletsStateManagementHelper
61 {
62
63 private static final Logger log = Logger.getLogger(DefaultFaceletsStateManagementHelper.class.getName());
64
65 private static final String SERIALIZED_VIEW_SESSION_ATTR=
66 DefaultFaceletsStateManagementHelper.class.getName() + ".SERIALIZED_VIEW";
67
68 public static final String SERIALIZED_VIEW_REQUEST_ATTR =
69 DefaultFaceletsStateManagementHelper.class.getName() + ".SERIALIZED_VIEW";
70
71 private static final String RESTORED_SERIALIZED_VIEW_REQUEST_ATTR =
72 DefaultFaceletsStateManagementHelper.class.getName() + ".RESTORED_SERIALIZED_VIEW";
73
74
75
76
77
78 private static final String NUMBER_OF_VIEWS_IN_SESSION_PARAM = "org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION";
79
80
81
82
83 private static final int DEFAULT_NUMBER_OF_VIEWS_IN_SESSION = 20;
84
85
86
87
88
89
90 private static final String SERIALIZE_STATE_IN_SESSION_PARAM = "org.apache.myfaces.SERIALIZE_STATE_IN_SESSION";
91
92
93
94
95
96
97
98 private static final String COMPRESS_SERVER_STATE_PARAM = "org.apache.myfaces.COMPRESS_STATE_IN_SESSION";
99
100
101
102
103 private static final boolean DEFAULT_COMPRESS_SERVER_STATE_PARAM = true;
104
105
106
107
108 private static final boolean DEFAULT_SERIALIZE_STATE_IN_SESSION = true;
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE = "org.apache.myfaces.CACHE_OLD_VIEWS_IN_SESSION_MODE";
134
135
136
137
138
139
140 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT = "hard-soft";
141
142 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT = "soft";
143
144 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK = "soft-weak";
145
146 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK = "weak";
147
148 private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF = "off";
149
150 private static final int UNCOMPRESSED_FLAG = 0;
151 private static final int COMPRESSED_FLAG = 1;
152
153 private static final int JSF_SEQUENCE_INDEX = 0;
154
155 protected Integer getServerStateId(Object[] state)
156 {
157 if (state != null)
158 {
159 Object serverStateId = state[JSF_SEQUENCE_INDEX];
160 if (serverStateId != null)
161 {
162 return Integer.valueOf((String) serverStateId, Character.MAX_RADIX);
163 }
164 }
165 return null;
166 }
167
168 protected void saveSerializedViewInServletSession(FacesContext context,
169 Object serializedView)
170 {
171 Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
172 SerializedViewCollection viewCollection = (SerializedViewCollection) sessionMap
173 .get(SERIALIZED_VIEW_SESSION_ATTR);
174 if (viewCollection == null)
175 {
176 viewCollection = new SerializedViewCollection();
177 sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
178 }
179 viewCollection.add(context, serializeView(context, serializedView));
180
181 sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
182 }
183
184 protected Object getSerializedViewFromServletSession(FacesContext context, String viewId, Integer sequence)
185 {
186 ExternalContext externalContext = context.getExternalContext();
187 Map<String, Object> requestMap = externalContext.getRequestMap();
188 Object serializedView = null;
189 if (requestMap.containsKey(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR))
190 {
191 serializedView = requestMap.get(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR);
192 }
193 else
194 {
195 SerializedViewCollection viewCollection = (SerializedViewCollection) externalContext
196 .getSessionMap().get(SERIALIZED_VIEW_SESSION_ATTR);
197 if (viewCollection != null)
198 {
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 if (sequence != null)
215 {
216 Object state = viewCollection.get(sequence, viewId);
217 if (state != null)
218 {
219 serializedView = deserializeView(state);
220 }
221 }
222 }
223 requestMap.put(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR, serializedView);
224 nextViewSequence(context);
225 }
226 return serializedView;
227 }
228
229 protected int getNextViewSequence(FacesContext context)
230 {
231 ExternalContext externalContext = context.getExternalContext();
232
233 if (!externalContext.getRequestMap().containsKey(RendererUtils.SEQUENCE_PARAM))
234 {
235 nextViewSequence(context);
236 }
237
238 Integer sequence = (Integer) externalContext.getRequestMap().get(RendererUtils.SEQUENCE_PARAM);
239 return sequence.intValue();
240 }
241
242 protected void nextViewSequence(FacesContext facescontext)
243 {
244 ExternalContext externalContext = facescontext.getExternalContext();
245 Object sessionObj = externalContext.getSession(true);
246 synchronized(sessionObj)
247
248 {
249 Map<String, Object> map = externalContext.getSessionMap();
250 Integer sequence = (Integer) map.get(RendererUtils.SEQUENCE_PARAM);
251 if(sequence == null || sequence.intValue() == Integer.MAX_VALUE)
252 {
253 sequence = Integer.valueOf(1);
254 }
255 else
256 {
257 sequence = Integer.valueOf(sequence.intValue() + 1);
258 }
259 map.put(RendererUtils.SEQUENCE_PARAM, sequence);
260 externalContext.getRequestMap().put(RendererUtils.SEQUENCE_PARAM, sequence);
261 }
262 }
263
264 protected Object serializeView(FacesContext context, Object serializedView)
265 {
266 if (log.isLoggable(Level.FINEST))
267 {
268 log.finest("Entering serializeView");
269 }
270
271 if(isSerializeStateInSession(context))
272 {
273 if (log.isLoggable(Level.FINEST))
274 {
275 log.finest("Processing serializeView - serialize state in session");
276 }
277
278 ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
279 try
280 {
281 OutputStream os = baos;
282 if(isCompressStateInSession(context))
283 {
284 if (log.isLoggable(Level.FINEST))
285 {
286 log.finest("Processing serializeView - serialize compressed");
287 }
288
289 os.write(COMPRESSED_FLAG);
290 os = new GZIPOutputStream(os, 1024);
291 }
292 else
293 {
294 if (log.isLoggable(Level.FINEST))
295 {
296 log.finest("Processing serializeView - serialize uncompressed");
297 }
298
299 os.write(UNCOMPRESSED_FLAG);
300 }
301
302 Object[] stateArray = (Object[]) serializedView;
303
304 ObjectOutputStream out = new ObjectOutputStream(os);
305 out.writeObject(stateArray[0]);
306 out.writeObject(stateArray[1]);
307 out.close();
308 baos.close();
309
310 if (log.isLoggable(Level.FINEST))
311 {
312 log.finest("Exiting serializeView - serialized. Bytes : " + baos.size());
313 }
314 return baos.toByteArray();
315 }
316 catch (IOException e)
317 {
318 log.log(Level.SEVERE, "Exiting serializeView - Could not serialize state: " + e.getMessage(), e);
319 return null;
320 }
321 }
322
323
324 if (log.isLoggable(Level.FINEST))
325 {
326 log.finest("Exiting serializeView - do not serialize state in session.");
327 }
328
329 return serializedView;
330
331 }
332
333
334
335
336
337
338
339 protected boolean isSerializeStateInSession(FacesContext context)
340 {
341 String value = context.getExternalContext().getInitParameter(
342 SERIALIZE_STATE_IN_SESSION_PARAM);
343 boolean serialize = DEFAULT_SERIALIZE_STATE_IN_SESSION;
344 if (value != null)
345 {
346 serialize = Boolean.valueOf(value);
347 }
348 return serialize;
349 }
350
351
352
353
354
355
356
357 protected boolean isCompressStateInSession(FacesContext context)
358 {
359 String value = context.getExternalContext().getInitParameter(
360 COMPRESS_SERVER_STATE_PARAM);
361 boolean compress = DEFAULT_COMPRESS_SERVER_STATE_PARAM;
362 if (value != null)
363 {
364 compress = Boolean.valueOf(value);
365 }
366 return compress;
367 }
368
369 protected Object deserializeView(Object state)
370 {
371 if (log.isLoggable(Level.FINEST))
372 {
373 log.finest("Entering deserializeView");
374 }
375
376 if(state instanceof byte[])
377 {
378 if (log.isLoggable(Level.FINEST))
379 {
380 log.finest("Processing deserializeView - deserializing serialized state. Bytes : "
381 + ((byte[]) state).length);
382 }
383
384 try
385 {
386 ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) state);
387 InputStream is = bais;
388 if(is.read() == COMPRESSED_FLAG)
389 {
390 is = new GZIPInputStream(is);
391 }
392 ObjectInputStream ois = null;
393 try
394 {
395 final ObjectInputStream in = new MyFacesObjectInputStream(is);
396 ois = in;
397 Object object = null;
398 if (System.getSecurityManager() != null)
399 {
400 object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object []>()
401 {
402 public Object[] run() throws PrivilegedActionException, IOException, ClassNotFoundException
403 {
404 return new Object[] {in.readObject(), in.readObject()};
405 }
406 });
407 }
408 else
409 {
410 object = new Object[] {in.readObject(), in.readObject()};
411 }
412 return object;
413 }
414 finally
415 {
416 if (ois != null)
417 {
418 ois.close();
419 ois = null;
420 }
421 }
422 }
423 catch (PrivilegedActionException e)
424 {
425 log.log(Level.SEVERE, "Exiting deserializeView - Could not deserialize state: " + e.getMessage(), e);
426 return null;
427 }
428 catch (IOException e)
429 {
430 log.log(Level.SEVERE, "Exiting deserializeView - Could not deserialize state: " + e.getMessage(), e);
431 return null;
432 }
433 catch (ClassNotFoundException e)
434 {
435 log.log(Level.SEVERE, "Exiting deserializeView - Could not deserialize state: " + e.getMessage(), e);
436 return null;
437 }
438 }
439 else if (state instanceof Object[])
440 {
441 if (log.isLoggable(Level.FINEST))
442 {
443 log.finest("Exiting deserializeView - state not serialized.");
444 }
445
446 return state;
447 }
448 else if(state == null)
449 {
450 log.severe("Exiting deserializeView - this method should not be called with a null-state.");
451 return null;
452 }
453 else
454 {
455 log.severe("Exiting deserializeView - this method should not be called with a state of type : "
456 + state.getClass());
457 return null;
458 }
459 }
460
461 protected static class SerializedViewCollection implements Serializable
462 {
463 private static final long serialVersionUID = -3734849062185115847L;
464
465 private final List<Object> _keys = new ArrayList<Object>(DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
466 private final Map<Object, Object> _serializedViews = new HashMap<Object, Object>();
467
468
469
470 private transient Map<Object, Object> _oldSerializedViews = null;
471
472 public synchronized void add(FacesContext context, Object state)
473 {
474 Object key = new SerializedViewKey(context);
475 _serializedViews.put(key, state);
476
477 while (_keys.remove(key))
478 {
479
480 }
481 _keys.add(key);
482
483 int views = getNumberOfViewsInSession(context);
484 while (_keys.size() > views)
485 {
486 key = _keys.remove(0);
487 Object oldView = _serializedViews.remove(key);
488 if (oldView != null &&
489 !CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF.equals(getCacheOldViewsInSessionMode(context)))
490 {
491 getOldSerializedViewsMap().put(key, oldView);
492 }
493 }
494 }
495
496
497
498
499
500
501
502 protected int getNumberOfViewsInSession(FacesContext context)
503 {
504 String value = context.getExternalContext().getInitParameter(
505 NUMBER_OF_VIEWS_IN_SESSION_PARAM);
506 int views = DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
507 if (value != null)
508 {
509 try
510 {
511 views = Integer.parseInt(value);
512 if (views <= 0)
513 {
514 log.severe("Configured value for " + NUMBER_OF_VIEWS_IN_SESSION_PARAM
515 + " is not valid, must be an value > 0, using default value ("
516 + DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
517 views = DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
518 }
519 }
520 catch (Throwable e)
521 {
522 log.log(Level.SEVERE, "Error determining the value for " + NUMBER_OF_VIEWS_IN_SESSION_PARAM
523 + ", expected an integer value > 0, using default value ("
524 + DEFAULT_NUMBER_OF_VIEWS_IN_SESSION + "): " + e.getMessage(), e);
525 }
526 }
527 return views;
528 }
529
530
531
532
533 @SuppressWarnings("unchecked")
534 protected Map<Object, Object> getOldSerializedViewsMap()
535 {
536 FacesContext context = FacesContext.getCurrentInstance();
537 if (_oldSerializedViews == null && context != null)
538 {
539 String cacheMode = getCacheOldViewsInSessionMode(context);
540 if (CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK.equals(cacheMode))
541 {
542 _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.WEAK, AbstractReferenceMap.WEAK, true);
543 }
544 else if (CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK.equals(cacheMode))
545 {
546 _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.WEAK, true);
547 }
548 else if (CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT.equals(cacheMode))
549 {
550 _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.SOFT, true);
551 }
552 else if (CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT.equals(cacheMode))
553 {
554 _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT);
555 }
556 }
557
558 return _oldSerializedViews;
559 }
560
561
562
563
564
565
566
567
568
569 protected String getCacheOldViewsInSessionMode(FacesContext context)
570 {
571 String value = context.getExternalContext().getInitParameter(
572 CACHE_OLD_VIEWS_IN_SESSION_MODE);
573 if (value == null)
574 {
575 return CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF;
576 }
577 else if (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT))
578 {
579 return CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT;
580 }
581 else if (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK))
582 {
583 return CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK;
584 }
585 else if (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK))
586 {
587 return CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK;
588 }
589 else if (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT))
590 {
591 return CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT;
592 }
593 else
594 {
595 return CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF;
596 }
597 }
598
599 public Object get(Integer sequence, String viewId)
600 {
601 Object key = new SerializedViewKey(viewId, sequence);
602 Object value = _serializedViews.get(key);
603 if (value == null)
604 {
605 Map<Object,Object> oldSerializedViewMap = getOldSerializedViewsMap();
606 if (oldSerializedViewMap != null)
607 {
608 value = oldSerializedViewMap.get(key);
609 }
610 }
611 return value;
612 }
613 }
614
615 protected static class SerializedViewKey implements Serializable
616 {
617 private static final long serialVersionUID = -1170697124386063642L;
618
619 private final String _viewId;
620 private final Integer _sequenceId;
621
622 public SerializedViewKey(String viewId, Integer sequence)
623 {
624 _sequenceId = sequence;
625 _viewId = viewId;
626 }
627
628 public SerializedViewKey(FacesContext context)
629 {
630 _sequenceId = RendererUtils.getViewSequence(context);
631 _viewId = context.getViewRoot().getViewId();
632 }
633
634 @Override
635 public int hashCode()
636 {
637 final int prime = 31;
638 int result = 1;
639 result = prime * result + ((_sequenceId == null) ? 0 : _sequenceId.hashCode());
640 result = prime * result + ((_viewId == null) ? 0 : _viewId.hashCode());
641 return result;
642 }
643
644 @Override
645 public boolean equals(Object obj)
646 {
647 if (this == obj)
648 {
649 return true;
650 }
651 if (obj == null)
652 {
653 return false;
654 }
655 if (getClass() != obj.getClass())
656 {
657 return false;
658 }
659 final SerializedViewKey other = (SerializedViewKey) obj;
660 if (_sequenceId == null)
661 {
662 if (other._sequenceId != null)
663 {
664 return false;
665 }
666 }
667 else if (!_sequenceId.equals(other._sequenceId))
668 {
669 return false;
670 }
671 if (_viewId == null)
672 {
673 if (other._viewId != null)
674 {
675 return false;
676 }
677 }
678 else if (!_viewId.equals(other._viewId))
679 {
680 return false;
681 }
682 return true;
683 }
684
685 }
686 }