1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.component;
20
21 import java.io.Externalizable;
22 import java.io.IOException;
23 import java.io.ObjectOutput;
24 import java.io.ObjectInput;
25
26 import javax.faces.component.UIComponent;
27 import javax.faces.context.FacesContext;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
33
34
35
36
37
38
39
40
41
42 class TreeState implements Externalizable
43 {
44 public TreeState()
45 {
46 _empty = true;
47 }
48
49 public boolean isEmpty()
50 {
51 return _empty;
52 }
53
54 @SuppressWarnings("unchecked")
55 public void restoreState(FacesContext context, UIXComponentBase component)
56 {
57 component.restoreState(context, _state);
58 int childCount = component.getChildCount();
59 int arrayCount = (_children == null) ? 0 : _children.length;
60 int transientCount = 0;
61
62
63
64
65
66 if (childCount != arrayCount)
67 {
68 List children = component.getChildren();
69 for (int i = 0; i < childCount; i++)
70 {
71 UIComponent child = (UIComponent) children.get(i);
72 if (child.isTransient())
73 transientCount++;
74 }
75 }
76
77 if (arrayCount + transientCount != childCount)
78 {
79 if (_LOG.isWarning())
80 _LOG.warning("SAVED_CHILD_COUNT_NOT_MATCH", new Object[] {arrayCount, childCount});
81 }
82
83 else
84 {
85 List children = component.getChildren();
86 int arrayIndex = 0;
87 for (int i = 0; i < childCount; i++)
88 {
89 UIComponent child = (UIComponent) children.get(i);
90 if (child.isTransient())
91 {
92 continue;
93 }
94 else
95 {
96 child.processRestoreState(context, _children[arrayIndex]);
97 arrayIndex++;
98 }
99 }
100 }
101
102
103 if (_facets != null)
104 {
105 assert(_facets.length % 2 == 0);
106
107 int facetCount = _facets.length / 2;
108
109 if (facetCount < component.getFacetCount())
110 {
111 if (_LOG.isWarning())
112 _LOG.warning("FACETS_STATE_MISSING_WILLNOT_RESTORE", component);
113 }
114
115
116 for (int i = 0; i < facetCount; i++)
117 {
118 assert((_facets[i * 2] == null) ||
119 (_facets[i * 2] instanceof String));
120
121 String facetName = (String) _facets[i * 2];
122 if (facetName == null)
123 continue;
124
125 Object facetState = _facets[i * 2 + 1];
126 UIComponent facet = component.getFacet(facetName);
127 if (facet == null)
128 {
129 if (_LOG.isWarning())
130 _LOG.warning("DISCARDING_SAVED_STATE", facetName);
131 }
132 else
133 {
134 if (facet.isTransient())
135 {
136 if (facetState != null)
137 {
138 if (_LOG.isWarning())
139 _LOG.warning("SAVED_STATE_INCLUDE_TRANSIENT_COMPONENT_STATE", facet);
140 }
141 }
142 else
143 {
144 facet.processRestoreState(context, facetState);
145 }
146 }
147 }
148 }
149 }
150
151 @SuppressWarnings("unchecked")
152 public void saveState(FacesContext context, UIXComponentBase component)
153 {
154
155 _state = component.saveState(context);
156 if (_state != null)
157 _empty = false;
158
159
160 int childCount = component.getChildCount();
161 if (childCount == 0)
162 {
163 _children = null;
164 }
165 else
166 {
167 _children = new Object[childCount];
168 List children = component.getChildren();
169 int j = 0;
170 for (int i = 0; i < childCount; i++)
171 {
172 UIComponent child = (UIComponent) children.get(i);
173 if (!child.isTransient())
174 {
175 Object childState = child.processSaveState(context);
176 if (childState != null)
177 {
178 _empty = false;
179 _children[j] = childState;
180 }
181
182 j++;
183 }
184 }
185
186
187
188 if (j < childCount)
189 {
190 Object[] newChildren = new Object[j];
191 System.arraycopy(_children, 0, newChildren, 0, j);
192 _children = newChildren;
193 }
194 }
195
196
197 int facetCount = component.getFacetCount();
198 if (facetCount == 0)
199 {
200 _facets = null;
201 }
202 else
203 {
204 _facets = new Object[facetCount * 2];
205 int i = 0;
206 Set<Map.Entry<String, UIComponent>> entries = component.getFacets().entrySet();
207 for(Map.Entry<String, UIComponent> entry : entries)
208 {
209 UIComponent facet = entry.getValue();
210
211
212 if (facet.isTransient())
213 continue;
214
215 Object facetState = facet.processSaveState(context);
216 if (facetState != null)
217 {
218 _empty = false;
219 _facets[2 * i] = entry.getKey();
220 _facets[2 * i + 1] = facetState;
221 }
222
223 i++;
224 }
225
226
227 if (i == 0)
228 _facets = null;
229 }
230 }
231
232
233
234
235
236
237 public void writeExternal(ObjectOutput out) throws IOException
238 {
239 out.writeObject(_state);
240 out.writeObject(_facets);
241 out.writeObject(_children);
242 }
243
244 public void readExternal(ObjectInput in)
245 throws IOException, ClassNotFoundException
246 {
247 _state = in.readObject();
248 _facets = (Object[]) in.readObject();
249 _children = (Object[]) in.readObject();
250 }
251
252
253 private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(TreeState.class);
254
255 private Object[] _facets;
256 private Object[] _children;
257 private Object _state;
258 private boolean _empty;
259
260 private static final long serialVersionUID = 1L;
261 }