1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.myfaces.trinidad.component;
23
24 import java.io.IOException;
25 import javax.faces.component.UIComponent;
26 import javax.faces.component.visit.VisitCallback;
27 import javax.faces.component.visit.VisitContext;
28 import javax.faces.component.visit.VisitContextWrapper;
29 import javax.faces.component.visit.VisitHint;
30 import javax.faces.component.visit.VisitResult;
31 import javax.faces.context.FacesContext;
32 import javax.faces.event.FacesEvent;
33 import javax.faces.event.PhaseId;
34 import org.apache.myfaces.trinidad.bean.FacesBean;
35 import org.apache.myfaces.trinidad.event.DisclosureEvent;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class UIXShowOne extends UIXComponentBase
57 {
58 static public final FacesBean.Type TYPE = new FacesBean.Type(
59 UIXComponentBase.TYPE);
60
61 static public final String COMPONENT_FAMILY =
62 "org.apache.myfaces.trinidad.ShowOne";
63 static public final String COMPONENT_TYPE =
64 "org.apache.myfaces.trinidad.ShowOne";
65
66
67
68
69 public UIXShowOne()
70 {
71 super("org.apache.myfaces.trinidad.Tab");
72 }
73
74 @Override
75 @SuppressWarnings("unchecked")
76 public void queueEvent(FacesEvent e)
77 {
78
79
80
81 FacesEvent unwrappedEvent = e;
82 while (unwrappedEvent instanceof WrapperEvent)
83 {
84 unwrappedEvent = ((WrapperEvent)unwrappedEvent).getEvent();
85 }
86
87 if (unwrappedEvent instanceof DisclosureEvent)
88 {
89 UIComponent parent = unwrappedEvent.getComponent().getParent();
90 while (parent != null && parent instanceof FlattenedComponent)
91 {
92 parent = parent.getParent();
93 }
94
95 if (this == parent)
96 {
97
98 DisclosureEvent disclosureEvent = (DisclosureEvent)unwrappedEvent;
99 if (disclosureEvent.isExpanded())
100 {
101 FacesContext context = FacesContext.getCurrentInstance();
102 String disclosedClientId = disclosureEvent.getComponent().getClientId(context);
103
104
105 try
106 {
107 UIXComponent.processFlattenedChildren(
108 context,
109 _undisclosureCallback,
110 getChildren(),
111 new UndisclosureCallbackState(e, disclosedClientId));
112 }
113 catch (IOException ioe)
114 {
115
116 ioe.printStackTrace();
117 }
118 }
119 }
120 }
121 super.queueEvent(e);
122 }
123
124 @Override
125 public boolean visitTree(
126 VisitContext visitContext,
127 VisitCallback callback)
128 {
129 if (visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED))
130 {
131
132
133 visitContext = new PartialVisitContext(visitContext);
134 }
135 return super.visitTree(visitContext, callback);
136 }
137
138 protected boolean isChildSelected(
139 UIXShowDetail component)
140 {
141 return component.isDisclosed();
142 }
143
144
145
146
147 private static class UndisclosureCallbackState
148 {
149 public UndisclosureCallbackState(
150 FacesEvent facesEvent,
151 String clientIdBeingDisclosed)
152 {
153 this.facesEvent = facesEvent;
154 this.clientIdBeingDisclosed = clientIdBeingDisclosed;
155 }
156
157 protected final FacesEvent facesEvent;
158 protected final String clientIdBeingDisclosed;
159 }
160
161
162
163
164 private class UndisclosureCallback implements ComponentProcessor<UndisclosureCallbackState>
165 {
166 public void processComponent(
167 FacesContext facesContext,
168 ComponentProcessingContext processContext,
169 UIComponent child,
170 UndisclosureCallbackState callbackState)
171 throws IOException
172 {
173 String clientIdBeingDisclosed = callbackState.clientIdBeingDisclosed;
174
175
176 String childClientId = child.getClientId(facesContext);
177 if (!clientIdBeingDisclosed.equals(childClientId))
178 {
179 UIXShowDetail toBeUnDisclosedChild = (UIXShowDetail)child;
180 if (toBeUnDisclosedChild.isDisclosed())
181 {
182
183
184
185
186 if (toBeUnDisclosedChild.isImmediate())
187 {
188 callbackState.facesEvent.setPhaseId(PhaseId.ANY_PHASE);
189 }
190 else
191 {
192 callbackState.facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
193 }
194
195
196
197
198 (new DisclosureEvent(toBeUnDisclosedChild, false)).queue();
199 }
200 }
201 }
202 }
203
204 private class PartialVisitContext
205 extends VisitContextWrapper
206 {
207 PartialVisitContext(VisitContext wrapped)
208 {
209 _wrapped = wrapped;
210 }
211
212 public VisitContext getWrapped()
213 {
214 return _wrapped;
215 }
216
217 @Override
218 public VisitResult invokeVisitCallback(
219 UIComponent component,
220 VisitCallback visitCallback)
221 {
222 if (component instanceof UIXShowDetail)
223 {
224 UIXShowDetail showDetail = (UIXShowDetail)component;
225 if (_isShowDetailForCurrentComponent(showDetail))
226 {
227 if (_foundItemToRender || !isChildSelected(showDetail))
228 {
229
230 return VisitResult.REJECT;
231 }
232 else
233 {
234 _foundItemToRender = true;
235 }
236 }
237 }
238
239 return super.invokeVisitCallback(component, visitCallback);
240 }
241
242 private boolean _isShowDetailForCurrentComponent(
243 UIXShowDetail showDetail)
244 {
245 for (UIComponent parent = showDetail.getParent(); parent != null; parent = parent.getParent())
246 {
247 if (parent == UIXShowOne.this)
248 {
249 return true;
250 }
251
252 if (parent instanceof FlattenedComponent &&
253 ((FlattenedComponent)parent).isFlatteningChildren(getFacesContext()))
254 {
255 continue;
256 }
257
258
259 return false;
260 }
261
262 return false;
263 }
264
265 private boolean _foundItemToRender;
266 private VisitContext _wrapped;
267 }
268
269 private final UndisclosureCallback _undisclosureCallback = new UndisclosureCallback();
270
271 @Override
272 public String getFamily()
273 {
274 return COMPONENT_FAMILY;
275 }
276
277 @Override
278 protected FacesBean.Type getBeanType()
279 {
280 return TYPE;
281 }
282
283
284
285
286 protected UIXShowOne(
287 String rendererType
288 )
289 {
290 super(rendererType);
291 }
292
293 static
294 {
295 TYPE.lockAndRegister("org.apache.myfaces.trinidad.ShowOne","org.apache.myfaces.trinidad.Tab");
296 }
297 }