1 package org.apache.commons.betwixt.digester;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import java.beans.BeanInfo;
19 import java.beans.Introspector;
20 import java.beans.PropertyDescriptor;
21
22 import org.apache.commons.betwixt.AttributeDescriptor;
23 import org.apache.commons.betwixt.ElementDescriptor;
24 import org.apache.commons.betwixt.XMLUtils;
25 import org.apache.commons.betwixt.expression.ConstantExpression;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.xml.sax.Attributes;
29 import org.xml.sax.SAXException;
30
31 /***
32 * <p><code>AttributeRule</code> the digester Rule for parsing the
33 * <attribute> elements.</p>
34 *
35 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
36 * @version $Id: AttributeRule.java,v 1.9 2004/02/28 13:38:32 yoavs Exp $
37 */
38 public class AttributeRule extends RuleSupport {
39
40 /*** Logger */
41 private static final Log log = LogFactory.getLog( AttributeRule.class );
42 /*** This loads all classes created by name. Defaults to this class's classloader */
43 private ClassLoader classLoader;
44 /*** The <code>Class</code> whose .betwixt file is being digested */
45 private Class beanClass;
46
47 /*** Base constructor */
48 public AttributeRule() {
49 this.classLoader = getClass().getClassLoader();
50 }
51
52
53
54
55 /***
56 * Process the beginning of this element.
57 *
58 * @param attributes The attribute list of this element
59 * @throws SAXException 1. If the attribute tag is not inside an element tag.
60 * 2. If the name attribute is not valid XML attribute name.
61 */
62 public void begin(Attributes attributes) throws SAXException {
63
64 AttributeDescriptor descriptor = new AttributeDescriptor();
65 String name = attributes.getValue( "name" );
66
67
68 if ( !XMLUtils.isWellFormedXMLName( name ) ) {
69 throw new SAXException("'" + name + "' would not be a well formed xml attribute name.");
70 }
71
72 descriptor.setQualifiedName( name );
73 descriptor.setLocalName( name );
74 String uri = attributes.getValue( "uri" );
75 if ( uri != null ) {
76 descriptor.setURI( uri );
77 }
78 String propertyName = attributes.getValue( "property" );
79 descriptor.setPropertyName( propertyName );
80 descriptor.setPropertyType( loadClass( attributes.getValue( "type" ) ) );
81
82 if ( propertyName != null && propertyName.length() > 0 ) {
83 configureDescriptor(descriptor);
84 } else {
85 String value = attributes.getValue( "value" );
86 if ( value != null ) {
87 descriptor.setTextExpression( new ConstantExpression( value ) );
88 }
89 }
90
91 Object top = digester.peek();
92 if ( top instanceof ElementDescriptor ) {
93 ElementDescriptor parent = (ElementDescriptor) top;
94 parent.addAttributeDescriptor( descriptor );
95 } else {
96 throw new SAXException( "Invalid use of <attribute>. It should "
97 + "be nested inside an <element> element" );
98 }
99
100 digester.push(descriptor);
101 }
102
103
104 /***
105 * Process the end of this element.
106 */
107 public void end() {
108 Object top = digester.pop();
109 }
110
111
112
113
114 /***
115 * Loads a class (using the appropriate classloader)
116 *
117 * @param name the name of the class to load
118 * @return the class instance loaded by the appropriate classloader
119 */
120 protected Class loadClass( String name ) {
121
122 if ( name != null ) {
123 try {
124 return classLoader.loadClass(name);
125 } catch (Exception e) {
126 }
127 }
128 return null;
129 }
130
131 /***
132 * Set the Expression and Updater from a bean property name
133 * @param attributeDescriptor configure this <code>AttributeDescriptor</code>
134 * from the property with a matching name in the bean class
135 */
136 protected void configureDescriptor(AttributeDescriptor attributeDescriptor) {
137 Class beanClass = getBeanClass();
138 if ( beanClass != null ) {
139 String name = attributeDescriptor.getPropertyName();
140 try {
141 BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );
142 PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
143 if ( descriptors != null ) {
144 for ( int i = 0, size = descriptors.length; i < size; i++ ) {
145 PropertyDescriptor descriptor = descriptors[i];
146 if ( name.equals( descriptor.getName() ) ) {
147 XMLIntrospectorHelper
148 .configureProperty( attributeDescriptor, descriptor );
149 getProcessedPropertyNameSet().add( name );
150 break;
151 }
152 }
153 }
154 } catch (Exception e) {
155 log.warn( "Caught introspection exception", e );
156 }
157 }
158 }
159 }