1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application.viewstate;
20
21 import java.util.Map;
22 import java.util.Random;
23 import javax.faces.context.ExternalContext;
24 import javax.faces.context.FacesContext;
25 import javax.xml.bind.DatatypeConverter;
26
27 import org.apache.myfaces.shared.renderkit.RendererUtils;
28 import org.apache.myfaces.shared.util.WebConfigParamUtils;
29
30
31
32
33 class RandomKeyFactory extends KeyFactory<byte[]>
34 {
35 private final Random random;
36 private final int length;
37
38 public RandomKeyFactory(FacesContext facesContext)
39 {
40 length = WebConfigParamUtils.getIntegerInitParameter(
41 facesContext.getExternalContext(),
42 ServerSideStateCacheImpl.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM,
43 ServerSideStateCacheImpl.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM_DEFAULT);
44 random = new Random(((int) System.nanoTime()) + this.hashCode());
45 }
46
47 public Integer generateCounterKey(FacesContext facesContext)
48 {
49 ExternalContext externalContext = facesContext.getExternalContext();
50 Object sessionObj = externalContext.getSession(true);
51 Integer sequence;
52 synchronized (sessionObj)
53 {
54 Map<String, Object> map = externalContext.getSessionMap();
55 sequence = (Integer) map.get(RendererUtils.SEQUENCE_PARAM);
56 if (sequence == null || sequence == Integer.MAX_VALUE)
57 {
58 sequence = 1;
59 }
60 else
61 {
62 sequence = sequence + 1;
63 }
64 map.put(RendererUtils.SEQUENCE_PARAM, sequence);
65 }
66 return sequence;
67 }
68
69 @Override
70 public byte[] generateKey(FacesContext facesContext)
71 {
72 byte[] array = new byte[length];
73 byte[] key = new byte[length + 4];
74
75 random.nextBytes(array);
76 for (int i = 0; i < array.length; i++)
77 {
78 key[i] = array[i];
79 }
80 int value = generateCounterKey(facesContext);
81 key[array.length] = (byte) (value >>> 24);
82 key[array.length + 1] = (byte) (value >>> 16);
83 key[array.length + 2] = (byte) (value >>> 8);
84 key[array.length + 3] = (byte) (value);
85 return key;
86 }
87
88 @Override
89 public String encode(byte[] key)
90 {
91 return DatatypeConverter.printHexBinary(key);
92 }
93
94 @Override
95 public byte[] decode(String value)
96 {
97 try
98 {
99 return DatatypeConverter.parseHexBinary(value);
100 }
101 catch (IllegalArgumentException ex)
102 {
103
104
105 }
106 return null;
107 }
108
109 }