View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.view.facelets.tag.composite;
20  
21  import java.io.IOException;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  
29  import javax.el.ValueExpression;
30  import javax.faces.FacesException;
31  import javax.faces.FacesWrapper;
32  import javax.faces.component.ContextCallback;
33  import javax.faces.component.UIComponent;
34  import javax.faces.component.behavior.ClientBehavior;
35  import javax.faces.component.behavior.ClientBehaviorHolder;
36  import javax.faces.component.visit.VisitCallback;
37  import javax.faces.component.visit.VisitContext;
38  import javax.faces.context.FacesContext;
39  import javax.faces.el.ValueBinding;
40  import javax.faces.event.AbortProcessingException;
41  import javax.faces.event.ComponentSystemEvent;
42  import javax.faces.event.ComponentSystemEventListener;
43  import javax.faces.event.FacesEvent;
44  import javax.faces.event.FacesListener;
45  import javax.faces.event.SystemEvent;
46  import javax.faces.event.SystemEventListener;
47  import javax.faces.render.Renderer;
48  
49  /**
50   * This class has two usages:
51   * 
52   * 1. On ClientBehaviorAttachedObjectTargetImpl to redirect the incoming sourceEvent
53   * to the final targetEvent.   
54   * 2. On FaceletsViewDeclarationLanguage.retargetAttachedObjects to redirect too, but
55   * this time is to allow chain events for nested composite components.
56   * 
57   * This class also implements FacesWrapper interface, to make possible to retrieve the
58   * real component if necessary.
59   * 
60   * @author Leonardo Uribe (latest modification by $Author$)
61   * @version $Revision$ $Date$
62   */
63  public class ClientBehaviorRedirectEventComponentWrapper extends UIComponent 
64      implements FacesWrapper<UIComponent>, ClientBehaviorHolder
65  {
66  
67      private final UIComponent _delegate;
68      private final String _sourceEvent; //cc:clientBehavior "name"
69      private final String _targetEvent; //cc:clientBehavior "event"
70  
71      public ClientBehaviorRedirectEventComponentWrapper(UIComponent delegate,
72              String sourceEvent, String targetEvent)
73      {
74          super();
75          _delegate = delegate;
76          _sourceEvent = sourceEvent;
77          _targetEvent = targetEvent;
78      }
79  
80      public UIComponent getWrapped()
81      {
82          return _delegate;
83      }
84  
85      public void addClientBehavior(String eventName, ClientBehavior behavior)
86      {
87          if (_sourceEvent.equals(eventName))
88          {
89              String targetEventName = _targetEvent == null
90                      ? ((ClientBehaviorHolder)_delegate).getDefaultEventName()
91                      : _targetEvent;
92              ((ClientBehaviorHolder)_delegate).addClientBehavior(targetEventName , behavior);
93          }
94      }
95  
96      public Map<String, List<ClientBehavior>> getClientBehaviors()
97      {
98          Map<String, List<ClientBehavior>> clientBehaviors = new HashMap<String, List<ClientBehavior>>(1);
99          clientBehaviors.put(_sourceEvent, ((ClientBehaviorHolder)_delegate).getClientBehaviors().get(_targetEvent));
100         return Collections.unmodifiableMap(clientBehaviors);
101     }
102 
103     public String getDefaultEventName()
104     {
105         if (_targetEvent == null )
106         {
107             // There is no targetEvent assigned, so we need to check if there is 
108             // a default event name on the delegate, if so return sourceEvent, otherwise
109             // there is no default event and we can't resolve the redirection, so
110             // return null. Note this usually could cause another exception later
111             // (see AjaxHandler code 
112             if (((ClientBehaviorHolder)_delegate).getDefaultEventName() != null)
113             {
114                 return _sourceEvent;
115             }
116             else
117             {
118                 return null;
119             }
120         }
121         else
122         {
123             // We have a target event, so in this case we have to return the sourceEvent,
124             // because it is expected the client behavior to be attached has this event name.
125             return _sourceEvent;
126         }
127     }
128 
129     public Collection<String> getEventNames()
130     {
131         return Collections.singletonList(_sourceEvent);
132     }
133     
134     // UIComponent wrapping. Just delegate.    
135     public void broadcast(FacesEvent event) throws AbortProcessingException
136     {
137         _delegate.broadcast(event);
138     }
139 
140     public void clearInitialState()
141     {
142         _delegate.clearInitialState();
143     }
144 
145     public void decode(FacesContext context)
146     {
147         _delegate.decode(context);
148     }
149 
150     public void encodeAll(FacesContext context) throws IOException
151     {
152         _delegate.encodeAll(context);
153     }
154 
155     public void encodeBegin(FacesContext context) throws IOException
156     {
157         _delegate.encodeBegin(context);
158     }
159 
160     public void encodeChildren(FacesContext context) throws IOException
161     {
162         _delegate.encodeChildren(context);
163     }
164 
165     public void encodeEnd(FacesContext context) throws IOException
166     {
167         _delegate.encodeEnd(context);
168     }
169 
170     public UIComponent findComponent(String expr)
171     {
172         return _delegate.findComponent(expr);
173     }
174 
175     public Map<String, Object> getAttributes()
176     {
177         return _delegate.getAttributes();
178     }
179 
180     public int getChildCount()
181     {
182         return _delegate.getChildCount();
183     }
184 
185     public List<UIComponent> getChildren()
186     {
187         return _delegate.getChildren();
188     }
189 
190     public String getClientId()
191     {
192         return _delegate.getClientId();
193     }
194 
195     public String getClientId(FacesContext context)
196     {
197         return _delegate.getClientId(context);
198     }
199 
200     public String getContainerClientId(FacesContext ctx)
201     {
202         return _delegate.getContainerClientId(ctx);
203     }
204 
205     public UIComponent getFacet(String name)
206     {
207         return _delegate.getFacet(name);
208     }
209 
210     public int getFacetCount()
211     {
212         return _delegate.getFacetCount();
213     }
214 
215     public Map<String, UIComponent> getFacets()
216     {
217         return _delegate.getFacets();
218     }
219 
220     public Iterator<UIComponent> getFacetsAndChildren()
221     {
222         return _delegate.getFacetsAndChildren();
223     }
224 
225     public String getFamily()
226     {
227         return _delegate.getFamily();
228     }
229 
230     public String getId()
231     {
232         return _delegate.getId();
233     }
234 
235     public List<SystemEventListener> getListenersForEventClass(
236             Class<? extends SystemEvent> eventClass)
237     {
238         return _delegate.getListenersForEventClass(eventClass);
239     }
240 
241     public UIComponent getNamingContainer()
242     {
243         return _delegate.getNamingContainer();
244     }
245 
246     public UIComponent getParent()
247     {
248         return _delegate.getParent();
249     }
250 
251     public String getRendererType()
252     {
253         return _delegate.getRendererType();
254     }
255 
256     public boolean getRendersChildren()
257     {
258         return _delegate.getRendersChildren();
259     }
260 
261     public Map<String, String> getResourceBundleMap()
262     {
263         return _delegate.getResourceBundleMap();
264     }
265 
266     public ValueBinding getValueBinding(String name)
267     {
268         return _delegate.getValueBinding(name);
269     }
270 
271     public ValueExpression getValueExpression(String name)
272     {
273         return _delegate.getValueExpression(name);
274     }
275 
276     public boolean initialStateMarked()
277     {
278         return _delegate.initialStateMarked();
279     }
280 
281     public boolean invokeOnComponent(FacesContext context, String clientId,
282             ContextCallback callback) throws FacesException
283     {
284         return _delegate.invokeOnComponent(context, clientId, callback);
285     }
286 
287     public boolean isInView()
288     {
289         return _delegate.isInView();
290     }
291 
292     public boolean isRendered()
293     {
294         return _delegate.isRendered();
295     }
296 
297     public boolean isTransient()
298     {
299         return _delegate.isTransient();
300     }
301 
302     public void markInitialState()
303     {
304         _delegate.markInitialState();
305     }
306 
307     public void processDecodes(FacesContext context)
308     {
309         _delegate.processDecodes(context);
310     }
311 
312     public void processEvent(ComponentSystemEvent event)
313             throws AbortProcessingException
314     {
315         _delegate.processEvent(event);
316     }
317 
318     public void processRestoreState(FacesContext context, Object state)
319     {
320         _delegate.processRestoreState(context, state);
321     }
322 
323     public Object processSaveState(FacesContext context)
324     {
325         return _delegate.processSaveState(context);
326     }
327 
328     public void processUpdates(FacesContext context)
329     {
330         _delegate.processUpdates(context);
331     }
332 
333     public void processValidators(FacesContext context)
334     {
335         _delegate.processValidators(context);
336     }
337 
338     public void queueEvent(FacesEvent event)
339     {
340         _delegate.queueEvent(event);
341     }
342 
343     public void restoreState(FacesContext context, Object state)
344     {
345         _delegate.restoreState(context, state);
346     }
347 
348     public Object saveState(FacesContext context)
349     {
350         return _delegate.saveState(context);
351     }
352 
353     public void setId(String id)
354     {
355         _delegate.setId(id);
356     }
357 
358     public void setInView(boolean isInView)
359     {
360         _delegate.setInView(isInView);
361     }
362 
363     public void setParent(UIComponent parent)
364     {
365         _delegate.setParent(parent);
366     }
367 
368     public void setRendered(boolean rendered)
369     {
370         _delegate.setRendered(rendered);
371     }
372 
373     public void setRendererType(String rendererType)
374     {
375         _delegate.setRendererType(rendererType);
376     }
377 
378     public void setTransient(boolean newTransientValue)
379     {
380         _delegate.setTransient(newTransientValue);
381     }
382 
383     public void setValueBinding(String name, ValueBinding binding)
384     {
385         _delegate.setValueBinding(name, binding);
386     }
387 
388     public void setValueExpression(String name, ValueExpression expression)
389     {
390         _delegate.setValueExpression(name, expression);
391     }
392 
393     public void subscribeToEvent(Class<? extends SystemEvent> eventClass,
394             ComponentSystemEventListener componentListener)
395     {
396         _delegate.subscribeToEvent(eventClass, componentListener);
397     }
398 
399     public void unsubscribeFromEvent(Class<? extends SystemEvent> eventClass,
400             ComponentSystemEventListener componentListener)
401     {
402         _delegate.unsubscribeFromEvent(eventClass, componentListener);
403     }
404 
405     public boolean visitTree(VisitContext context, VisitCallback callback)
406     {
407         return _delegate.visitTree(context, callback);
408     }
409     
410     // Some methods of UIComponent are protected, but for the scope of this
411     // wrapper are never used, so it is safe to just do nothing or return null.
412 
413     @Override
414     protected FacesContext getFacesContext()
415     {
416         return FacesContext.getCurrentInstance();
417     }
418 
419     @Override
420     protected void addFacesListener(FacesListener listener)
421     {
422     }
423 
424     @Override
425     protected FacesListener[] getFacesListeners(Class clazz)
426     {
427         return null;
428     }
429 
430     @Override
431     protected Renderer getRenderer(FacesContext context)
432     {
433         return null;
434     }
435 
436     @Override
437     protected void removeFacesListener(FacesListener listener)
438     {
439     }
440 
441     @Override
442     public Map<String, Object> getPassThroughAttributes(boolean create)
443     {
444         return getWrapped().getPassThroughAttributes(create);
445     }
446 }