Coverage report

  %line %branch
org.apache.commons.jelly.tags.bean.BeanTag
74% 
81% 

 1  
 /*
 2  
  * Copyright 2002,2004 The Apache Software Foundation.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 
 17  
 package org.apache.commons.jelly.tags.bean;
 18  
 
 19  
 import java.lang.reflect.InvocationTargetException;
 20  
 import java.lang.reflect.Method;
 21  
 import java.util.Collection;
 22  
 
 23  
 import org.apache.commons.beanutils.BeanUtils;
 24  
 import org.apache.commons.beanutils.MethodUtils;
 25  
 import org.apache.commons.jelly.JellyTagException;
 26  
 import org.apache.commons.jelly.Tag;
 27  
 import org.apache.commons.jelly.impl.BeanSource;
 28  
 import org.apache.commons.jelly.impl.CollectionTag;
 29  
 import org.apache.commons.jelly.tags.core.UseBeanTag;
 30  
 import org.apache.commons.logging.Log;
 31  
 import org.apache.commons.logging.LogFactory;
 32  
 
 33  
 
 34  
 /**
 35  
  * Creates a bean for the given tag which is then either output as a variable
 36  
  * or can be added to a parent tag.
 37  
  *
 38  
  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 39  
  * @author Christian Sell
 40  
  * @version   $Revision: 155420 $
 41  
  */
 42  
 public class BeanTag extends UseBeanTag {
 43  
 
 44  
     /** The Log to which logging calls will be made. */
 45  9
     private static final Log log = LogFactory.getLog(BeanTag.class);
 46  
 
 47  3
     protected static final Object[] EMPTY_ARGUMENTS = {};
 48  
 
 49  
     /** the name of the property to create */
 50  
     private String tagName;
 51  
 
 52  
     /** the name of the adder method */
 53  
     protected String addMethodName;
 54  
 
 55  
     /** if present this is used to call a doit method when the bean is constructed */
 56  
     private Method invokeMethod;
 57  
 
 58  
 
 59  
     public BeanTag() {
 60  0
         this(null, "bean", null);
 61  0
     }
 62  
 
 63  
     public BeanTag(Class defaultClass, String tagName) {
 64  93
         this(defaultClass, tagName, null);
 65  93
     }
 66  
 
 67  
     public BeanTag(Class defaultClass, String tagName, Method invokeMethod) {
 68  120
         super(defaultClass);
 69  120
         this.tagName = tagName;
 70  120
         this.invokeMethod = invokeMethod;
 71  
 
 72  120
         if (tagName.length() > 0) {
 73  120
             addMethodName = "add"
 74  
                 + tagName.substring(0,1).toUpperCase()
 75  
                 + tagName.substring(1);
 76  
         }
 77  120
     }
 78  
 
 79  
     /**
 80  
      * @return the local name of the XML tag to which this tag is bound
 81  
      */
 82  
     public String getTagName() {
 83  0
         return tagName;
 84  
     }
 85  
 
 86  
     /**
 87  
      * Output the tag as a named variable. If the parent bean has an adder or setter
 88  
      * method then invoke that to register this bean with its parent.
 89  
      */
 90  
     protected void processBean(String var, Object bean) throws JellyTagException {
 91  120
         if (var != null) {
 92  12
             context.setVariable(var, bean);
 93  
         }
 94  
 
 95  
         // now lets try set the parent property via calling the adder or the setter method
 96  120
         if (bean != null) {
 97  120
             Tag parent = this;
 98  
 
 99  
             while (true) {
 100  144
                 parent = parent.getParent();
 101  144
                 if (parent == null) {
 102  12
                     break;
 103  
                 }
 104  
 
 105  132
                 if (parent instanceof BeanSource) {
 106  102
                     BeanSource source = (BeanSource) parent;
 107  102
                     Object parentObject = source.getBean();
 108  102
                     if (parentObject != null) {
 109  102
                         if (parentObject instanceof Collection) {
 110  6
                             Collection collection = (Collection) parentObject;
 111  6
                             collection.add(bean);
 112  
                         }
 113  
                         else {
 114  
                             // lets see if there's a setter method...
 115  96
                             Method method = findAddMethod(parentObject.getClass(), bean.getClass());
 116  96
                             if (method != null) {
 117  96
                                 Object[] args = { bean };
 118  
                                 try {
 119  96
                                     method.invoke(parentObject, args);
 120  
                                 }
 121  0
                                 catch (Exception e) {
 122  0
                                     throw new JellyTagException( "failed to invoke method: " + method + " on bean: " + parentObject + " reason: " + e, e );
 123  192
                                 }
 124  
                             }
 125  
                             else {
 126  
                                 try {
 127  0
                                   BeanUtils.setProperty(parentObject, tagName, bean);
 128  0
                                 } catch (IllegalAccessException e) {
 129  0
                                     throw new JellyTagException(e);
 130  0
                                 } catch (InvocationTargetException e) {
 131  0
                                     throw new JellyTagException(e);
 132  96
                                 }
 133  
                             }
 134  
                         }
 135  
                     }
 136  
                     else {
 137  0
                         log.warn("Cannot process null bean for tag: " + parent);
 138  
                     }
 139  
                 }
 140  30
                 else if (parent instanceof CollectionTag) {
 141  6
                     CollectionTag tag = (CollectionTag) parent;
 142  6
                     tag.addItem(bean);
 143  
                 }
 144  
                 else {
 145  
                     continue;
 146  
                 }
 147  
                 break;
 148  
             }
 149  
 
 150  120
             if (invokeMethod != null) {
 151  3
                 Object[] args = { bean };
 152  
                 try {
 153  3
                     invokeMethod.invoke(bean, EMPTY_ARGUMENTS);
 154  
                 }
 155  0
                 catch (Exception e) {
 156  0
                     throw new JellyTagException( "failed to invoke method: " + invokeMethod + " on bean: " + bean + " reason: " + e, e );
 157  6
                 }
 158  
             }
 159  
             else {
 160  117
                 if (parent == null && var == class="keyword">null) {
 161  
                     //warn if the bean gets lost in space
 162  0
                     log.warn( "Could not add bean to parent for bean: " + bean );
 163  
                 }
 164  
             }
 165  
         }
 166  120
     }
 167  
 
 168  
     /**
 169  
      * Finds the Method to add the new bean
 170  
      */
 171  
     protected Method findAddMethod(Class beanClass, Class valueClass) {
 172  96
         if (addMethodName == null) {
 173  0
             return null;
 174  
         }
 175  96
         Class[] argTypes = { valueClass };
 176  96
         return MethodUtils.getAccessibleMethod(
 177  
             beanClass, addMethodName, argTypes
 178  
         );
 179  
     }
 180  
 
 181  
 
 182  
     /**
 183  
      * @return the parent bean object
 184  
      */
 185  
     protected Object getParentObject() throws JellyTagException {
 186  90
         BeanSource tag = (BeanSource) findAncestorWithClass(BeanSource.class);
 187  90
         if (tag != null) {
 188  90
             return tag.getBean();
 189  
         }
 190  0
         return null;
 191  
     }
 192  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.