Coverage Report - org.apache.commons.betwixt.digester.AddDefaultsRule

Classes in this File Line Coverage Branch Coverage Complexity
AddDefaultsRule
76% 
90% 
4.429

 1  
 /*
 2  
  * Copyright 2001-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  
 package org.apache.commons.betwixt.digester;
 17  
 
 18  
 import java.beans.BeanInfo;
 19  
 import java.beans.Introspector;
 20  
 import java.beans.PropertyDescriptor;
 21  
 import java.util.Set;
 22  
 
 23  
 import org.apache.commons.betwixt.AttributeDescriptor;
 24  
 import org.apache.commons.betwixt.BeanProperty;
 25  
 import org.apache.commons.betwixt.Descriptor;
 26  
 import org.apache.commons.betwixt.ElementDescriptor;
 27  
 import org.apache.commons.betwixt.NodeDescriptor;
 28  
 import org.apache.commons.betwixt.XMLBeanInfo;
 29  
 import org.apache.commons.logging.Log;
 30  
 import org.apache.commons.logging.LogFactory;
 31  
 import org.xml.sax.Attributes;
 32  
 import org.xml.sax.SAXException;
 33  
 
 34  
 /** <p><code>AddDefaultsRule</code> appends all the default properties
 35  
   * to the current element.</p>
 36  
   *
 37  
   * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 38  
   */
 39  604
 public class AddDefaultsRule extends RuleSupport {
 40  
 
 41  
     /** Logger */
 42  604
     private static final Log log = LogFactory.getLog( AddDefaultsRule.class );
 43  
     
 44  
     /** Base constructor */
 45  1624
     public AddDefaultsRule() {
 46  1624
     }
 47  
     
 48  
     // Rule interface
 49  
     //-------------------------------------------------------------------------    
 50  
     
 51  
     /**
 52  
      * Process the beginning of this element.
 53  
      *
 54  
      * @param attributes The attribute list of this element
 55  
      * @throws Exception generally this will indicate an unrecoverable error 
 56  
      */
 57  
     public void begin(String name, String namespace, Attributes attributes) throws Exception {
 58  936
         boolean addProperties = true;
 59  936
         String addPropertiesAttributeValue = attributes.getValue("add-properties");
 60  936
         if (addPropertiesAttributeValue != null)
 61  
         {
 62  104
             addProperties = Boolean.valueOf(addPropertiesAttributeValue).booleanValue();
 63  
         }
 64  
         
 65  936
         boolean addAdders = true;
 66  936
         String addAddersAttributeValue = attributes.getValue("add-adders");
 67  936
         if (addAddersAttributeValue != null)
 68  
         {
 69  78
             addAdders = Boolean.valueOf(addAddersAttributeValue).booleanValue();
 70  
         }
 71  
         
 72  936
         boolean guessNames = true;
 73  936
         String guessNamesAttributeValue = attributes.getValue("guess-names");
 74  936
         if (guessNamesAttributeValue != null)
 75  
         {
 76  26
             guessNames = Boolean.valueOf(guessNamesAttributeValue).booleanValue();
 77  
         }
 78  
         
 79  936
         if (addProperties) {
 80  897
             addDefaultProperties();
 81  
         }
 82  
         
 83  936
         if (addAdders) {
 84  871
             addAdders(guessNames);
 85  
         }
 86  936
     }
 87  
 
 88  
     /**
 89  
      * Adds default adder methods
 90  
      */
 91  
     private void addAdders(boolean guessNames) {
 92  871
         Class beanClass = getBeanClass();
 93  
         // default any addProperty() methods
 94  1742
         getXMLIntrospector().defaultAddMethods( 
 95  871
                                             getRootElementDescriptor(), 
 96  871
                                             beanClass, !guessNames);
 97  871
     }
 98  
 
 99  
     /**
 100  
      * Adds default property methods
 101  
      *
 102  
      */
 103  
     private void addDefaultProperties() {
 104  897
         Class beanClass = getBeanClass();
 105  897
         Set processedProperties = getProcessedPropertyNameSet();
 106  897
         if ( beanClass != null ) {
 107  
             try {
 108  884
                 boolean attributesForPrimitives = getXMLInfoDigester().isAttributesForPrimitives();
 109  
                 BeanInfo beanInfo;
 110  884
                 if( getXMLIntrospector().getConfiguration().ignoreAllBeanInfo() ) {
 111  0
                     beanInfo = Introspector.getBeanInfo( beanClass, Introspector.IGNORE_ALL_BEANINFO );
 112  
                 }
 113  
                 else {
 114  884
                     beanInfo = Introspector.getBeanInfo( beanClass );
 115  
                 }
 116  884
                 PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
 117  884
                 if ( descriptors != null ) {
 118  6136
                     for ( int i = 0, size = descriptors.length; i < size; i++ ) {
 119  5252
                         PropertyDescriptor descriptor = descriptors[i];
 120  
                         // have we already created a property for this
 121  5252
                         String propertyName = descriptor.getName();
 122  5252
                         if ( processedProperties.contains( propertyName ) ) {
 123  1768
                             continue;
 124  
                         }
 125  3484
                         if (!getXMLIntrospector().getConfiguration().getPropertySuppressionStrategy()
 126  3484
                                 .suppressProperty(
 127  3484
                                         beanClass,
 128  3484
                                         descriptor.getPropertyType(),
 129  3484
                                         descriptor.getName())) {
 130  2613
                                 Descriptor nodeDescriptor = 
 131  2613
                                                 getXMLIntrospector().createXMLDescriptor(new BeanProperty(descriptor));
 132  2613
                                 if ( nodeDescriptor != null ) {
 133  2613
                                     addDescriptor( nodeDescriptor );
 134  
                                 }
 135  
                         }
 136  
                     }
 137  
                 }
 138  0
             } catch (Exception e) {
 139  0
                 log.info( "Caught introspection exception", e );
 140  
             }
 141  
         }
 142  897
     }
 143  
 
 144  
 
 145  
     // Implementation methods
 146  
     //-------------------------------------------------------------------------    
 147  
    
 148  
     /**
 149  
     * Add a desciptor to the top object on the Digester stack.
 150  
     * 
 151  
     * @param nodeDescriptor add this <code>NodeDescriptor</code>. Must not be null.
 152  
     * @throws SAXException if the parent for the addDefaults element is not a <element> 
 153  
     * or if the top object on the stack is not a <code>XMLBeanInfo</code> or a 
 154  
     * <code>ElementDescriptor</code>
 155  
     * @deprecated 0.5 replaced {@link #addDescriptor( Descriptor )} 
 156  
     */
 157  
     protected void addDescriptor( NodeDescriptor nodeDescriptor ) throws SAXException {
 158  0
         addDescriptor( (Descriptor) nodeDescriptor );
 159  0
     }
 160  
       
 161  
     /**
 162  
     * Add a desciptor to the top object on the Digester stack.
 163  
     * 
 164  
     * @param nodeDescriptor add this <code>NodeDescriptor</code>. Must not be null.
 165  
     * @throws SAXException if the parent for the addDefaults element is not a <element> 
 166  
     * or if the top object on the stack is not a <code>XMLBeanInfo</code> or a 
 167  
     * <code>ElementDescriptor</code>
 168  
     * @since 0.5
 169  
     */
 170  
     protected void addDescriptor( Descriptor nodeDescriptor ) throws SAXException {
 171  2613
         Object top = digester.peek();
 172  2613
         if ( top instanceof XMLBeanInfo ) {
 173  0
             log.warn( "It is advisable to put an <addDefaults/> element inside an <element> tag" );
 174  
             
 175  0
             XMLBeanInfo beanInfo = (XMLBeanInfo) top;
 176  
             // if there is already a root element descriptor then use it
 177  
             // otherwise use this descriptor
 178  0
             if ( nodeDescriptor instanceof ElementDescriptor ) {
 179  0
                 ElementDescriptor elementDescriptor = (ElementDescriptor) nodeDescriptor;
 180  0
                 ElementDescriptor root = beanInfo.getElementDescriptor() ;
 181  0
                 if ( root == null ) {
 182  0
                     beanInfo.setElementDescriptor( elementDescriptor );
 183  
                 } else {
 184  0
                     root.addElementDescriptor( elementDescriptor );
 185  
                 }
 186  
             } else { 
 187  0
                 throw new SAXException( 
 188  0
                     "the <addDefaults> element should be within an <element> tag" );
 189  
             }
 190  2613
         } else if ( top instanceof ElementDescriptor ) {
 191  2613
             ElementDescriptor parent = (ElementDescriptor) top;
 192  2613
             if ( nodeDescriptor instanceof ElementDescriptor ) {
 193  2522
                 parent.addElementDescriptor( (ElementDescriptor) nodeDescriptor );
 194  
             } else {
 195  91
                 parent.addAttributeDescriptor( (AttributeDescriptor) nodeDescriptor );
 196  
             }
 197  
         } else {
 198  0
             throw new SAXException( 
 199  0
                 "Invalid use of <addDefaults>. It should be nested inside <element> element" );
 200  
         }            
 201  2613
     }     
 202  
 
 203  
     /**
 204  
      * Gets an <code>ElementDescriptor</code> for the top on digester's stack.
 205  
      *
 206  
      * @return the top object or the element description if the top object 
 207  
      * is an <code>ElementDescriptor</code> or a <code>XMLBeanInfo</code> class (respectively)
 208  
      * Otherwise null.
 209  
      */
 210  
     protected ElementDescriptor getRootElementDescriptor() {
 211  871
         Object top = digester.peek();
 212  871
         if ( top instanceof XMLBeanInfo ) {
 213  0
             XMLBeanInfo beanInfo = (XMLBeanInfo) top;
 214  0
             return beanInfo.getElementDescriptor();
 215  
             
 216  871
         } else if ( top instanceof ElementDescriptor ) {
 217  871
             ElementDescriptor parent = (ElementDescriptor) top;
 218  
             // XXX: could maybe walk up the parent hierarchy?
 219  871
             return parent;
 220  
         }
 221  0
         return null;
 222  
     }
 223  
 }