View Javadoc

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