Coverage Report - org.apache.commons.betwixt.strategy.TypeBindingStrategy

Classes in this File Line Coverage Branch Coverage Complexity
TypeBindingStrategy
81% 
100% 
4.429

 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  
 package org.apache.commons.betwixt.strategy;
 17  
 
 18  
 import java.io.Serializable;
 19  
 import java.util.Date;
 20  
 
 21  
 /**
 22  
  * Determines the way that a type (of object) should be bound
 23  
  * by Betwixt.
 24  
  * 
 25  
  * @author <a href='http://commons.apache.org'>Apache Commons Team</a>, <a href='http://www.apache.org'>Apache Software Foundation</a>
 26  
  */
 27  2040
 public abstract class TypeBindingStrategy {
 28  
     
 29  
     /**
 30  
      * The default Betwixt <code>TypeBindingStrategy</code> implementation.
 31  
      * Since the default implementation has no state, 
 32  
      * a singleton instance can be provided.
 33  
      */
 34  1020
     public static final TypeBindingStrategy DEFAULT = new Default();
 35  
     
 36  
     /**
 37  
      * Gets the binding type to be used for the given Java type.
 38  
      * @param type <code>Class</code> for which the binding type is to be determined,
 39  
      * not null
 40  
      * @return <code>BindingType</code> enumeration indicating the type of binding,
 41  
      * not null
 42  
      */
 43  
     public abstract BindingType bindingType(Class type);
 44  
     
 45  
 
 46  
     /**
 47  
      * Enumerates the possible general ways that Betwixt can map a Java type to an XML type.
 48  
      * @author <a href='http://commons.apache.org'>Apache Commons Team</a>, <a href='http://www.apache.org'>Apache Software Foundation</a>
 49  
      */
 50  955
     public static final class BindingType implements Serializable {
 51  
         
 52  
         private static final int COMPLEX_INDICATOR = 1;
 53  
         private static final int PRIMITIVE_INDICATOR = 2;
 54  
         
 55  
         /**
 56  
          * Indicates that the java type should be bound to a complex xml type.
 57  
          * A complex xml type may have child elements and attributes.
 58  
          * Betwixt determines the mapping for a java bean bound to a complex type.  
 59  
          */
 60  955
         public static final BindingType COMPLEX = new BindingType(COMPLEX_INDICATOR);
 61  
         
 62  
         /**
 63  
          * Indicates that the type should be bound as a Java primitive.
 64  
          * Betwixt may bind this to an attribute or a simple xml type.
 65  
          * Which is determined by the configuration for binding primitives.
 66  
          */
 67  955
         public static final BindingType PRIMITIVE = new BindingType(PRIMITIVE_INDICATOR);
 68  
         
 69  
         private int type;
 70  
         
 71  1910
         private BindingType(int type) {
 72  1910
             this.type = type;
 73  1910
         }
 74  
         
 75  
         
 76  
         /**
 77  
          * @see java.lang.Object#equals(java.lang.Object)
 78  
          */
 79  
         public boolean equals(Object object) {
 80  26102
             boolean result = false;
 81  26102
             if (object instanceof BindingType) {
 82  26102
                 BindingType bindingType = (BindingType) object;
 83  26102
                 result = (type == bindingType.type);
 84  
             }
 85  26102
             return result;
 86  
         }
 87  
         
 88  
         /**
 89  
          * @see java.lang.Object#hashCode()
 90  
          */
 91  
         public int hashCode() {
 92  0
             return type;
 93  
         }
 94  
         
 95  
         /**
 96  
          * @see java.lang.Object#toString()
 97  
          */
 98  
         public String toString() {
 99  0
             StringBuffer buffer = new StringBuffer();
 100  0
             buffer.append("BindingType: ");
 101  0
             switch (type) {
 102  
                               case (COMPLEX_INDICATOR):
 103  0
                                           buffer.append("COMPLEX");
 104  0
                                                 break;
 105  
             
 106  
                             case (PRIMITIVE_INDICATOR):
 107  0
                                 buffer.append("PRIMITIVE");
 108  
                                 break;
 109  
             }
 110  
             
 111  0
             return buffer.toString();
 112  
         }
 113  
 }
 114  
     
 115  
     /**
 116  
      * The default <code>TypeBindingStrategy</code> used by Betwixt.
 117  
      * This implementation recognizes all the usual Java primitive wrappers 
 118  
      * (plus a few more that will in most typical use cases be regarded in the same way). 
 119  
      * @author <a href='http://commons.apache.org'>Apache Commons Team</a>, <a href='http://www.apache.org'>Apache Software Foundation</a>
 120  
      */
 121  2040
     public static final class Default extends TypeBindingStrategy {
 122  
 
 123  
         /**
 124  
          * Class who are simple and whose subclass are also simple
 125  
          */
 126  2040
         private static final Class[] INHERITED_SIMPLE = {
 127  1020
                                                         Number.class, 
 128  1020
                                                         String.class,
 129  1020
                                                         Date.class,
 130  1020
                                                         java.sql.Date.class,
 131  1020
                                                         java.sql.Time.class,
 132  1020
                                                         java.sql.Timestamp.class,
 133  1020
                                                         java.math.BigDecimal.class,
 134  1020
                                                         java.math.BigInteger.class};
 135  
                                                         
 136  
         /**
 137  
          * Classes who are complex and whose subclasses are also complex
 138  
          */
 139  2040
         private static final Class[] INHERITED_COMPLEX = {
 140  1020
                                                                                                 Throwable.class
 141  
                                                                         };
 142  
 
 143  
         /**
 144  
          * Gets the binding type to be used for the given Java type.
 145  
          * This implementation recognizes all the usual Java primitive wrappers 
 146  
          * (plus a few more that will in most typical use cases be regarded in the same way). 
 147  
          * @param type <code>Class</code> for which the binding type is to be determined,
 148  
          * not null
 149  
          * @return <code>BindingType</code> enumeration indicating the type of binding,
 150  
          * not null
 151  
          */
 152  
         public BindingType bindingType(Class type) {
 153  26102
             BindingType result =  BindingType.COMPLEX;
 154  26102
             if (isStandardPrimitive(type)) {
 155  13169
                 result = BindingType.PRIMITIVE;
 156  
             }
 157  
        
 158  26102
             return result;
 159  
         }
 160  
         
 161  
         /**
 162  
          * is the given type one of the standard Betwixt primitives?
 163  
          * @param type <code>Class</code>, not null
 164  
          * @return true if the type is one of the standard Betwixt primitives
 165  
          */
 166  
         protected boolean isStandardPrimitive(Class type) {
 167  26102
             if ( type == null ) {
 168  0
                 return false;
 169  
                 
 170  26102
             } else if ( type.isPrimitive() ) {
 171  1170
                 return true;
 172  
                 
 173  24932
             } else if ( type.equals( Object.class ) ) {
 174  344
                 return false;
 175  
             }
 176  141524
             for ( int i=0, size=INHERITED_SIMPLE.length; i<size; i++ ) {
 177  128649
                 if ( INHERITED_SIMPLE[i].equals( type ) ) {
 178  11713
                     return true;
 179  
                 }
 180  
             }
 181  
     
 182  25750
             for ( int i=0, size=INHERITED_COMPLEX.length; i<size; i++ ) {
 183  12875
                 if ( INHERITED_COMPLEX[i].equals( type ) ) {
 184  0
                     return false;
 185  
                 }
 186  
             }
 187  
             
 188  25737
             for ( int i=0, size=INHERITED_COMPLEX.length; i<size; i++ ) {
 189  12875
                 if ( INHERITED_COMPLEX[i].isAssignableFrom( type ) ) {
 190  13
                     return false;
 191  
                 }
 192  
             }     
 193  
             
 194  12862
             if (type.getName().startsWith( "java.lang." )) {
 195  286
                 return true;
 196  
             }
 197  
             
 198  113184
             for ( int i=0, size=INHERITED_SIMPLE.length; i<size; i++ ) {
 199  100608
                 if ( INHERITED_SIMPLE[i].isAssignableFrom( type ) ) {
 200  0
                     return true;
 201  
                 }
 202  
             }            
 203  12576
             return false;
 204  
         }
 205  
     }
 206  
 }