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 }