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.Serializable;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.EnumSet;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30 import javax.el.ValueExpression;
31 import javax.faces.FacesException;
32 import javax.faces.FactoryFinder;
33 import javax.faces.application.ProjectStage;
34 import javax.faces.application.StateManager;
35 import javax.faces.component.ContextCallback;
36 import javax.faces.component.UIComponent;
37 import javax.faces.component.UIComponentBase;
38 import javax.faces.component.UIViewRoot;
39 import javax.faces.component.visit.VisitCallback;
40 import javax.faces.component.visit.VisitContext;
41 import javax.faces.component.visit.VisitContextFactory;
42 import javax.faces.component.visit.VisitHint;
43 import javax.faces.component.visit.VisitResult;
44 import javax.faces.context.FacesContext;
45 import javax.faces.event.PostAddToViewEvent;
46 import javax.faces.event.PreRemoveFromViewEvent;
47 import javax.faces.event.SystemEvent;
48 import javax.faces.event.SystemEventListener;
49 import javax.faces.render.RenderKitFactory;
50 import javax.faces.render.ResponseStateManager;
51 import javax.faces.view.StateManagementStrategy;
52 import javax.faces.view.ViewDeclarationLanguage;
53 import javax.faces.view.ViewDeclarationLanguageFactory;
54 import javax.faces.view.ViewMetadata;
55 import org.apache.myfaces.application.StateManagerImpl;
56 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
57 import org.apache.myfaces.context.RequestViewContext;
58 import org.apache.myfaces.shared.config.MyfacesConfig;
59 import org.apache.myfaces.shared.util.ClassUtils;
60 import org.apache.myfaces.shared.util.HashMapUtils;
61 import org.apache.myfaces.shared.util.WebConfigParamUtils;
62 import org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils;
63 import org.apache.myfaces.view.facelets.pool.ViewEntry;
64 import org.apache.myfaces.view.facelets.pool.ViewPool;
65 import org.apache.myfaces.view.facelets.pool.ViewStructureMetadata;
66 import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
67 import org.apache.myfaces.view.facelets.tag.jsf.FaceletState;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 public class DefaultFaceletsStateManagementStrategy extends StateManagementStrategy
107 {
108 public static final String CLIENTIDS_ADDED = "oam.CLIENTIDS_ADDED";
109
110 public static final String CLIENTIDS_REMOVED = "oam.CLIENTIDS_REMOVED";
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public static final String COMPONENT_ADDED_AFTER_BUILD_VIEW = "oam.COMPONENT_ADDED_AFTER_BUILD_VIEW";
127
128
129
130
131
132
133
134
135
136 @Deprecated
137 @JSFWebConfigParam(since="2.0.8, 2.1.2", defaultValue="true", expectedValues="true, false",
138 group="state", tags="performance", deprecated=true)
139 public static final String SAVE_STATE_WITH_VISIT_TREE_ON_PSS
140 = "org.apache.myfaces.SAVE_STATE_WITH_VISIT_TREE_ON_PSS";
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 @JSFWebConfigParam(since="2.0.12, 2.1.6", defaultValue="auto", expectedValues="true, auto, false",
158 group="state", tags="performance")
159 public static final String CHECK_ID_PRODUCTION_MODE
160 = "org.apache.myfaces.CHECK_ID_PRODUCTION_MODE";
161
162 private static final String CHECK_ID_PRODUCTION_MODE_DEFAULT = "auto";
163 private static final String CHECK_ID_PRODUCTION_MODE_TRUE = "true";
164 private static final String CHECK_ID_PRODUCTION_MODE_AUTO = "auto";
165
166 private static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";
167
168 private static final String SERIALIZED_VIEW_REQUEST_ATTR =
169 StateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
170
171 private static final Object[] EMPTY_STATES = new Object[]{null, null};
172
173 private static final Set<VisitHint> VISIT_HINTS = Collections.unmodifiableSet(
174 EnumSet.of(VisitHint.SKIP_ITERATION));
175
176 private static final String UNIQUE_ID_COUNTER_KEY =
177 "oam.view.uniqueIdCounter";
178
179 private ViewDeclarationLanguageFactory _vdlFactory;
180
181 private RenderKitFactory _renderKitFactory = null;
182
183 private VisitContextFactory _visitContextFactory = null;
184
185 private String _checkIdsProductionMode;
186
187 private MyfacesConfig _config;
188
189 private ViewPoolProcessor _viewPoolProcessor;
190
191 public DefaultFaceletsStateManagementStrategy ()
192 {
193 this(FacesContext.getCurrentInstance());
194 }
195
196 public DefaultFaceletsStateManagementStrategy (FacesContext context)
197 {
198 _vdlFactory = (ViewDeclarationLanguageFactory)
199 FactoryFinder.getFactory(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY);
200 _config = MyfacesConfig.getCurrentInstance(context.getExternalContext());
201 _viewPoolProcessor = ViewPoolProcessor.getInstance(context);
202 }
203
204 @SuppressWarnings("unchecked")
205 @Override
206 public UIViewRoot restoreView (FacesContext context, String viewId, String renderKitId)
207 {
208 ResponseStateManager manager;
209 Object state[];
210 Map<String, Object> states;
211 UIViewRoot view = null;
212
213
214
215 final boolean oldContextEventState = context.isProcessingEvents();
216
217 manager = getRenderKitFactory().getRenderKit(context, renderKitId).getResponseStateManager();
218
219 state = (Object[]) manager.getState(context, viewId);
220
221 if (state == null)
222 {
223
224 return null;
225 }
226
227 if (state[1] instanceof Object[])
228 {
229 Object[] fullState = (Object[]) state[1];
230 view = (UIViewRoot) internalRestoreTreeStructure((TreeStructComponent)fullState[0]);
231
232 if (view != null)
233 {
234 context.setViewRoot (view);
235 view.processRestoreState(context, fullState[1]);
236
237
238
239
240 RequestViewContext.getCurrentInstance(context).
241 refreshRequestViewContext(context, view);
242
243 if (fullState.length == 3 && fullState[2] != null)
244 {
245 context.setResourceLibraryContracts((List) UIComponentBase.
246 restoreAttachedState(context, fullState[2]));
247 }
248 }
249 }
250 else
251 {
252
253 ViewDeclarationLanguage vdl = _vdlFactory.getViewDeclarationLanguage(viewId);
254 Object faceletViewState = null;
255 try
256 {
257 ViewMetadata metadata = vdl.getViewMetadata (context, viewId);
258
259 if (metadata != null)
260 {
261 view = metadata.createMetadataView(context);
262
263
264 if (view == null && context.getResponseComplete())
265 {
266 return null;
267 }
268 }
269 if (view == null)
270 {
271 view = context.getApplication().getViewHandler().createView(context, viewId);
272 }
273
274 context.setViewRoot (view);
275 boolean skipBuildView = false;
276 if (state != null && state[1] != null)
277 {
278
279
280
281
282
283 states = (Map<String, Object>) state[1];
284 faceletViewState = UIComponentBase.restoreAttachedState(
285 context,states.get(ComponentSupport.FACELET_STATE_INSTANCE));
286 if (faceletViewState != null && _viewPoolProcessor != null)
287 {
288 ViewPool viewPool = _viewPoolProcessor.getViewPool(context, view);
289 if (viewPool != null)
290 {
291 ViewStructureMetadata viewMetadata = viewPool.retrieveDynamicViewStructureMetadata(
292 context, view, (FaceletState) faceletViewState);
293 if (viewMetadata != null)
294 {
295 ViewEntry entry = viewPool.popDynamicStructureView(context, view,
296 (FaceletState) faceletViewState);
297 if (entry != null)
298 {
299 skipBuildView = true;
300 _viewPoolProcessor.cloneAndRestoreView(context, view, entry, viewMetadata);
301 }
302 }
303 }
304 }
305 if (view.getId() == null)
306 {
307 view.setId(view.createUniqueId(context, null));
308 }
309 if (faceletViewState != null)
310 {
311
312
313 FaceletState newFaceletState = (FaceletState) view.getAttributes().get(
314 ComponentSupport.FACELET_STATE_INSTANCE);
315 if (newFaceletState != null)
316 {
317 newFaceletState.restoreState(context,
318 ((FaceletState)faceletViewState).saveState(context));
319 faceletViewState = newFaceletState;
320 }
321 else
322 {
323 view.getAttributes().put(ComponentSupport.FACELET_STATE_INSTANCE, faceletViewState);
324 }
325
326
327
328
329
330 }
331 if (state.length == 3)
332 {
333
334 view.getAttributes().put(UNIQUE_ID_COUNTER_KEY, state[2]);
335 }
336 Object viewRootState = states.get(view.getClientId(context));
337 if (viewRootState != null)
338 {
339 try
340 {
341 view.pushComponentToEL(context, view);
342 view.restoreViewScopeState(context, viewRootState);
343 }
344 finally
345 {
346 view.popComponentFromEL(context);
347 }
348 }
349 }
350
351
352
353
354 if (!skipBuildView)
355 {
356 try
357 {
358 context.setProcessingEvents (true);
359 vdl.buildView (context, view);
360
361
362
363 suscribeListeners(view);
364 }
365 finally
366 {
367 context.setProcessingEvents (oldContextEventState);
368 }
369 }
370 }
371 catch (Throwable e)
372 {
373 throw new FacesException ("unable to create view \"" + viewId + "\"", e);
374 }
375
376
377
378 boolean statelessMode = manager.isStateless(context, viewId);
379 if (statelessMode && !view.isTransient())
380 {
381 throw new IllegalStateException("View is not transient");
382 }
383 if (!statelessMode && view.isTransient())
384 {
385 throw new IllegalStateException("Cannot apply state over stateless view");
386 }
387
388 if (state != null && state[1] != null)
389 {
390 states = (Map<String, Object>) state[1];
391
392 Integer lastUniqueIdCounter = (Integer) view.getAttributes().get(UNIQUE_ID_COUNTER_KEY);
393
394
395 FaceletState oldFaceletState = (FaceletState) view.getAttributes().get(
396 ComponentSupport.FACELET_STATE_INSTANCE);
397
398
399 boolean emptyState = false;
400 boolean containsFaceletState = states.containsKey(
401 ComponentSupport.FACELET_STATE_INSTANCE);
402 if (states.isEmpty())
403 {
404 emptyState = true;
405 }
406 else if (states.size() == 1 &&
407 containsFaceletState)
408 {
409 emptyState = true;
410 }
411
412 if (!emptyState)
413 {
414
415
416
417 if ((states.size() == 1 && !containsFaceletState) ||
418 (states.size() == 2 && containsFaceletState))
419 {
420 Object viewState = states.get(view.getClientId(context));
421 if (viewState != null)
422 {
423 restoreViewRootOnlyFromMap(context,viewState, view);
424 }
425 else
426 {
427
428 restoreStateFromMap(context, states, view);
429 }
430 }
431 else
432 {
433 restoreStateFromMap(context, states, view);
434 }
435 }
436 if (faceletViewState != null)
437 {
438
439 if (oldFaceletState != null && oldFaceletState.getBindings() != null &&
440 !oldFaceletState.getBindings().isEmpty())
441 {
442
443
444
445
446
447
448 FaceletState newFaceletState = (FaceletState) faceletViewState;
449 for (Map.Entry<String, Map<String, ValueExpression> > entry :
450 oldFaceletState.getBindings().entrySet())
451 {
452 for (Map.Entry<String, ValueExpression> entry2 : entry.getValue().entrySet())
453 {
454 ValueExpression expr = newFaceletState.getBinding(entry.getKey(), entry2.getKey());
455 if (expr == null)
456 {
457 newFaceletState.putBinding(entry.getKey(), entry2.getKey(), entry2.getValue());
458 }
459 }
460 }
461 view.getAttributes().put(ComponentSupport.FACELET_STATE_INSTANCE, newFaceletState);
462 }
463 else
464 {
465
466 view.getAttributes().put(ComponentSupport.FACELET_STATE_INSTANCE, faceletViewState);
467 }
468 }
469 if (lastUniqueIdCounter != null)
470 {
471 Integer newUniqueIdCounter = (Integer) view.getAttributes().get(UNIQUE_ID_COUNTER_KEY);
472 if (newUniqueIdCounter != null &&
473 lastUniqueIdCounter.intValue() > newUniqueIdCounter.intValue())
474 {
475
476
477
478 view.getAttributes().put(UNIQUE_ID_COUNTER_KEY, lastUniqueIdCounter);
479 }
480 }
481 handleDynamicAddedRemovedComponents(context, view, states);
482 }
483 }
484 return view;
485 }
486
487 public void handleDynamicAddedRemovedComponents(FacesContext context, UIViewRoot view, Map<String, Object> states)
488 {
489 List<String> clientIdsRemoved = getClientIdsRemoved(view);
490
491 if (clientIdsRemoved != null)
492 {
493 Set<String> idsRemovedSet = new HashSet<String>(HashMapUtils.calcCapacity(clientIdsRemoved.size()));
494 context.getAttributes().put(FaceletViewDeclarationLanguage.REMOVING_COMPONENTS_BUILD, Boolean.TRUE);
495 try
496 {
497
498 for (int i = 0, size = clientIdsRemoved.size(); i < size; i++)
499 {
500 String clientId = clientIdsRemoved.get(i);
501 if (!idsRemovedSet.contains(clientId))
502 {
503 RemoveComponentCallback callback = new RemoveComponentCallback();
504 view.invokeOnComponent(context, clientId, callback);
505 if (callback.isComponentFound())
506 {
507
508 idsRemovedSet.add(clientId);
509 }
510 }
511 }
512 clientIdsRemoved.clear();
513 clientIdsRemoved.addAll(idsRemovedSet);
514 }
515 finally
516 {
517 context.getAttributes().remove(FaceletViewDeclarationLanguage.REMOVING_COMPONENTS_BUILD);
518 }
519 }
520 List<String> clientIdsAdded = getClientIdsAdded(view);
521 if (clientIdsAdded != null)
522 {
523 Set<String> idsAddedSet = new HashSet<String>(HashMapUtils.calcCapacity(clientIdsAdded.size()));
524
525 for (int i = 0, size = clientIdsAdded.size(); i < size; i++)
526 {
527 String clientId = clientIdsAdded.get(i);
528 if (!idsAddedSet.contains(clientId))
529 {
530 final AttachedFullStateWrapper wrapper = (AttachedFullStateWrapper) states.get(clientId);
531 if (wrapper != null)
532 {
533 final Object[] addedState = (Object[]) wrapper.getWrappedStateObject();
534 if (addedState != null)
535 {
536 if (addedState.length == 2)
537 {
538 view = (UIViewRoot)
539 internalRestoreTreeStructure((TreeStructComponent) addedState[0]);
540 view.processRestoreState(context, addedState[1]);
541 break;
542 }
543 else
544 {
545 final String parentClientId = (String) addedState[0];
546 view.invokeOnComponent(context, parentClientId,
547 new AddComponentCallback(addedState));
548 }
549 }
550 }
551 idsAddedSet.add(clientId);
552 }
553 }
554
555
556 clientIdsAdded.clear();
557
558
559
560
561 RequestViewContext.getCurrentInstance(context).
562 refreshRequestViewContext(context, view);
563 }
564 }
565
566 public static class RemoveComponentCallback implements ContextCallback
567 {
568 private boolean componentFound;
569
570 public RemoveComponentCallback()
571 {
572 this.componentFound = false;
573 }
574
575 public void invokeContextCallback(FacesContext context,
576 UIComponent target)
577 {
578 if (target.getParent() != null &&
579 !target.getParent().getChildren().remove(target))
580 {
581 String key = null;
582 if (target.getParent().getFacetCount() > 0)
583 {
584 for (Map.Entry<String, UIComponent> entry :
585 target.getParent().getFacets().entrySet())
586 {
587 if (entry.getValue()==target)
588 {
589 key = entry.getKey();
590 break;
591 }
592 }
593 }
594 if (key != null)
595 {
596 UIComponent removedTarget = target.getParent().getFacets().remove(key);
597 if (removedTarget != null)
598 {
599 this.componentFound = true;
600 }
601 }
602 }
603 else
604 {
605 this.componentFound = true;
606 }
607 }
608
609 public boolean isComponentFound()
610 {
611 return this.componentFound;
612 }
613 }
614
615 public static class AddComponentCallback implements ContextCallback
616 {
617 private final Object[] addedState;
618
619 public AddComponentCallback(Object[] addedState)
620 {
621 this.addedState = addedState;
622 }
623
624 public void invokeContextCallback(FacesContext context,
625 UIComponent target)
626 {
627 if (addedState[1] != null)
628 {
629 String facetName = (String) addedState[1];
630 UIComponent child
631 = internalRestoreTreeStructure((TreeStructComponent)
632 addedState[3]);
633 child.processRestoreState(context, addedState[4]);
634 target.getFacets().put(facetName,child);
635 }
636 else
637 {
638 Integer childIndex = (Integer) addedState[2];
639 UIComponent child
640 = internalRestoreTreeStructure((TreeStructComponent)
641 addedState[3]);
642 child.processRestoreState(context, addedState[4]);
643
644 boolean done = false;
645
646 if (child.getAttributes().containsKey(ComponentSupport.MARK_CREATED))
647 {
648
649
650
651 UIComponent parent = target;
652 if (parent.getChildCount() > 0)
653 {
654 String tagId = (String) child.getAttributes().get(ComponentSupport.MARK_CREATED);
655 if (childIndex < parent.getChildCount())
656 {
657
658 UIComponent dup = parent.getChildren().get(childIndex);
659 if (tagId.equals(dup.getAttributes().get(ComponentSupport.MARK_CREATED)))
660 {
661
662 parent.getChildren().remove(childIndex.intValue());
663 parent.getChildren().add(childIndex, child);
664 done = true;
665 }
666 }
667 if (!done)
668 {
669
670 for (int i = 0, childCount = parent.getChildCount(); i < childCount; i ++)
671 {
672 UIComponent dup = parent.getChildren().get(i);
673 if (tagId.equals(dup.getAttributes().get(ComponentSupport.MARK_CREATED)))
674 {
675
676 parent.getChildren().remove(i);
677 parent.getChildren().add(i, child);
678 done = true;
679 break;
680 }
681 }
682 }
683 }
684 }
685 if (!done)
686 {
687 try
688 {
689 target.getChildren().add(childIndex, child);
690 }
691 catch (IndexOutOfBoundsException e)
692 {
693
694
695 target.getChildren().add(child);
696 }
697 }
698 }
699 }
700 }
701
702 @Override
703 public Object saveView (FacesContext context)
704 {
705 UIViewRoot view = context.getViewRoot();
706 Object states;
707
708 if (view == null)
709 {
710
711
712 return null;
713 }
714
715 Object serializedView = context.getAttributes()
716 .get(SERIALIZED_VIEW_REQUEST_ATTR);
717
718
719
720 if (serializedView == null)
721 {
722
723
724
725 if (context.isProjectStage(ProjectStage.Production))
726 {
727 if (CHECK_ID_PRODUCTION_MODE_AUTO.equals(getCheckIdProductionMode(context)))
728 {
729 CheckDuplicateIdFaceletUtils.checkIdsStatefulComponents(context, view);
730 }
731 else if (CHECK_ID_PRODUCTION_MODE_TRUE.equals(getCheckIdProductionMode(context)))
732 {
733 CheckDuplicateIdFaceletUtils.checkIds(context, view);
734 }
735 }
736 else
737 {
738 CheckDuplicateIdFaceletUtils.checkIds(context, view);
739 }
740
741
742
743 boolean viewResetable = false;
744 int count = 0;
745 Object faceletViewState = null;
746 boolean saveViewFully = view.getAttributes().containsKey(COMPONENT_ADDED_AFTER_BUILD_VIEW);
747 if (saveViewFully)
748 {
749 ensureClearInitialState(view);
750 Object rlcStates = !context.getResourceLibraryContracts().isEmpty() ?
751 UIComponentBase.saveAttachedState(context,
752 new ArrayList<String>(context.getResourceLibraryContracts())) : null;
753 states = new Object[]{
754 internalBuildTreeStructureToSave(view),
755 view.processSaveState(context), rlcStates};
756 }
757 else
758 {
759 states = new HashMap<String, Object>();
760
761 faceletViewState = view.getAttributes().get(ComponentSupport.FACELET_STATE_INSTANCE);
762 if (faceletViewState != null)
763 {
764 ((Map<String, Object>)states).put(ComponentSupport.FACELET_STATE_INSTANCE,
765 UIComponentBase.saveAttachedState(context, faceletViewState));
766
767 view.getAttributes().remove(ComponentSupport.FACELET_STATE_INSTANCE);
768 view.getTransientStateHelper().putTransient(
769 ComponentSupport.FACELET_STATE_INSTANCE, faceletViewState);
770 }
771 if (_viewPoolProcessor != null &&
772 _viewPoolProcessor.isViewPoolEnabledForThisView(context, view))
773 {
774 SaveStateAndResetViewCallback cb = saveStateOnMapVisitTreeAndReset(
775 context,(Map<String,Object>) states, view,
776 Boolean.TRUE.equals(
777 context.getAttributes().get(ViewPoolProcessor.FORCE_HARD_RESET)));
778 viewResetable = cb.isViewResetable();
779 count = cb.getCount();
780 }
781 else
782 {
783 saveStateOnMapVisitTree(context,(Map<String,Object>) states, view);
784 }
785
786 if ( ((Map<String,Object>)states).isEmpty())
787 {
788 states = null;
789 }
790 }
791
792 Integer uniqueIdCount = (Integer) view.getAttributes().get(UNIQUE_ID_COUNTER_KEY);
793 if (uniqueIdCount != null && !uniqueIdCount.equals(1))
794 {
795 serializedView = new Object[] { null, states, uniqueIdCount };
796 }
797 else if (states == null)
798 {
799 serializedView = EMPTY_STATES;
800 }
801 else
802 {
803 serializedView = new Object[] { null, states };
804 }
805
806
807 if (!saveViewFully && _viewPoolProcessor != null)
808 {
809 if (viewResetable)
810 {
811 _viewPoolProcessor.pushResetableView(
812 context, view, (FaceletState) faceletViewState);
813 }
814 else
815 {
816 _viewPoolProcessor.pushPartialView(
817 context, view, (FaceletState) faceletViewState, count);
818 }
819 }
820
821 context.getAttributes().put(SERIALIZED_VIEW_REQUEST_ATTR, serializedView);
822
823 }
824
825 return serializedView;
826 }
827
828 private void restoreViewRootOnlyFromMap(
829 final FacesContext context, final Object viewState,
830 final UIComponent view)
831 {
832
833
834 try
835 {
836
837 view.pushComponentToEL(context, view);
838 if (viewState != null && !(viewState instanceof AttachedFullStateWrapper))
839 {
840 try
841 {
842 view.restoreState(context, viewState);
843 }
844 catch(Exception e)
845 {
846 throw new IllegalStateException(
847 "Error restoring component: "+
848 view.getClientId(context), e);
849 }
850 }
851 }
852 finally
853 {
854 view.popComponentFromEL(context);
855 }
856 }
857
858 private void restoreStateFromMap(final FacesContext context, final Map<String,Object> states,
859 final UIComponent component)
860 {
861 if (states == null)
862 {
863 return;
864 }
865
866 try
867 {
868
869 component.pushComponentToEL(context, component);
870 Object state = states.get(component.getClientId(context));
871 if (state != null)
872 {
873 if (state instanceof AttachedFullStateWrapper)
874 {
875
876 return;
877 }
878 try
879 {
880 component.restoreState(context, state);
881 }
882 catch(Exception e)
883 {
884 throw new IllegalStateException("Error restoring component: "+component.getClientId(context), e);
885 }
886 }
887
888
889 if (component.getChildCount() > 0)
890 {
891
892
893 List<UIComponent> children = component.getChildren();
894 for (int i = 0; i < children.size(); i++)
895 {
896 UIComponent child = children.get(i);
897 if (child != null && !child.isTransient())
898 {
899 restoreStateFromMap( context, states, child);
900 }
901 }
902 }
903
904
905 if (component.getFacetCount() > 0)
906 {
907 Map<String, UIComponent> facetMap = component.getFacets();
908
909 for (Map.Entry<String, UIComponent> entry : facetMap.entrySet())
910 {
911 UIComponent child = entry.getValue();
912 if (child != null && !child.isTransient())
913 {
914
915 restoreStateFromMap( context, states, child);
916 }
917 }
918 }
919 }
920 finally
921 {
922 component.popComponentFromEL(context);
923 }
924 }
925
926 static List<String> getClientIdsAdded(UIViewRoot root)
927 {
928 return (List<String>) root.getAttributes().get(CLIENTIDS_ADDED);
929 }
930
931 static void setClientsIdsAdded(UIViewRoot root, List<String> clientIdsList)
932 {
933 root.getAttributes().put(CLIENTIDS_ADDED, clientIdsList);
934 }
935
936 static List<String> getClientIdsRemoved(UIViewRoot root)
937 {
938 return (List<String>) root.getAttributes().get(CLIENTIDS_REMOVED);
939 }
940
941 static void setClientsIdsRemoved(UIViewRoot root, List<String> clientIdsList)
942 {
943 root.getAttributes().put(CLIENTIDS_REMOVED, clientIdsList);
944 }
945
946 @SuppressWarnings("unchecked")
947 private void registerOnAddRemoveList(FacesContext facesContext, String clientId)
948 {
949 UIViewRoot uiViewRoot = facesContext.getViewRoot();
950
951 List<String> clientIdsAdded = (List<String>) getClientIdsAdded(uiViewRoot);
952 if (clientIdsAdded == null)
953 {
954
955 clientIdsAdded = new ArrayList<String>();
956 }
957 clientIdsAdded.add(clientId);
958
959 setClientsIdsAdded(uiViewRoot, clientIdsAdded);
960
961 List<String> clientIdsRemoved = (List<String>) getClientIdsRemoved(uiViewRoot);
962 if (clientIdsRemoved == null)
963 {
964
965 clientIdsRemoved = new ArrayList<String>();
966 }
967
968 clientIdsRemoved.add(clientId);
969
970 setClientsIdsRemoved(uiViewRoot, clientIdsRemoved);
971 }
972
973 @SuppressWarnings("unchecked")
974 private void registerOnAddList(FacesContext facesContext, String clientId)
975 {
976 UIViewRoot uiViewRoot = facesContext.getViewRoot();
977
978 List<String> clientIdsAdded = (List<String>) getClientIdsAdded(uiViewRoot);
979 if (clientIdsAdded == null)
980 {
981
982 clientIdsAdded = new ArrayList<String>();
983 }
984 clientIdsAdded.add(clientId);
985
986 setClientsIdsAdded(uiViewRoot, clientIdsAdded);
987 }
988
989 private void saveStateOnMapVisitTree(final FacesContext facesContext, final Map<String,Object> states,
990 final UIViewRoot uiViewRoot)
991 {
992 facesContext.getAttributes().put(SKIP_ITERATION_HINT, Boolean.TRUE);
993 try
994 {
995 uiViewRoot.visitTree( getVisitContextFactory().getVisitContext(
996 facesContext, null, VISIT_HINTS), new VisitCallback()
997 {
998 public VisitResult visit(VisitContext context, UIComponent target)
999 {
1000 FacesContext facesContext = context.getFacesContext();
1001 Object state;
1002
1003 if ((target == null) || target.isTransient())
1004 {
1005
1006
1007 return VisitResult.REJECT;
1008 }
1009
1010 ComponentState componentAddedAfterBuildView
1011 = (ComponentState) target.getAttributes().get(COMPONENT_ADDED_AFTER_BUILD_VIEW);
1012
1013
1014 if (componentAddedAfterBuildView != null && (target.getParent() != null))
1015 {
1016 if (ComponentState.REMOVE_ADD.equals(componentAddedAfterBuildView))
1017 {
1018 registerOnAddRemoveList(facesContext, target.getClientId(facesContext));
1019 target.getAttributes().put(COMPONENT_ADDED_AFTER_BUILD_VIEW, ComponentState.ADDED);
1020 }
1021 else if (ComponentState.ADD.equals(componentAddedAfterBuildView))
1022 {
1023 registerOnAddList(facesContext, target.getClientId(facesContext));
1024 target.getAttributes().put(COMPONENT_ADDED_AFTER_BUILD_VIEW, ComponentState.ADDED);
1025 }
1026 else if (ComponentState.ADDED.equals(componentAddedAfterBuildView))
1027 {
1028 registerOnAddList(facesContext, target.getClientId(facesContext));
1029 }
1030 ensureClearInitialState(target);
1031
1032
1033
1034 int childIndex = target.getParent().getChildren().indexOf(target);
1035 if (childIndex >= 0)
1036 {
1037 states.put(target.getClientId(facesContext), new AttachedFullStateWrapper(
1038 new Object[]{
1039 target.getParent().getClientId(facesContext),
1040 null,
1041 childIndex,
1042 internalBuildTreeStructureToSave(target),
1043 target.processSaveState(facesContext)}));
1044 }
1045 else
1046 {
1047 String facetName = null;
1048 if (target.getParent().getFacetCount() > 0)
1049 {
1050 for (Map.Entry<String, UIComponent> entry : target.getParent().getFacets().entrySet())
1051 {
1052 if (target.equals(entry.getValue()))
1053 {
1054 facetName = entry.getKey();
1055 break;
1056 }
1057 }
1058 }
1059 states.put(target.getClientId(facesContext),new AttachedFullStateWrapper(new Object[]{
1060 target.getParent().getClientId(facesContext),
1061 facetName,
1062 null,
1063 internalBuildTreeStructureToSave(target),
1064 target.processSaveState(facesContext)}));
1065 }
1066 return VisitResult.REJECT;
1067 }
1068 else if (target.getParent() != null)
1069 {
1070 state = target.saveState (facesContext);
1071
1072 if (state != null)
1073 {
1074
1075
1076 states.put (target.getClientId (facesContext), state);
1077 }
1078
1079 return VisitResult.ACCEPT;
1080 }
1081 else
1082 {
1083
1084 return VisitResult.ACCEPT;
1085 }
1086 }
1087 });
1088 }
1089 finally
1090 {
1091 facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
1092 }
1093 if (!uiViewRoot.isTransient())
1094 {
1095 Object state = uiViewRoot.saveState (facesContext);
1096 if (state != null)
1097 {
1098
1099
1100 states.put (uiViewRoot.getClientId (facesContext), state);
1101 }
1102 }
1103 }
1104
1105
1106 private SaveStateAndResetViewCallback saveStateOnMapVisitTreeAndReset(final FacesContext facesContext,
1107 final Map<String,Object> states, final UIViewRoot uiViewRoot, boolean forceHardReset)
1108 {
1109 facesContext.getAttributes().put(SKIP_ITERATION_HINT, Boolean.TRUE);
1110 SaveStateAndResetViewCallback callback = new SaveStateAndResetViewCallback(
1111 facesContext.getViewRoot(), states, forceHardReset);
1112 if (forceHardReset)
1113 {
1114 uiViewRoot.getAttributes().put(ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY,
1115 ViewPoolProcessor.RESET_MODE_HARD);
1116 }
1117 else
1118 {
1119 uiViewRoot.getAttributes().put(ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY,
1120 ViewPoolProcessor.RESET_MODE_SOFT);
1121 }
1122 try
1123 {
1124 if (_viewPoolProcessor != null &&
1125 !_viewPoolProcessor.isViewPoolEnabledForThisView(facesContext, uiViewRoot))
1126 {
1127 callback.setViewResetable(false);
1128 }
1129
1130
1131
1132
1133 if (callback.isViewResetable())
1134 {
1135 List<String> removedIds = getClientIdsRemoved(uiViewRoot);
1136 if (removedIds != null && !removedIds.isEmpty())
1137 {
1138 callback.setViewResetable(false);
1139 }
1140 }
1141
1142 try
1143 {
1144 uiViewRoot.visitTree( getVisitContextFactory().getVisitContext(
1145 facesContext, null, VISIT_HINTS), callback);
1146 }
1147 finally
1148 {
1149 facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
1150 }
1151
1152 if (callback.isViewResetable() && callback.isRemoveAddedComponents())
1153 {
1154 List<String> clientIdsToRemove = getClientIdsAdded(uiViewRoot);
1155
1156 if (clientIdsToRemove != null)
1157 {
1158
1159 for (int i = 0, size = clientIdsToRemove.size(); i < size; i++)
1160 {
1161 String clientId = clientIdsToRemove.get(i);
1162 uiViewRoot.invokeOnComponent(facesContext, clientId, new RemoveComponentCallback());
1163 }
1164 }
1165 }
1166
1167 Object state = uiViewRoot.saveState (facesContext);
1168 if (state != null)
1169 {
1170
1171 states.put (uiViewRoot.getClientId (facesContext), state);
1172
1173
1174 Integer oldResetMode = (Integer) uiViewRoot.getAttributes().put(
1175 ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY, ViewPoolProcessor.RESET_MODE_HARD);
1176 state = uiViewRoot.saveState (facesContext);
1177 uiViewRoot.getAttributes().put(ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY, oldResetMode);
1178 if (state != null)
1179 {
1180 callback.setViewResetable(false);
1181 }
1182 }
1183 }
1184 finally
1185 {
1186 uiViewRoot.getAttributes().put(ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY,
1187 ViewPoolProcessor.RESET_MODE_OFF);
1188 }
1189 return callback;
1190 }
1191
1192 private class SaveStateAndResetViewCallback implements VisitCallback
1193 {
1194 private final Map<String, Object> states;
1195
1196 private final UIViewRoot view;
1197
1198 private boolean viewResetable;
1199
1200 private boolean skipRoot;
1201
1202 private int count;
1203
1204 private boolean forceHardReset;
1205
1206 private boolean removeAddedComponents;
1207
1208 public SaveStateAndResetViewCallback(UIViewRoot view, Map<String, Object> states,
1209 boolean forceHardReset)
1210 {
1211 this.states = states;
1212 this.view = view;
1213 this.viewResetable = true;
1214 this.skipRoot = true;
1215 this.count = 0;
1216 this.forceHardReset = forceHardReset;
1217 this.removeAddedComponents = false;
1218 }
1219
1220 public VisitResult visit(VisitContext context, UIComponent target)
1221 {
1222 FacesContext facesContext = context.getFacesContext();
1223 Object state;
1224 this.count++;
1225
1226 if ((target == null) || target.isTransient())
1227 {
1228
1229
1230 return VisitResult.REJECT;
1231 }
1232
1233 if (skipRoot && target instanceof UIViewRoot)
1234 {
1235
1236 skipRoot = false;
1237 return VisitResult.ACCEPT;
1238 }
1239
1240 ComponentState componentAddedAfterBuildView
1241 = (ComponentState) target.getAttributes().get(COMPONENT_ADDED_AFTER_BUILD_VIEW);
1242
1243
1244 if (componentAddedAfterBuildView != null && (target.getParent() != null))
1245 {
1246
1247
1248
1249 setRemoveAddedComponents(true);
1250 if (forceHardReset)
1251 {
1252
1253
1254 if (isViewResetable() &&
1255 ComponentState.REMOVE_ADD.equals(componentAddedAfterBuildView))
1256 {
1257 setViewResetable(false);
1258 }
1259
1260 return VisitResult.REJECT;
1261 }
1262 if (ComponentState.REMOVE_ADD.equals(componentAddedAfterBuildView))
1263 {
1264
1265 setViewResetable(false);
1266 registerOnAddRemoveList(facesContext, target.getClientId(facesContext));
1267 target.getAttributes().put(COMPONENT_ADDED_AFTER_BUILD_VIEW, ComponentState.ADDED);
1268 }
1269 else if (ComponentState.ADD.equals(componentAddedAfterBuildView))
1270 {
1271 registerOnAddList(facesContext, target.getClientId(facesContext));
1272 target.getAttributes().put(COMPONENT_ADDED_AFTER_BUILD_VIEW, ComponentState.ADDED);
1273 }
1274 else if (ComponentState.ADDED.equals(componentAddedAfterBuildView))
1275 {
1276
1277
1278 registerOnAddList(facesContext, target.getClientId(facesContext));
1279 }
1280 ensureClearInitialState(target);
1281
1282
1283
1284 int childIndex = target.getParent().getChildren().indexOf(target);
1285 if (childIndex >= 0)
1286 {
1287 states.put(target.getClientId(facesContext), new AttachedFullStateWrapper(
1288 new Object[]{
1289 target.getParent().getClientId(facesContext),
1290 null,
1291 childIndex,
1292 internalBuildTreeStructureToSave(target),
1293 target.processSaveState(facesContext)}));
1294 }
1295 else
1296 {
1297 String facetName = null;
1298 if (target.getParent().getFacetCount() > 0)
1299 {
1300 for (Map.Entry<String, UIComponent> entry : target.getParent().getFacets().entrySet())
1301 {
1302 if (target.equals(entry.getValue()))
1303 {
1304 facetName = entry.getKey();
1305 break;
1306 }
1307 }
1308 }
1309 states.put(target.getClientId(facesContext),new AttachedFullStateWrapper(new Object[]{
1310 target.getParent().getClientId(facesContext),
1311 facetName,
1312 null,
1313 internalBuildTreeStructureToSave(target),
1314 target.processSaveState(facesContext)}));
1315 }
1316 return VisitResult.REJECT;
1317 }
1318 else if (target.getParent() != null)
1319 {
1320 if (forceHardReset)
1321 {
1322
1323 state = target.saveState (facesContext);
1324 if (state != null)
1325 {
1326 setViewResetable(false);
1327 return VisitResult.REJECT;
1328 }
1329 }
1330 else
1331 {
1332 state = target.saveState (facesContext);
1333
1334 if (state != null)
1335 {
1336
1337 states.put (target.getClientId (facesContext), state);
1338
1339 if (isViewResetable())
1340 {
1341
1342 Integer oldResetMode = (Integer) view.getAttributes().put(
1343 ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY,
1344 ViewPoolProcessor.RESET_MODE_HARD);
1345 state = target.saveState (facesContext);
1346 view.getAttributes().put(ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY,
1347 oldResetMode);
1348 if (state != null)
1349 {
1350 setViewResetable(false);
1351 }
1352 }
1353 }
1354 }
1355
1356 return VisitResult.ACCEPT;
1357 }
1358 else
1359 {
1360
1361 return VisitResult.ACCEPT;
1362 }
1363 }
1364
1365
1366
1367
1368 public boolean isViewResetable()
1369 {
1370 return viewResetable;
1371 }
1372
1373
1374
1375
1376 public void setViewResetable(boolean viewResetable)
1377 {
1378 this.viewResetable = viewResetable;
1379 }
1380
1381 public int getCount()
1382 {
1383 return count;
1384 }
1385
1386
1387
1388
1389 public boolean isRemoveAddedComponents()
1390 {
1391 return removeAddedComponents;
1392 }
1393
1394
1395
1396
1397 public void setRemoveAddedComponents(boolean removeAddedComponents)
1398 {
1399 this.removeAddedComponents = removeAddedComponents;
1400 }
1401 }
1402
1403 protected void ensureClearInitialState(UIComponent c)
1404 {
1405 c.clearInitialState();
1406 if (c.getChildCount() > 0)
1407 {
1408 for (int i = 0, childCount = c.getChildCount(); i < childCount; i++)
1409 {
1410 UIComponent child = c.getChildren().get(i);
1411 ensureClearInitialState(child);
1412 }
1413 }
1414 if (c.getFacetCount() > 0)
1415 {
1416 for (UIComponent child : c.getFacets().values())
1417 {
1418 ensureClearInitialState(child);
1419 }
1420 }
1421 }
1422
1423 public void suscribeListeners(UIViewRoot uiViewRoot)
1424 {
1425 boolean listenerSubscribed = false;
1426 List<SystemEventListener> pavList = uiViewRoot.getViewListenersForEventClass(PostAddToViewEvent.class);
1427 if (pavList != null)
1428 {
1429 for (SystemEventListener listener : pavList)
1430 {
1431 if (listener instanceof PostAddPreRemoveFromViewListener)
1432 {
1433 listenerSubscribed = true;
1434 break;
1435 }
1436 }
1437 }
1438 if (!listenerSubscribed)
1439 {
1440 PostAddPreRemoveFromViewListener componentListener = new PostAddPreRemoveFromViewListener();
1441 uiViewRoot.subscribeToViewEvent(PostAddToViewEvent.class, componentListener);
1442 uiViewRoot.subscribeToViewEvent(PreRemoveFromViewEvent.class, componentListener);
1443 }
1444 }
1445
1446 protected RenderKitFactory getRenderKitFactory()
1447 {
1448 if (_renderKitFactory == null)
1449 {
1450 _renderKitFactory = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
1451 }
1452 return _renderKitFactory;
1453 }
1454
1455 protected VisitContextFactory getVisitContextFactory()
1456 {
1457 if (_visitContextFactory == null)
1458 {
1459 _visitContextFactory = (VisitContextFactory)FactoryFinder.getFactory(FactoryFinder.VISIT_CONTEXT_FACTORY);
1460 }
1461 return _visitContextFactory;
1462 }
1463
1464 protected String getCheckIdProductionMode(FacesContext facesContext)
1465 {
1466 if (_checkIdsProductionMode == null)
1467 {
1468 _checkIdsProductionMode
1469 = WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(),
1470 CHECK_ID_PRODUCTION_MODE, CHECK_ID_PRODUCTION_MODE_DEFAULT);
1471 }
1472 return _checkIdsProductionMode;
1473 }
1474
1475
1476 public static class PostAddPreRemoveFromViewListener implements SystemEventListener
1477 {
1478 private transient FacesContext _facesContext;
1479
1480 private transient Boolean _isRefreshOnTransientBuildPreserveState;
1481
1482 public boolean isListenerForSource(Object source)
1483 {
1484
1485
1486 return (source instanceof UIComponent);
1487 }
1488
1489 private boolean isRefreshOnTransientBuildPreserveState()
1490 {
1491 if (_isRefreshOnTransientBuildPreserveState == null)
1492 {
1493 _isRefreshOnTransientBuildPreserveState = MyfacesConfig.getCurrentInstance(
1494 _facesContext.getExternalContext()).isRefreshTransientBuildOnPSSPreserveState();
1495 }
1496 return _isRefreshOnTransientBuildPreserveState;
1497 }
1498
1499 public void processEvent(SystemEvent event)
1500 {
1501 UIComponent component = (UIComponent) event.getSource();
1502
1503 if (component.isTransient())
1504 {
1505 return;
1506 }
1507
1508
1509
1510
1511 if (_facesContext == null)
1512 {
1513 _facesContext = FacesContext.getCurrentInstance();
1514 }
1515
1516 if (event instanceof PostAddToViewEvent)
1517 {
1518 if (!isRefreshOnTransientBuildPreserveState() &&
1519 Boolean.TRUE.equals(_facesContext.getAttributes().get(StateManager.IS_BUILDING_INITIAL_STATE)))
1520 {
1521 return;
1522 }
1523
1524
1525 component.getAttributes().put(COMPONENT_ADDED_AFTER_BUILD_VIEW, ComponentState.ADD);
1526 }
1527 else
1528 {
1529
1530
1531
1532
1533
1534 if (FaceletViewDeclarationLanguage.isRemovingComponentBuild(_facesContext))
1535 {
1536 return;
1537 }
1538
1539 if (!isRefreshOnTransientBuildPreserveState() &&
1540 FaceletCompositionContext.getCurrentInstance(_facesContext) != null &&
1541 (component.getAttributes().containsKey(ComponentSupport.MARK_CREATED) ||
1542 component.getAttributes().containsKey(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER))
1543 )
1544 {
1545
1546
1547
1548
1549
1550
1551
1552 return;
1553 }
1554
1555
1556 UIViewRoot uiViewRoot = _facesContext.getViewRoot();
1557
1558 List<String> clientIdsRemoved = getClientIdsRemoved(uiViewRoot);
1559 if (clientIdsRemoved == null)
1560 {
1561
1562 clientIdsRemoved = new ArrayList<String>();
1563 }
1564 clientIdsRemoved.add(component.getClientId(_facesContext));
1565 setClientsIdsRemoved(uiViewRoot, clientIdsRemoved);
1566 }
1567 }
1568 }
1569
1570 private static TreeStructComponent internalBuildTreeStructureToSave(UIComponent component)
1571 {
1572 TreeStructComponent structComp = new TreeStructComponent(component.getClass().getName(),
1573 component.getId());
1574
1575
1576 if (component.getChildCount() > 0)
1577 {
1578 List<TreeStructComponent> structChildList = new ArrayList<TreeStructComponent>();
1579 for (int i = 0, childCount = component.getChildCount(); i < childCount; i++)
1580 {
1581 UIComponent child = component.getChildren().get(i);
1582 if (!child.isTransient())
1583 {
1584 TreeStructComponent structChild = internalBuildTreeStructureToSave(child);
1585 structChildList.add(structChild);
1586 }
1587 }
1588
1589 TreeStructComponent[] childArray = structChildList.toArray(new TreeStructComponent[structChildList.size()]);
1590 structComp.setChildren(childArray);
1591 }
1592
1593
1594
1595 if (component.getFacetCount() > 0)
1596 {
1597 Map<String, UIComponent> facetMap = component.getFacets();
1598 List<Object[]> structFacetList = new ArrayList<Object[]>();
1599 for (Map.Entry<String, UIComponent> entry : facetMap.entrySet())
1600 {
1601 UIComponent child = entry.getValue();
1602 if (!child.isTransient())
1603 {
1604 String facetName = entry.getKey();
1605 TreeStructComponent structChild = internalBuildTreeStructureToSave(child);
1606 structFacetList.add(new Object[] {facetName, structChild});
1607 }
1608 }
1609
1610 Object[] facetArray = structFacetList.toArray(new Object[structFacetList.size()]);
1611 structComp.setFacets(facetArray);
1612 }
1613
1614 return structComp;
1615 }
1616
1617 private static UIComponent internalRestoreTreeStructure(TreeStructComponent treeStructComp)
1618 {
1619 String compClass = treeStructComp.getComponentClass();
1620 String compId = treeStructComp.getComponentId();
1621 UIComponent component = (UIComponent)ClassUtils.newInstance(compClass);
1622 component.setId(compId);
1623
1624
1625 TreeStructComponent[] childArray = treeStructComp.getChildren();
1626 if (childArray != null)
1627 {
1628 List<UIComponent> childList = component.getChildren();
1629 for (int i = 0, len = childArray.length; i < len; i++)
1630 {
1631 UIComponent child = internalRestoreTreeStructure(childArray[i]);
1632 childList.add(child);
1633 }
1634 }
1635
1636
1637 Object[] facetArray = treeStructComp.getFacets();
1638 if (facetArray != null)
1639 {
1640 Map<String, UIComponent> facetMap = component.getFacets();
1641 for (int i = 0, len = facetArray.length; i < len; i++)
1642 {
1643 Object[] tuple = (Object[])facetArray[i];
1644 String facetName = (String)tuple[0];
1645 TreeStructComponent structChild = (TreeStructComponent)tuple[1];
1646 UIComponent child = internalRestoreTreeStructure(structChild);
1647 facetMap.put(facetName, child);
1648 }
1649 }
1650
1651 return component;
1652 }
1653
1654 public static class TreeStructComponent implements Serializable
1655 {
1656 private static final long serialVersionUID = 5069109074684737231L;
1657 private String _componentClass;
1658 private String _componentId;
1659 private TreeStructComponent[] _children = null;
1660 private Object[] _facets = null;
1661
1662 TreeStructComponent(String componentClass, String componentId)
1663 {
1664 _componentClass = componentClass;
1665 _componentId = componentId;
1666 }
1667
1668 public String getComponentClass()
1669 {
1670 return _componentClass;
1671 }
1672
1673 public String getComponentId()
1674 {
1675 return _componentId;
1676 }
1677
1678 void setChildren(TreeStructComponent[] children)
1679 {
1680 _children = children;
1681 }
1682
1683 TreeStructComponent[] getChildren()
1684 {
1685 return _children;
1686 }
1687
1688 Object[] getFacets()
1689 {
1690 return _facets;
1691 }
1692
1693 void setFacets(Object[] facets)
1694 {
1695 _facets = facets;
1696 }
1697 }
1698
1699 }