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;
  17. /** <p><code>XMLBeanInfo</code> represents the XML metadata information
  18. * used to map a Java Bean cleanly to XML. This provides a default
  19. * introspection mechansim, rather like {@link java.beans.BeanInfo}
  20. * which can be customized through some mechansim, either via Java code
  21. * or XSLT for example.</p>
  22. *
  23. * <h4><code>ID</code> and <code>IDREF</code> Attribute Names</h4>
  24. * <p>These special attributes are defined in the xml specification.
  25. * They are used by Betwixt to write bean graphs with cyclic references.
  26. * In most cases, these will take the values 'id' and 'idref' respectively
  27. * but these names can be varied in the DTD.
  28. * Therefore, these names are specified by this class but default to the
  29. * usual values.</p>
  30. *
  31. * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
  32. * @version $Revision: 1.9 $
  33. */
  34. public class XMLBeanInfo {
  35. /** Descriptor for main element */
  36. private ElementDescriptor elementDescriptor;
  37. /** the beans class that this XML info refers to */
  38. private Class beanClass;
  39. /** <code>ID</code> attribute name */
  40. private String idAttributeName = "id";
  41. /** <code>IDREF</code> attribute name */
  42. private String idrefAttributeName = "idref";
  43. /** Have we already cached the <code>idAttributeDescriptor</code>? */
  44. private boolean cachedIDAttribute = false;
  45. /** Cached <code>ID</code> attribute descriptor */
  46. private AttributeDescriptor idAttributeDescriptor;
  47. /**
  48. * Base constructor
  49. * @param beanClass for this Class
  50. */
  51. public XMLBeanInfo( Class beanClass ) {
  52. this.beanClass = beanClass;
  53. }
  54. /**
  55. * Gets descriptor for bean represention
  56. *
  57. * @return ElementDescriptor describing root element
  58. */
  59. public ElementDescriptor getElementDescriptor() {
  60. return elementDescriptor;
  61. }
  62. /**
  63. * Sets descriptor for bean represention
  64. *
  65. * @param elementDescriptor descriptor for bean
  66. */
  67. public void setElementDescriptor(ElementDescriptor elementDescriptor) {
  68. this.elementDescriptor = elementDescriptor;
  69. }
  70. /**
  71. * Gets the beans class that this XML info refers to
  72. *
  73. * @return the beans class that this XML info refers to
  74. */
  75. public Class getBeanClass() {
  76. return beanClass;
  77. }
  78. /**
  79. * Sets the beans class that this XML info refers to
  80. *
  81. * @param beanClass the class that this refers to
  82. */
  83. public void setBeanClass(Class beanClass) {
  84. this.beanClass = beanClass;
  85. }
  86. /**
  87. * Search attributes for one matching <code>ID</code> attribute name
  88. *
  89. * @return the xml ID attribute
  90. */
  91. public AttributeDescriptor getIDAttribute() {
  92. //
  93. // XXX for some reason caching isn't working at the moment
  94. // it could be that this method is called too early
  95. // and not reset when attributes change
  96. // on the other hand, the speed gain is likely to be too
  97. // small to bother about
  98. //
  99. //if ( cachedIDAttribute = false ) {
  100. idAttributeDescriptor = findIDAttribute();
  101. // cachedIDAttribute = true;
  102. //}
  103. return idAttributeDescriptor;
  104. }
  105. /**
  106. * ID attribute search implementation
  107. * @return the AttributeDescriptor for the <code>ID</code> attribute
  108. */
  109. private AttributeDescriptor findIDAttribute() {
  110. // we'll check to see if the bean already has an id
  111. if ( getElementDescriptor().hasAttributes() ) {
  112. AttributeDescriptor[] attributes = getElementDescriptor().getAttributeDescriptors();
  113. if ( attributes != null ) {
  114. for ( int i = 0, size = attributes.length; i < size; i++ ) {
  115. // support a match either on local or qualified name
  116. if ( getIDAttributeName().equals( attributes[i].getQualifiedName() )
  117. || getIDAttributeName().equals( attributes[i].getLocalName() )) {
  118. // we've got a match so use this attribute
  119. return attributes[i];
  120. }
  121. }
  122. }
  123. }
  124. return null;
  125. }
  126. /**
  127. * <p>Get name of <code>ID</code> attribute.
  128. * This is used to write (for example) automatic <code>ID</code>
  129. * attribute values.</p>
  130. *
  131. * <p>The default name is 'id'.</p>
  132. *
  133. * @return name for the special <code>ID</code> attribute
  134. */
  135. public String getIDAttributeName() {
  136. return idAttributeName;
  137. }
  138. /**
  139. * Set name of <code>ID</code> attribute
  140. * This is used to write (for example) automatic <code>ID</code>
  141. * attribute values.</p>
  142. *
  143. * <p>The default name is 'id'.</p>
  144. *
  145. * @param idAttributeName the attribute name for the special <code>ID</code> attribute
  146. */
  147. public void setIDAttributeName(String idAttributeName) {
  148. this.idAttributeName = idAttributeName;
  149. }
  150. /**
  151. * <p>Get <code>IDREF</code> attribute name
  152. * This is used (for example) to deal with cyclic references.
  153. *
  154. * <p>The default name is 'idref'.</p>
  155. *
  156. * @return name for the special <code>IDREF</code> attribute
  157. */
  158. public String getIDREFAttributeName() {
  159. return idrefAttributeName;
  160. }
  161. /**
  162. * Set <code>IDREF</code> attribute name
  163. * This is used (for example) to deal with cyclic references.
  164. *
  165. * <p>The default name is 'idref'.</p>
  166. *
  167. * @param idrefAttributeName the attribute name for the special <code>IDREF</code> attribute
  168. */
  169. public void setIDREFAttributeName(String idrefAttributeName) {
  170. this.idrefAttributeName = idrefAttributeName;
  171. }
  172. /**
  173. * Gets log-friendly string representation.
  174. *
  175. * @return something useful for logging
  176. */
  177. public String toString() {
  178. return
  179. "XMLBeanInfo [class=" + getBeanClass()
  180. + ", descriptor=" + getElementDescriptor() + "]";
  181. }
  182. }