1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.betwixt.digester;
17
18 import java.beans.BeanInfo;
19 import java.beans.Introspector;
20 import java.beans.PropertyDescriptor;
21 import java.util.Set;
22
23 import org.apache.commons.betwixt.AttributeDescriptor;
24 import org.apache.commons.betwixt.Descriptor;
25 import org.apache.commons.betwixt.ElementDescriptor;
26 import org.apache.commons.betwixt.NodeDescriptor;
27 import org.apache.commons.betwixt.XMLBeanInfo;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.xml.sax.Attributes;
31 import org.xml.sax.SAXException;
32
33 /*** <p><code>AddDefaultsRule</code> appends all the default properties
34 * to the current element.</p>
35 *
36 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
37 * @version $Revision: 1.11.2.1 $
38 */
39 public class AddDefaultsRule extends RuleSupport {
40
41 /*** Logger */
42 private static final Log log = LogFactory.getLog( AddDefaultsRule.class );
43
44 /*** Base constructor */
45 public AddDefaultsRule() {
46 }
47
48
49
50
51 /***
52 * Process the beginning of this element.
53 *
54 * @param attributes The attribute list of this element
55 * @throws Exception generally this will indicate an unrecoverable error
56 */
57 public void begin(Attributes attributes) throws Exception {
58 Class beanClass = getBeanClass();
59 Set procesedProperties = getProcessedPropertyNameSet();
60 if ( beanClass != null ) {
61 try {
62 boolean attributesForPrimitives = getXMLInfoDigester().isAttributesForPrimitives();
63 BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );
64 PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
65 if ( descriptors != null ) {
66 for ( int i = 0, size = descriptors.length; i < size; i++ ) {
67 PropertyDescriptor descriptor = descriptors[i];
68
69 String name = descriptor.getName();
70 if ( procesedProperties.contains( name ) ) {
71 continue;
72 }
73 Descriptor nodeDescriptor = getXMLIntrospector().createDescriptor(
74 descriptor, attributesForPrimitives);
75 if ( nodeDescriptor != null ) {
76 addDescriptor( nodeDescriptor );
77 }
78 }
79 }
80 } catch (Exception e) {
81 log.info( "Caught introspection exception", e );
82 }
83 }
84
85
86 XMLIntrospectorHelper.defaultAddMethods(
87 getXMLIntrospector(),
88 getRootElementDescriptor(),
89 beanClass );
90 }
91
92
93
94
95
96 /***
97 * Add a desciptor to the top object on the Digester stack.
98 *
99 * @param nodeDescriptor add this <code>NodeDescriptor</code>. Must not be null.
100 * @throws SAXException if the parent for the addDefaults element is not a <element>
101 * or if the top object on the stack is not a <code>XMLBeanInfo</code> or a
102 * <code>ElementDescriptor</code>
103 * @deprecated 0.5 replaced by {@link #addDescriptor( Descriptor )}
104 */
105 protected void addDescriptor( NodeDescriptor nodeDescriptor ) throws SAXException {
106 addDescriptor( (Descriptor) nodeDescriptor );
107 }
108
109 /***
110 * Add a desciptor to the top object on the Digester stack.
111 *
112 * @param nodeDescriptor add this <code>NodeDescriptor</code>. Must not be null.
113 * @throws SAXException if the parent for the addDefaults element is not a <element>
114 * or if the top object on the stack is not a <code>XMLBeanInfo</code> or a
115 * <code>ElementDescriptor</code>
116 * @since 0.5
117 */
118 protected void addDescriptor( Descriptor nodeDescriptor ) throws SAXException {
119 Object top = digester.peek();
120 if ( top instanceof XMLBeanInfo ) {
121 log.warn( "It is advisable to put an <addDefaults/> element inside an <element> tag" );
122
123 XMLBeanInfo beanInfo = (XMLBeanInfo) top;
124
125
126 if ( nodeDescriptor instanceof ElementDescriptor ) {
127 ElementDescriptor elementDescriptor = (ElementDescriptor) nodeDescriptor;
128 ElementDescriptor root = beanInfo.getElementDescriptor() ;
129 if ( root == null ) {
130 beanInfo.setElementDescriptor( elementDescriptor );
131 } else {
132 root.addElementDescriptor( elementDescriptor );
133 }
134 } else {
135 throw new SAXException(
136 "the <addDefaults> element should be within an <element> tag" );
137 }
138 } else if ( top instanceof ElementDescriptor ) {
139 ElementDescriptor parent = (ElementDescriptor) top;
140 if ( nodeDescriptor instanceof ElementDescriptor ) {
141 parent.addElementDescriptor( (ElementDescriptor) nodeDescriptor );
142 } else {
143 parent.addAttributeDescriptor( (AttributeDescriptor) nodeDescriptor );
144 }
145 } else {
146 throw new SAXException(
147 "Invalid use of <addDefaults>. It should be nested inside <element> element" );
148 }
149 }
150
151 /***
152 * Gets an <code>ElementDescriptor</code> for the top on digester's stack.
153 *
154 * @return the top object or the element description if the top object
155 * is an <code>ElementDescriptor</code> or a <code>XMLBeanInfo</code> class (respectively)
156 * Otherwise null.
157 */
158 protected ElementDescriptor getRootElementDescriptor() {
159 Object top = digester.peek();
160 if ( top instanceof XMLBeanInfo ) {
161 XMLBeanInfo beanInfo = (XMLBeanInfo) top;
162 return beanInfo.getElementDescriptor();
163
164 } else if ( top instanceof ElementDescriptor ) {
165 ElementDescriptor parent = (ElementDescriptor) top;
166
167 return parent;
168 }
169 return null;
170 }
171 }