001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.betwixt;
018:
019: /** <p><code>XMLBeanInfo</code> represents the XML metadata information
020: * used to map a Java Bean cleanly to XML. This provides a default
021: * introspection mechansim, rather like {@link java.beans.BeanInfo}
022: * which can be customized through some mechansim, either via Java code
023: * or XSLT for example.</p>
024: *
025: * <h4><code>ID</code> and <code>IDREF</code> Attribute Names</h4>
026: * <p>These special attributes are defined in the xml specification.
027: * They are used by Betwixt to write bean graphs with cyclic references.
028: * In most cases, these will take the values 'id' and 'idref' respectively
029: * but these names can be varied in the DTD.
030: * Therefore, these names are specified by this class but default to the
031: * usual values.</p>
032: *
033: * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
034: * @version $Revision: 438373 $
035: */
036: public class XMLBeanInfo {
037: /** Descriptor for main element */
038: private ElementDescriptor elementDescriptor;
039:
040: /** the beans class that this XML info refers to */
041: private Class beanClass;
042: /** <code>ID</code> attribute name */
043: private String idAttributeName = "id";
044: /** <code>IDREF</code> attribute name */
045: private String idrefAttributeName = "idref";
046: /** Have we already cached the <code>idAttributeDescriptor</code>? */
047: private boolean cachedIDAttribute = false;
048: /** Cached <code>ID</code> attribute descriptor */
049: private AttributeDescriptor idAttributeDescriptor;
050:
051: /**
052: * Base constructor
053: * @param beanClass for this Class
054: */
055: public XMLBeanInfo(Class beanClass) {
056: this .beanClass = beanClass;
057: }
058:
059: /**
060: * Gets descriptor for bean represention
061: *
062: * @return ElementDescriptor describing root element
063: */
064: public ElementDescriptor getElementDescriptor() {
065: return elementDescriptor;
066: }
067:
068: /**
069: * Sets descriptor for bean represention
070: *
071: * @param elementDescriptor descriptor for bean
072: */
073: public void setElementDescriptor(ElementDescriptor elementDescriptor) {
074: this .elementDescriptor = elementDescriptor;
075: }
076:
077: /**
078: * Gets the beans class that this XML info refers to
079: *
080: * @return the beans class that this XML info refers to
081: */
082: public Class getBeanClass() {
083: return beanClass;
084: }
085:
086: /**
087: * Sets the beans class that this XML info refers to
088: *
089: * @param beanClass the class that this refers to
090: */
091: public void setBeanClass(Class beanClass) {
092: this .beanClass = beanClass;
093: }
094:
095: /**
096: * Search attributes for one matching <code>ID</code> attribute name
097: *
098: * @return the xml ID attribute
099: */
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()
123: .getAttributeDescriptors();
124: if (attributes != null) {
125: for (int i = 0, size = attributes.length; i < size; i++) {
126: // support a match either on local or qualified name
127: if (getIDAttributeName().equals(
128: attributes[i].getQualifiedName())
129: || getIDAttributeName().equals(
130: attributes[i].getLocalName())) {
131: // we've got a match so use this attribute
132: return attributes[i];
133:
134: }
135: }
136: }
137: }
138: return null;
139: }
140:
141: /**
142: * <p>Get name of <code>ID</code> attribute.
143: * This is used to write (for example) automatic <code>ID</code>
144: * attribute values.</p>
145: *
146: * <p>The default name is 'id'.</p>
147: *
148: * @return name for the special <code>ID</code> attribute
149: */
150: public String getIDAttributeName() {
151: return idAttributeName;
152: }
153:
154: /**
155: * Set name of <code>ID</code> attribute
156: * This is used to write (for example) automatic <code>ID</code>
157: * attribute values.</p>
158: *
159: * <p>The default name is 'id'.</p>
160: *
161: * @param idAttributeName the attribute name for the special <code>ID</code> attribute
162: */
163: public void setIDAttributeName(String idAttributeName) {
164: this .idAttributeName = idAttributeName;
165: }
166:
167: /**
168: * <p>Get <code>IDREF</code> attribute name
169: * This is used (for example) to deal with cyclic references.
170: *
171: * <p>The default name is 'idref'.</p>
172: *
173: * @return name for the special <code>IDREF</code> attribute
174: */
175: public String getIDREFAttributeName() {
176: return idrefAttributeName;
177: }
178:
179: /**
180: * Set <code>IDREF</code> attribute name
181: * This is used (for example) to deal with cyclic references.
182: *
183: * <p>The default name is 'idref'.</p>
184: *
185: * @param idrefAttributeName the attribute name for the special <code>IDREF</code> attribute
186: */
187: public void setIDREFAttributeName(String idrefAttributeName) {
188: this .idrefAttributeName = idrefAttributeName;
189: }
190:
191: /**
192: * Gets log-friendly string representation.
193: *
194: * @return something useful for logging
195: */
196: public String toString() {
197: return "XMLBeanInfo [class=" + getBeanClass() + ", descriptor="
198: + getElementDescriptor() + "]";
199: }
200: }
|