View Javadoc

1   package org.apache.commons.betwixt.digester;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */ 
19  
20  import java.beans.PropertyDescriptor;
21  import java.lang.reflect.Method;
22  
23  import org.apache.commons.betwixt.ElementDescriptor;
24  import org.apache.commons.betwixt.TextDescriptor;
25  import org.apache.commons.betwixt.XMLBeanInfo;
26  import org.apache.commons.betwixt.expression.ConstantExpression;
27  import org.apache.commons.betwixt.expression.MethodExpression;
28  import org.apache.commons.betwixt.expression.MethodUpdater;
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  import org.xml.sax.Attributes;
32  import org.xml.sax.SAXException;
33  
34  /** 
35    * <p>Rule for parsing &lt;text&gt; elements.
36    * These allow mixed content text to be specified.
37    * A mixed content element example:
38    * <pre>
39    *     &lt;foo&gt;text&lt;bar/&gt;&lt;/foo&gt;
40    * </pre>
41    * </p>
42    *
43    * @author Robert Burrell Donkin
44    * @version $Id: TextRule.java 438373 2006-08-30 05:17:21Z bayard $
45    */
46  public class TextRule extends MappedPropertyRule {
47  
48      /** Logger */
49      private static final Log log = LogFactory.getLog( TextRule.class );
50      /** Base constructor */
51      public TextRule() {}
52      
53      // Rule interface
54      //-------------------------------------------------------------------------    
55      
56      /**
57       * Process the beginning of this element.
58       *
59       * @param attributes The attribute list of this element
60       * @throws SAXException 1. If this tag's parent is not an element tag.
61       * 2. If this tag has a value attribute together with either a property
62       * or type attribute.
63       */
64      public void begin(String name, String namespace, Attributes attributes) throws SAXException {
65          
66          TextDescriptor descriptor = new TextDescriptor();
67          
68          String value = attributes.getValue( "value" );
69          String propertyName = attributes.getValue( "property" );
70          String propertyType = attributes.getValue( "type" );
71          
72          if ( value != null) {
73              if ( propertyName != null || propertyType != null ) {
74                  // not allowed
75                  throw new SAXException(
76                      "You cannot specify attribute 'value' together with either " 
77                      + " the 'property' or 'type' attributes");                
78              }
79              // fixed value text
80              descriptor.setTextExpression( new ConstantExpression( value ) );
81              
82          } else {
83              // property based text
84              descriptor.setPropertyName( propertyName );
85              
86              Class beanClass = getBeanClass();
87              
88              // set the property type using reflection
89              descriptor.setPropertyType( 
90                  getPropertyType( propertyType, beanClass, propertyName ) 
91              );
92              
93              if ( beanClass != null ) {
94                  String descriptorPropertyName = descriptor.getPropertyName();
95                  PropertyDescriptor propertyDescriptor = 
96                      getPropertyDescriptor( beanClass, descriptorPropertyName );
97                  if ( propertyDescriptor != null ) { 
98                          Method readMethod = propertyDescriptor.getReadMethod();
99                          descriptor.setTextExpression( new MethodExpression( readMethod ) );
100                         Method writeMethod = propertyDescriptor.getWriteMethod();
101                         if (writeMethod != null) {
102                             descriptor.setUpdater( new MethodUpdater(writeMethod));
103                         }
104                         getProcessedPropertyNameSet().add( descriptorPropertyName );
105                 }
106             }
107         }
108         
109         Object top = digester.peek();
110         if ( top instanceof XMLBeanInfo ) {
111             XMLBeanInfo beanInfo = (XMLBeanInfo) top;
112             ElementDescriptor elementDescriptor = beanInfo.getElementDescriptor();
113             if (elementDescriptor != null) {
114                 elementDescriptor.addContentDescriptor( descriptor );
115             }
116             
117         } else if ( top instanceof ElementDescriptor ) {
118             ElementDescriptor parent = (ElementDescriptor) top;
119             parent.addContentDescriptor( descriptor );
120             
121         } else {
122             throw new SAXException( "Invalid use of <text>. It should " 
123                 + "be nested <text> nodes" );
124         }
125     }
126 }