Coverage Report - org.apache.commons.betwixt.IntrospectionConfiguration

Classes in this File Line Coverage Branch Coverage Complexity
IntrospectionConfiguration
85% 
100% 
1.091

 1  
 /*
 2  
  * Copyright 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.betwixt;
 18  
 
 19  
 import org.apache.commons.betwixt.strategy.ClassNormalizer;
 20  
 import org.apache.commons.betwixt.strategy.CollectiveTypeStrategy;
 21  
 import org.apache.commons.betwixt.strategy.DefaultNameMapper;
 22  
 import org.apache.commons.betwixt.strategy.DefaultPluralStemmer;
 23  
 import org.apache.commons.betwixt.strategy.MappingDerivationStrategy;
 24  
 import org.apache.commons.betwixt.strategy.NameMapper;
 25  
 import org.apache.commons.betwixt.strategy.NamespacePrefixMapper;
 26  
 import org.apache.commons.betwixt.strategy.PluralStemmer;
 27  
 import org.apache.commons.betwixt.strategy.PropertySuppressionStrategy;
 28  
 import org.apache.commons.betwixt.strategy.SimpleTypeMapper;
 29  
 import org.apache.commons.betwixt.strategy.StandardSimpleTypeMapper;
 30  
 import org.apache.commons.betwixt.strategy.TypeBindingStrategy;
 31  
 import org.apache.commons.logging.Log;
 32  
 import org.apache.commons.logging.LogFactory;
 33  
 
 34  
 /**
 35  
  * <p>Stores introspection phase binding configuration.</p>
 36  
  * <p>
 37  
  * There are two phase in Betwixt's processing. 
 38  
  * The first phase is the introspection of the bean. 
 39  
  * Strutural configuration settings effect this phase. 
 40  
  * The second phase comes when Betwixt dynamically uses reflection 
 41  
  * to execute the mapping. 
 42  
  * This object stores configuration settings pertaining to the first phase.
 43  
  * </p>
 44  
  * <p>
 45  
  * These common settings have been collected into one class so that they can  
 46  
  * be more easily shared not only between the objects that execute the introspection
 47  
  * but also (by a user) between different <code>XMLIntrospector</code>s.
 48  
  * </p>
 49  
  * @author <a href='http://jakarta.apache.org/'>Apache Commons Team</a>
 50  
  * @version $Revision: 397648 $
 51  
  */
 52  7396
 public class IntrospectionConfiguration {
 53  
 
 54  
     /** should attributes or elements be used for primitive types */
 55  3698
     private boolean attributesForPrimitives = false;
 56  
     
 57  2208
     /** should we wrap collections in an extra element? */
 58  3698
     private boolean wrapCollectionsInElement = true;
 59  
 
 60  1104
     /** Should the existing bean info search path for java.reflect.Introspector be used? */
 61  3698
     private boolean useBeanInfoSearchPath = false;
 62  
     
 63  1104
     /** Should existing BeanInfo classes be used at all for java.reflect.Introspector */
 64  3698
     private boolean ignoreAllBeanInfo = false;
 65  
 
 66  1104
     // pluggable strategies        
 67  
     /** The strategy used to detect matching singular and plural properties */
 68  
     private PluralStemmer pluralStemmer;
 69  1104
     
 70  
     /** The strategy used to convert bean type names into element names */
 71  
     private NameMapper elementNameMapper;
 72  
 
 73  
     /** Strategy normalizes the Class of the Object before introspection */
 74  3698
     private ClassNormalizer classNormalizer = new ClassNormalizer(); 
 75  
     
 76  
     /** Log for introspection messages */
 77  3698
     private Log introspectionLog = LogFactory.getLog(XMLIntrospector.class);
 78  
 
 79  1104
     /**
 80  
      * The strategy used to convert bean type names into attribute names
 81  
      * It will default to the normal nameMapper.
 82  1104
      */
 83  
     private NameMapper attributeNameMapper;
 84  
 
 85  
     /** Prefix naming strategy */
 86  3698
     private NamespacePrefixMapper prefixMapper = new NamespacePrefixMapper();
 87  
     /** Mapping strategy for simple types */
 88  3698
     private SimpleTypeMapper simpleTypeMapper = new StandardSimpleTypeMapper();
 89  
     /** Binding strategy for Java type */
 90  3698
     private TypeBindingStrategy typeBindingStrategy = TypeBindingStrategy.DEFAULT;
 91  1104
     /** Strategy used for determining which types are collective */
 92  3698
     private CollectiveTypeStrategy collectiveTypeStrategy = CollectiveTypeStrategy.DEFAULT;
 93  1104
     
 94  
     /** 
 95  1104
      * Strategy used to determine whether the bind or introspection time type is to be used to  
 96  
      * determine the mapping.
 97  1104
      */
 98  3698
             private MappingDerivationStrategy mappingDerivationStrategy = MappingDerivationStrategy.DEFAULT;
 99  
     
 100  
             /**
 101  
              * Strategy used to determine which properties should be ignored
 102  
              */
 103  4802
             private PropertySuppressionStrategy propertySuppressionStrategy = PropertySuppressionStrategy.DEFAULT;
 104  
             
 105  
     /**
 106  
       * Gets the <code>ClassNormalizer</code> strategy.
 107  
       * This is used to determine the Class to be introspected
 108  1104
       * (the normalized Class). 
 109  
       *
 110  
       * @return the <code>ClassNormalizer</code> used to determine the Class to be introspected
 111  
       * for a given Object.
 112  
       */
 113  
     public ClassNormalizer getClassNormalizer() {
 114  7248
         return classNormalizer;
 115  
     }
 116  
     
 117  
     /**
 118  
       * Sets the <code>ClassNormalizer</code> strategy.
 119  2169
       * This is used to determine the Class to be introspected
 120  
       * (the normalized Class). 
 121  
       *
 122  
       * @param classNormalizer the <code>ClassNormalizer</code> to be used to determine 
 123  
       * the Class to be introspected for a given Object.
 124  
       */    
 125  
     public void setClassNormalizer(ClassNormalizer classNormalizer) {
 126  30
         this.classNormalizer = classNormalizer;
 127  30
     }
 128  
 
 129  
     /** 
 130  
       * Should attributes (or elements) be used for primitive types.
 131  9
       * @return true if primitive types will be mapped to attributes in the introspection
 132  9
       */
 133  
     public boolean isAttributesForPrimitives() {
 134  7570
         return attributesForPrimitives;
 135  
     }
 136  
 
 137  
     /** 
 138  
       * Set whether attributes (or elements) should be used for primitive types. 
 139  2271
       * @param attributesForPrimitives pass trus to map primitives to attributes,
 140  
       *        pass false to map primitives to elements
 141  
       */
 142  
     public void setAttributesForPrimitives(boolean attributesForPrimitives) {
 143  4930
         this.attributesForPrimitives = attributesForPrimitives;
 144  4930
     }
 145  
     
 146  
     /**
 147  
      * Should collections be wrapped in an extra element?
 148  1479
      * 
 149  1479
      * @return whether we should we wrap collections in an extra element? 
 150  
      */
 151  
     public boolean isWrapCollectionsInElement() {
 152  1730
         return wrapCollectionsInElement;
 153  
     }
 154  
 
 155  
     /** 
 156  
      * Sets whether we should we wrap collections in an extra element.
 157  519
      *
 158  
      * @param wrapCollectionsInElement pass true if collections should be wrapped in a
 159  
      *        parent element
 160  
      */
 161  
     public void setWrapCollectionsInElement(boolean wrapCollectionsInElement) {
 162  820
         this.wrapCollectionsInElement = wrapCollectionsInElement;
 163  820
     }    
 164  
 
 165  
     /** 
 166  
      * Get singular and plural matching strategy.
 167  246
      *
 168  246
      * @return the strategy used to detect matching singular and plural properties 
 169  
      */
 170  
     public PluralStemmer getPluralStemmer() {
 171  2016
         if ( pluralStemmer == null ) {
 172  1288
             pluralStemmer = createPluralStemmer();
 173  
         }
 174  2016
         return pluralStemmer;
 175  
     }
 176  594
     
 177  381
     /** 
 178  
      * Sets the strategy used to detect matching singular and plural properties 
 179  594
      *
 180  
      * @param pluralStemmer the PluralStemmer used to match singular and plural
 181  
      */
 182  
     public void setPluralStemmer(PluralStemmer pluralStemmer) {
 183  20
         this.pluralStemmer = pluralStemmer;
 184  20
     }
 185  
     
 186  
     /**
 187  
      * Gets the name mapping strategy used to convert bean names into elements.
 188  6
      *
 189  6
      * @return the strategy used to convert bean type names into element 
 190  
      * names. If no element mapper is currently defined then a default one is created.
 191  
      */
 192  
     public NameMapper getElementNameMapper() {
 193  15164
         if ( elementNameMapper == null ) {
 194  1858
             elementNameMapper = createNameMapper();
 195  
          }
 196  15164
         return elementNameMapper;
 197  
     }
 198  4542
      
 199  552
     /**
 200  
      * Sets the strategy used to convert bean type names into element names
 201  4542
      * @param nameMapper the NameMapper to use for the conversion
 202  
      */
 203  
     public void setElementNameMapper(NameMapper nameMapper) {
 204  480
         this.elementNameMapper = nameMapper;
 205  480
     }
 206  
     
 207  
     /**
 208  
      * Gets the name mapping strategy used to convert bean names into attributes.
 209  144
      *
 210  144
      * @return the strategy used to convert bean type names into attribute
 211  
      * names. If no attributeNamemapper is known, it will default to the ElementNameMapper
 212  
      */
 213  
     public NameMapper getAttributeNameMapper() {
 214  2220
         if (attributeNameMapper == null) {
 215  470
             attributeNameMapper = createNameMapper();
 216  
         }
 217  2220
         return attributeNameMapper;
 218  
      }
 219  666
 
 220  141
 
 221  
     /**
 222  666
      * Sets the strategy used to convert bean type names into attribute names
 223  
      * @param nameMapper the NameMapper to use for the convertion
 224  
      */
 225  
     public void setAttributeNameMapper(NameMapper nameMapper) {
 226  200
         this.attributeNameMapper = nameMapper;
 227  200
     }
 228  
     
 229  
     /**
 230  
      * <p>Should the original <code>java.reflect.Introspector</code> bean info search path be used?</p>
 231  60
      * <p>
 232  60
      * Default is false.
 233  
      * </p>
 234  
      * 
 235  
      * @return boolean if the beanInfoSearchPath should be used.
 236  
      */
 237  
     public boolean useBeanInfoSearchPath() {
 238  33460
         return useBeanInfoSearchPath;
 239  
     }
 240  
 
 241  
     /**
 242  
      * Specifies if you want to use the beanInfoSearchPath 
 243  9966
      * @see java.beans.Introspector for more details
 244  
      * @param useBeanInfoSearchPath 
 245  
      */
 246  
     public void setUseBeanInfoSearchPath(boolean useBeanInfoSearchPath) {
 247  0
         this.useBeanInfoSearchPath = useBeanInfoSearchPath;
 248  0
     }
 249  
     
 250  
     /**
 251  
      * <p>Should existing BeanInfo classes be ignored by <code>java.reflect.Introspector</code>.</p>
 252  0
      * <p>
 253  0
      * Default is false.
 254  
      * </p>
 255  
      * 
 256  
      * @return boolean if the BeanInfo classes should be used.
 257  
      */
 258  
     public boolean ignoreAllBeanInfo() {
 259  12764
         return ignoreAllBeanInfo;
 260  
     }
 261  
     
 262  
     /**
 263  
      * Specifies if you want to ignore existing BeanInfo classes at all for introspection
 264  3822
      * @see java.beans.Introspector for more details
 265  
      * @param ignoreAllBeanInfo set to true to ignore all BeanInfo classes
 266  
      */
 267  
     public void setIgnoreAllBeanInfo(boolean ignoreAllBeanInfo) {
 268  20
         this.ignoreAllBeanInfo = ignoreAllBeanInfo;
 269  20
     }
 270  
     
 271  
     
 272  
     /** 
 273  6
      * A Factory method to lazily create a new strategy 
 274  6
      * to detect matching singular and plural properties.
 275  
      *
 276  
      * @return new defualt PluralStemmer implementation
 277  
      */
 278  
     protected PluralStemmer createPluralStemmer() {
 279  1288
         return new DefaultPluralStemmer();
 280  
     }
 281  
     
 282  
     /** 
 283  
      * A Factory method to lazily create a strategy 
 284  381
      * used to convert bean type names into element names.
 285  
      *
 286  
      * @return new default NameMapper implementation
 287  
      */
 288  
     protected NameMapper createNameMapper() {
 289  2328
         return new DefaultNameMapper();
 290  
     }
 291  
     
 292  
     /**
 293  
      * Gets the common Log used for introspection.
 294  693
      * It is more convenient to use a single Log
 295  
      * that can be easily configured.
 296  
      * @return Log, not null
 297  
      */
 298  
     public Log getIntrospectionLog() {
 299  95794
         return introspectionLog;
 300  
     }
 301  
 
 302  
     /**
 303  
      * Sets the common Log used by introspection.
 304  28569
      * It is more convenient to use a single Log
 305  
      * that can be easily configured.
 306  
      * @param log Log, not null
 307  
      */
 308  
     public void setIntrospectionLog(Log log) {
 309  0
         introspectionLog = log;
 310  0
     }
 311  
 
 312  
     
 313  
     /**
 314  0
      * Gets the <code>NamespacePrefixMapper</code> used to convert namespace URIs 
 315  0
      * into prefixes.
 316  
      * @return NamespacePrefixMapper, not null
 317  
      */
 318  
     public NamespacePrefixMapper getPrefixMapper() {
 319  2100
         return prefixMapper;
 320  
     }
 321  
 
 322  
     /**
 323  
      * Sets the <code>NamespacePrefixMapper</code> used to convert namespave URIs
 324  630
      * into prefixes.
 325  
      * @param mapper NamespacePrefixMapper, not null
 326  
      */
 327  
     public void setPrefixMapper(NamespacePrefixMapper mapper) {
 328  0
         prefixMapper = mapper;
 329  0
     }
 330  
     
 331  
     
 332  
     /**
 333  0
      * Gets the simple type binding strategy.
 334  0
      * @return SimpleTypeMapper, not null
 335  
      */
 336  
     public SimpleTypeMapper getSimpleTypeMapper() {
 337  7720
         return simpleTypeMapper;
 338  
     }
 339  
 
 340  
     /**
 341  
      * Sets the simple type binding strategy.
 342  2316
      * @param mapper SimpleTypeMapper, not null
 343  
      */
 344  
     public void setSimpleTypeMapper(SimpleTypeMapper mapper) {
 345  30
         simpleTypeMapper = mapper;
 346  30
     }
 347  
 
 348  
     /**
 349  
      * Gets the <code>TypeBindingStrategy</code> to be used
 350  9
      * to determine the binding for Java types.
 351  9
      * @return the <code>TypeBindingStrategy</code> to be used, 
 352  
      * not null
 353  
      */
 354  
     public TypeBindingStrategy getTypeBindingStrategy() {
 355  20074
         return typeBindingStrategy;
 356  
     }
 357  
     
 358  
     /**
 359  
      * Sets the <code>TypeBindingStrategy</code> to be used
 360  6015
      * to determine the binding for Java types.
 361  
      * @param typeBindingStrategy the <code>TypeBindingStrategy</code> to be used,
 362  
      * not null
 363  
      */
 364  
     public void setTypeBindingStrategy(TypeBindingStrategy typeBindingStrategy) {
 365  0
         this.typeBindingStrategy = typeBindingStrategy;
 366  0
     }
 367  
     
 368  
     
 369  
     /**
 370  0
      * Gets the <code>MappingDerivationStrategy</code>
 371  0
      * used to determine whether the bind or introspection time
 372  
      * type should determine the mapping.
 373  
      * @since 0.7
 374  
      * @return <code>MappingDerivationStrategy</code>, not null
 375  
      */
 376  
     public MappingDerivationStrategy getMappingDerivationStrategy() {
 377  16412
         return mappingDerivationStrategy;
 378  
     }
 379  
     /**
 380  
      * Sets the <code>MappingDerivationStrategy</code>
 381  
      * used to determine whether the bind or introspection time
 382  4911
      * type should determine the mapping.
 383  
      * @since 0.7
 384  
      * @param mappingDerivationStrategy <code>MappingDerivationStrategy</code>, not null
 385  
      */
 386  
     public void setMappingDerivationStrategy(
 387  
             MappingDerivationStrategy mappingDerivationStrategy) {
 388  90
         this.mappingDerivationStrategy = mappingDerivationStrategy;
 389  90
     }
 390  
 
 391  
     /**
 392  
      * Gets the strategy which determines the properties to be ignored.
 393  27
      * @since 0.7
 394  27
      * @return the <code>PropertySuppressionStrategy</code> to be used for introspection, not null
 395  
      */
 396  
     public PropertySuppressionStrategy getPropertySuppressionStrategy() {
 397  14662
         return propertySuppressionStrategy;
 398  
     }
 399  
     
 400  
     /**
 401  
      * Sets the strategy which determines the properties to be ignored.
 402  4386
      * @since 0.7
 403  
      * @param propertySuppressionStrategy the <code>PropertySuppressionStrategy</code> to be used for introspection, not null
 404  
      */
 405  
     public void setPropertySuppressionStrategy(
 406  
             PropertySuppressionStrategy propertySuppressionStrategy) {
 407  30
         this.propertySuppressionStrategy = propertySuppressionStrategy;
 408  30
     }
 409  
     
 410  
     /**
 411  
      * Gets the strategy used to determine which types are collective.
 412  9
      * @return <code>CollectiveTypeStrategy</code>, not null
 413  9
      */
 414  
     public CollectiveTypeStrategy getCollectiveTypeStrategy() {
 415  17048
         return collectiveTypeStrategy;
 416  
     }
 417  
 
 418  
     /**
 419  
      * Sets the strategy used to determine which types are collective.
 420  5100
      * @param collectiveTypeStrategy <code>CollectiveTypeStrategy</code>, not null
 421  
      */
 422  
     public void setCollectiveTypeStrategy(
 423  
             CollectiveTypeStrategy collectiveTypeStrategy) {
 424  0
         this.collectiveTypeStrategy = collectiveTypeStrategy;
 425  0
     }
 426  
 
 427  
     /** 
 428  
      * Is this a loop type class?
 429  0
      * @since 0.7
 430  0
      * @param type is this <code>Class</code> a loop type?
 431  
      * @return true if the type is a loop type, or if type is null 
 432  
      */
 433  
     public boolean isLoopType(Class type) {
 434  17048
         return getCollectiveTypeStrategy().isCollective(type);
 435  
     }
 436  
 }