Coverage Report - org.apache.myfaces.view.facelets.tag.jsf.BehaviorTagHandlerDelegate
 
Classes in this File Line Coverage Branch Coverage Complexity
BehaviorTagHandlerDelegate
0%
0/50
0%
0/26
3.857
 
 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.jsf;
 20  
 
 21  
 import java.io.IOException;
 22  
 
 23  
 import javax.el.ValueExpression;
 24  
 import javax.faces.component.UIComponent;
 25  
 import javax.faces.component.behavior.Behavior;
 26  
 import javax.faces.component.behavior.ClientBehavior;
 27  
 import javax.faces.component.behavior.ClientBehaviorHolder;
 28  
 import javax.faces.context.FacesContext;
 29  
 import javax.faces.view.BehaviorHolderAttachedObjectHandler;
 30  
 import javax.faces.view.facelets.BehaviorHandler;
 31  
 import javax.faces.view.facelets.ComponentHandler;
 32  
 import javax.faces.view.facelets.FaceletContext;
 33  
 import javax.faces.view.facelets.MetaRuleset;
 34  
 import javax.faces.view.facelets.TagAttribute;
 35  
 import javax.faces.view.facelets.TagAttributeException;
 36  
 import javax.faces.view.facelets.TagException;
 37  
 import javax.faces.view.facelets.TagHandlerDelegate;
 38  
 
 39  
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 40  
 import org.apache.myfaces.view.facelets.tag.MetaRulesetImpl;
 41  
 import org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler;
 42  
 
 43  
 /**
 44  
  * @author Leonardo Uribe (latest modification by $Author$)
 45  
  * @version $Revision$ $Date$
 46  
  *
 47  
  * @since 2.0
 48  
  */
 49  
 public class BehaviorTagHandlerDelegate extends TagHandlerDelegate implements BehaviorHolderAttachedObjectHandler
 50  
 {
 51  
 
 52  
     private BehaviorHandler _delegate;
 53  
     
 54  
     public BehaviorTagHandlerDelegate(BehaviorHandler delegate)
 55  0
     {
 56  0
         _delegate = delegate;
 57  0
     }
 58  
 
 59  
     @Override
 60  
     public void apply(FaceletContext ctx, UIComponent parent) throws IOException
 61  
     {
 62  0
         if (!ComponentHandler.isNew(parent))
 63  
         {
 64  0
             return;
 65  
         }
 66  
         // Note that the only contract defined at this moment based on behavior api
 67  
         // is client behavior, so it is enough to cast it here. In the future, new
 68  
         // implementations should be added here.
 69  0
         if (parent instanceof ClientBehaviorHolder)
 70  
         {
 71  0
             applyAttachedObject(ctx.getFacesContext(), parent);
 72  
         }
 73  0
         else if (UIComponent.isCompositeComponent(parent))
 74  
         {
 75  0
             FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
 76  
             // It is supposed that for composite components, this tag should
 77  
             // add itself as a target, but note that on whole api does not exists
 78  
             // some tag that expose client behaviors as targets for composite
 79  
             // components. In RI, there exists a tag called composite:clientBehavior,
 80  
             // but does not appear on spec or javadoc, maybe because this could be
 81  
             // understand as an implementation detail, after all there exists a key
 82  
             // called AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY that could be
 83  
             // used to create a tag outside jsf implementation to attach targets.
 84  0
             mctx.addAttachedObjectHandler(parent, _delegate);
 85  0
         }
 86  
         else
 87  
         {
 88  0
             throw new TagException(_delegate.getTag(),
 89  
                     "Parent not composite component or an instance of ClientBehaviorHolder: " + parent);
 90  
         }
 91  
         
 92  0
     }
 93  
     
 94  
     protected Behavior createBehavior(FaceletContext ctx)
 95  
     {
 96  0
         if (_delegate.getBehaviorId() == null)
 97  
         {
 98  0
             throw new TagException(
 99  
                                    _delegate.getTag(),
 100  
                                    "No behavior id defined");
 101  
         }
 102  0
         return ctx.getFacesContext().getApplication().createBehavior(_delegate.getBehaviorId());
 103  
     }
 104  
 
 105  
     /**
 106  
      * This tag call _delegate.setAttributes, so the returned MetaRuleset
 107  
      * should ignore attributes that are not supposed to be there like
 108  
      * "binding" and "event"
 109  
      */
 110  
     @Override
 111  
     public MetaRuleset createMetaRuleset(Class type)
 112  
     {
 113  0
         MetaRuleset ruleset = new MetaRulesetImpl(_delegate.getTag(), type);
 114  0
         ruleset.ignore("binding");
 115  0
         ruleset.ignore("event");
 116  0
         return ruleset;
 117  
     }
 118  
 
 119  
     /**
 120  
      * Create a ClientBehavior and attach it to the component
 121  
      */
 122  
     public void applyAttachedObject(FacesContext context, UIComponent parent)
 123  
     {
 124  
         // Retrieve the current FaceletContext from FacesContext object
 125  0
         FaceletContext faceletContext = (FaceletContext) context.getAttributes().get(
 126  
                 FaceletContext.FACELET_CONTEXT_KEY);
 127  
         
 128  0
         ValueExpression ve = null;
 129  0
         Behavior behavior = null;
 130  0
         if (_delegate.getBinding() != null)
 131  
         {
 132  0
             ve = _delegate.getBinding().getValueExpression(faceletContext, Behavior.class);
 133  0
             behavior = (Behavior) ve.getValue(faceletContext);
 134  
         }
 135  0
         if (behavior == null)
 136  
         {
 137  0
             behavior = this.createBehavior(faceletContext);
 138  0
             if (ve != null)
 139  
             {
 140  0
                 ve.setValue(faceletContext, behavior);
 141  
             }
 142  
         }
 143  0
         if (behavior == null)
 144  
         {
 145  0
             throw new TagException(_delegate.getTag(), "No Validator was created");
 146  
         }
 147  0
         _delegate.setAttributes(faceletContext, behavior);
 148  
         
 149  0
         if (behavior instanceof ClientBehavior)
 150  
         {
 151  
             // cast to a ClientBehaviorHolder
 152  0
             ClientBehaviorHolder cvh = (ClientBehaviorHolder) parent;
 153  
             
 154  
             // TODO: check if the behavior could be applied to the current parent
 155  
             // For run tests it is not necessary, so we let this one pending.
 156  
 
 157  
             // It is necessary to obtain a event name for add it, so we have to
 158  
             // look first to the defined event name, otherwise take the default from
 159  
             // the holder
 160  0
             String eventName = getEventName();
 161  0
             if (eventName == null)
 162  
             {
 163  0
                 eventName = cvh.getDefaultEventName();
 164  
             }
 165  0
             if (eventName == null)
 166  
             {
 167  0
                 throw new TagAttributeException(_delegate.getEvent(),
 168  
                         "eventName could not be defined for client behavior "+ behavior.toString());
 169  
             }
 170  0
             else if (!cvh.getEventNames().contains(eventName))
 171  
             {
 172  0
                 throw new TagAttributeException(_delegate.getEvent(),
 173  
                         "eventName "+eventName+" not found on component instance");
 174  
             }
 175  
             else
 176  
             {
 177  0
                 cvh.addClientBehavior(eventName, (ClientBehavior) behavior);
 178  
             }
 179  
             
 180  0
             AjaxHandler.registerJsfAjaxDefaultResource(faceletContext, parent);
 181  
         }
 182  0
     }
 183  
 
 184  
     public String getFor()
 185  
     {
 186  0
         TagAttribute forAttribute = _delegate.getTagAttribute("for");
 187  
         
 188  0
         if (forAttribute == null)
 189  
         {
 190  0
             return null;
 191  
         }
 192  
         else
 193  
         {
 194  0
             return forAttribute.getValue();
 195  
         }
 196  
     }
 197  
 
 198  
     public String getEventName()
 199  
     {
 200  0
         return _delegate.getEventName();
 201  
     }
 202  
 
 203  
 }