1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.application.pss;
20
21 import org.apache.myfaces.shared_impl.util.ClassUtils;
22
23 import javax.faces.component.UIViewRoot;
24 import javax.faces.component.UIComponent;
25 import javax.faces.context.FacesContext;
26 import java.util.*;
27
28
29
30
31 public class PartialTreeStructureManager
32 {
33 public static final String PARTIAL_STATE_CLASS_IDS = PartialTreeStructureManager.class.getName() + ".PARTIAL_STATE_MANAGER_COMPONENT_IDS";
34
35
36 private FacesContext _facesContext = null;
37
38 public PartialTreeStructureManager(FacesContext facesContext)
39 {
40 _facesContext = facesContext;
41 }
42
43 public Object buildTreeStructureToSave(UIViewRoot viewRoot, FacesContext facesContext)
44 {
45 Object savedStateTree = viewRoot.processSaveState(facesContext);
46 if (viewRoot instanceof UIViewRootWrapper) {
47
48 return internalBuildInitalTreeStructureToSave(viewRoot,facesContext, savedStateTree,0);
49 }
50 else return internalBuildTreeStructureToSave(viewRoot,facesContext, savedStateTree,0);
51 }
52
53 private TreeStructComponent internalBuildInitalTreeStructureToSave(UIComponent component,FacesContext facesContext, Object state, int childIndex)
54 {
55
56 Object myState = ((Object[])state)[0];
57 Map facetStateMap = (Map)((Object[])state)[1];
58 List childrenStateList = (List)((Object[])state)[2];
59
60 TreeStructComponent structComp = new TreeStructComponent(convertStringToComponentClassId(facesContext,component.getClass().getName()),
61 component.getId(),myState,component.isTransient());
62
63
64 if (component.getChildCount() > 0)
65 {
66 List childList = component.getChildren();
67 List structChildList = new ArrayList();
68 for (int i = 0, len = childList.size(); i < len; i++)
69 {
70 UIComponent child = (UIComponent)childList.get(i);
71 if (!child.isTransient())
72 {
73
74 TreeStructComponent structChild = internalBuildInitalTreeStructureToSave(child,facesContext,childrenStateList != null ? childrenStateList.get(childIndex++):null,0);
75 structChildList.add(structChild);
76 }
77 else
78 {
79
80 child.setTransient(false);
81 TreeStructComponent structChild = internalBuildInitalTreeStructureToSave(child,facesContext,child.processSaveState(facesContext),0);
82 structChildList.add(structChild);
83 child.setTransient(true);
84
85 }
86 }
87 TreeStructComponent[] childArray = (TreeStructComponent[])structChildList.toArray(new TreeStructComponent[structChildList.size()]);
88 structComp.setChildren(childArray);
89 }
90
91
92 Map facetMap = component.getFacets();
93 if (!facetMap.isEmpty())
94 {
95 List structFacetList = new ArrayList();
96 for (Iterator it = facetMap.entrySet().iterator(); it.hasNext(); )
97 {
98 Map.Entry entry = (Map.Entry)it.next();
99 UIComponent child = (UIComponent)entry.getValue();
100 String facetName = (String)entry.getKey();
101 if (!child.isTransient())
102 {
103
104 TreeStructComponent structChild = internalBuildInitalTreeStructureToSave(child,facesContext,facetStateMap.get(facetName),0);
105 structFacetList.add(new Object[] {facetName, structChild});
106 }
107 else
108 {
109
110 child.setTransient(false);
111 TreeStructComponent structChild = internalBuildInitalTreeStructureToSave(child,facesContext,child.processSaveState(facesContext),0);
112 structFacetList.add(new Object[] {facetName, structChild});
113 child.setTransient(true);
114 }
115 }
116 Object[] facetArray = structFacetList.toArray(new Object[structFacetList.size()]);
117 structComp.setFacets(facetArray);
118 }
119
120 return structComp;
121 }
122
123 private TreeStructComponent internalBuildTreeStructureToSave(UIComponent component,FacesContext facesContext, Object state, int childIndex)
124 {
125
126 Object myState = ((Object[])state)[0];
127 Map facetStateMap = (Map)((Object[])state)[1];
128 List childrenStateList = (List)((Object[])state)[2];
129
130 TreeStructComponent structComp = new TreeStructComponent(convertStringToComponentClassId(facesContext,component.getClass().getName()),
131 component.getId(),myState,component.isTransient());
132
133
134 if (component.getChildCount() > 0)
135 {
136 List childList = component.getChildren();
137 List structChildList = new ArrayList();
138 for (int i = 0, len = childList.size(); i < len; i++)
139 {
140 UIComponent child = (UIComponent)childList.get(i);
141 if (!child.isTransient())
142 {
143
144 TreeStructComponent structChild = internalBuildTreeStructureToSave(child,facesContext,childrenStateList != null ? childrenStateList.get(childIndex++):null,0);
145 structChildList.add(structChild);
146 }
147 }
148 TreeStructComponent[] childArray = (TreeStructComponent[])structChildList.toArray(new TreeStructComponent[structChildList.size()]);
149 structComp.setChildren(childArray);
150 }
151
152
153 Map facetMap = component.getFacets();
154 if (!facetMap.isEmpty())
155 {
156 List structFacetList = new ArrayList();
157 for (Iterator it = facetMap.entrySet().iterator(); it.hasNext(); )
158 {
159 Map.Entry entry = (Map.Entry)it.next();
160 UIComponent child = (UIComponent)entry.getValue();
161 String facetName = (String)entry.getKey();
162 if (!child.isTransient())
163 {
164
165 TreeStructComponent structChild = internalBuildTreeStructureToSave(child,facesContext,facetStateMap.get(facetName),0);
166 structFacetList.add(new Object[] {facetName, structChild});
167 }
168
169 }
170 Object[] facetArray = structFacetList.toArray(new Object[structFacetList.size()]);
171 structComp.setFacets(facetArray);
172 }
173
174 return structComp;
175 }
176
177
178
179 public UIViewRoot restoreTreeStructure(FacesContext facesContext,Object treeStructRoot)
180 {
181 if (treeStructRoot instanceof TreeStructComponent)
182 {
183 return (UIViewRoot)internalRestoreTreeStructure((TreeStructComponent)treeStructRoot,facesContext);
184 }
185 else
186 {
187 throw new IllegalArgumentException("TreeStructure of type " + treeStructRoot.getClass().getName() + " is not supported.");
188 }
189 }
190
191 private UIComponent internalRestoreTreeStructure(TreeStructComponent treeStructComp,FacesContext facesContext)
192 {
193 String compClass = convertComponentClassIdToString(facesContext,treeStructComp.getComponentClass());
194 String compId = treeStructComp.getComponentId();
195 UIComponent component = (UIComponent) ClassUtils.newInstance(compClass);
196 component.setId(compId);
197 component.setTransient(treeStructComp.isTransient());
198
199
200 TreeStructComponent[] childArray = treeStructComp.getChildren();
201 if (childArray != null)
202 {
203 List childList = component.getChildren();
204 for (int i = 0, len = childArray.length; i < len; i++)
205 {
206 UIComponent child = internalRestoreTreeStructure(childArray[i],facesContext);
207 childList.add(child);
208 }
209 }
210
211
212 Object[] facetArray = treeStructComp.getFacets();
213 if (facetArray != null)
214 {
215 Map facetMap = component.getFacets();
216 for (int i = 0, len = facetArray.length; i < len; i++)
217 {
218 TreeStructComponent structChild = (TreeStructComponent)((Object[])facetArray[i])[1];
219 String facetName = (String)((Object[])facetArray[i])[0];
220 UIComponent child = internalRestoreTreeStructure(structChild,facesContext);
221 facetMap.put(facetName, child);
222 }
223 }
224
225
226 return component;
227 }
228
229
230
231 private String convertComponentClassIdToString(FacesContext facesContext,Integer classId){
232 Object[] idmaps = (Object[])facesContext.getExternalContext().getApplicationMap().get(PARTIAL_STATE_CLASS_IDS);
233
234 if ( idmaps== null)
235 {
236
237 idmaps = new Object[2];
238
239 idmaps[0] = new HashMap();
240 idmaps[1] = new HashMap();
241 facesContext.getExternalContext().getApplicationMap().put(PARTIAL_STATE_CLASS_IDS,idmaps);
242 }
243 return (String)((HashMap)idmaps[0]).get(classId);
244 }
245
246 private Integer convertStringToComponentClassId(FacesContext facesContext,String stringToConvert){
247
248
249
250 if (stringToConvert.equalsIgnoreCase("org.apache.myfaces.application.pss.UIViewRootWrapper")) {
251 stringToConvert = "javax.faces.component.UIViewRoot";
252 }
253
254 Object[] idmaps = (Object[])facesContext.getExternalContext().getApplicationMap().get(PARTIAL_STATE_CLASS_IDS);
255
256 if ( idmaps== null)
257 {
258
259 idmaps = new Object[2];
260
261 idmaps[0] = new HashMap();
262 idmaps[1] = new HashMap();
263 }
264 Integer idInMap = (Integer)((HashMap)idmaps[1]).get(stringToConvert);
265 HashMap idToStringMap=((HashMap)idmaps[0]);
266 HashMap stringToIdMap=((HashMap)idmaps[1]);
267
268 if (idInMap == null )
269 {
270
271 Integer id = new Integer(stringToIdMap.size());
272
273 stringToIdMap.put(stringToConvert,id);
274 idToStringMap.put(id,stringToConvert);
275 }
276 facesContext.getExternalContext().getApplicationMap().put(PARTIAL_STATE_CLASS_IDS,idmaps);
277 return (Integer)stringToIdMap.get(stringToConvert);
278 }
279
280
281 }