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. import java.io.Serializable;
  18. import java.util.Date;
  19. /**
  20. * Determines the way that a type (of object) should be bound
  21. * by Betwixt.
  22. *
  23. * @author <a href='http://jakarta.apache.org/commons'>Jakarta Commons Team</a>, <a href='http://www.apache.org'>Apache Software Foundation</a>
  24. */
  25. public abstract class TypeBindingStrategy {
  26. /**
  27. * The default Betwixt <code>TypeBindingStrategy</code> implementation.
  28. * Since the default implementation has no state,
  29. * a singleton instance can be provided.
  30. */
  31. public static final TypeBindingStrategy DEFAULT = new Default();
  32. /**
  33. * Gets the binding type to be used for the given Java type.
  34. * @param type <code>Class</code> for which the binding type is to be determined,
  35. * not null
  36. * @return <code>BindingType</code> enumeration indicating the type of binding,
  37. * not null
  38. */
  39. public abstract BindingType bindingType(Class type);
  40. /**
  41. * Enumerates the possible general ways that Betwixt can map a Java type to an XML type.
  42. * @author <a href='http://jakarta.apache.org/commons'>Jakarta Commons Team</a>, <a href='http://www.apache.org'>Apache Software Foundation</a>
  43. */
  44. public static final class BindingType implements Serializable {
  45. private static final int COMPLEX_INDICATOR = 1;
  46. private static final int PRIMITIVE_INDICATOR = 2;
  47. /**
  48. * Indicates that the java type should be bound to a complex xml type.
  49. * A complex xml type may have child elements and attributes.
  50. * Betwixt determines the mapping for a java bean bound to a complex type.
  51. */
  52. public static final BindingType COMPLEX = new BindingType(COMPLEX_INDICATOR);
  53. /**
  54. * Indicates that the type should be bound as a Java primitive.
  55. * Betwixt may bind this to an attribute or a simple xml type.
  56. * Which is determined by the configuration for binding primitives.
  57. */
  58. public static final BindingType PRIMITIVE = new BindingType(PRIMITIVE_INDICATOR);
  59. private int type;
  60. private BindingType(int type) {
  61. this.type = type;
  62. }
  63. /**
  64. * @see java.lang.Object#equals(java.lang.Object)
  65. */
  66. public boolean equals(Object object) {
  67. boolean result = false;
  68. if (object instanceof BindingType) {
  69. BindingType bindingType = (BindingType) object;
  70. result = (type == bindingType.type);
  71. }
  72. return result;
  73. }
  74. /**
  75. * @see java.lang.Object#hashCode()
  76. */
  77. public int hashCode() {
  78. return type;
  79. }
  80. /**
  81. * @see java.lang.Object#toString()
  82. */
  83. public String toString() {
  84. StringBuffer buffer = new StringBuffer();
  85. buffer.append("BindingType: ");
  86. switch (type) {
  87. case (COMPLEX_INDICATOR):
  88. buffer.append("COMPLEX");
  89. break;
  90. case (PRIMITIVE_INDICATOR):
  91. buffer.append("PRIMITIVE");
  92. break;
  93. }
  94. return buffer.toString();
  95. }
  96. }
  97. /**
  98. * The default <code>TypeBindingStrategy</code> used by Betwixt.
  99. * This implementation recognizes all the usual Java primitive wrappers
  100. * (plus a few more that will in most typical use cases be regarded in the same way).
  101. * @author <a href='http://jakarta.apache.org/commons'>Jakarta Commons Team</a>, <a href='http://www.apache.org'>Apache Software Foundation</a>
  102. */
  103. public static final class Default extends TypeBindingStrategy {
  104. /**
  105. * Gets the binding type to be used for the given Java type.
  106. * This implementation recognizes all the usual Java primitive wrappers
  107. * (plus a few more that will in most typical use cases be regarded in the same way).
  108. * @param type <code>Class</code> for which the binding type is to be determined,
  109. * not null
  110. * @return <code>BindingType</code> enumeration indicating the type of binding,
  111. * not null
  112. */
  113. public BindingType bindingType(Class type) {
  114. BindingType result = BindingType.COMPLEX;
  115. if (isStandardPrimitive(type)) {
  116. result = BindingType.PRIMITIVE;
  117. }
  118. return result;
  119. }
  120. /**
  121. * is the given type one of the standard Betwixt primitives?
  122. * @param type <code>Class</code>, not null
  123. * @return true if the type is one of the standard Betwixt primitives
  124. */
  125. protected boolean isStandardPrimitive(Class type) {
  126. if ( type == null ) {
  127. return false;
  128. } else if ( type.isPrimitive() ) {
  129. return true;
  130. } else if ( type.equals( Object.class ) ) {
  131. return false;
  132. }
  133. return type.getName().startsWith( "java.lang." )
  134. || Number.class.isAssignableFrom( type )
  135. || String.class.isAssignableFrom( type )
  136. || Date.class.isAssignableFrom( type )
  137. || java.sql.Date.class.isAssignableFrom( type )
  138. || java.sql.Time.class.isAssignableFrom( type )
  139. || java.sql.Timestamp.class.isAssignableFrom( type )
  140. || java.math.BigDecimal.class.isAssignableFrom( type )
  141. || java.math.BigInteger.class.isAssignableFrom( type );
  142. }
  143. }
  144. }