View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jelly.tags.bean;
17  
18  import java.lang.reflect.Method;
19  import java.util.Hashtable;
20  import java.util.Map;
21  
22  import org.apache.commons.beanutils.MethodUtils;
23  import org.apache.commons.jelly.JellyException;
24  import org.apache.commons.jelly.Tag;
25  import org.apache.commons.jelly.TagLibrary;
26  import org.apache.commons.jelly.impl.TagFactory;
27  import org.apache.commons.jelly.impl.TagScript;
28  
29  import org.xml.sax.Attributes;
30  
31  /*** Describes the Taglib. This class could be generated by XDoclet
32    *
33    * @author Theo Niemeijer
34    * @version $Revision: 155420 $
35    */
36  public class BeanTagLibrary extends TagLibrary {
37  
38      /*** Synchronized map of tag names to bean classes */
39      private Map beanTypes = new Hashtable();
40  
41      /*** Synchronized map of tag names to invoke methods */
42      private Map invokeMethods = new Hashtable();
43  
44      public BeanTagLibrary() {
45          registerTagFactory(
46              "beandef",
47              new TagFactory() {
48                  public Tag createTag(String name, Attributes attributes) throws JellyException {
49                      return new BeandefTag(BeanTagLibrary.this);
50                  }
51              }
52          );
53      }
54  
55      /***
56       * Allows tags to register new bean types
57       */
58      public void registerBean(String name, Class type) {
59          beanTypes.put(name, type);
60      }
61  
62      /***
63       * Allows tags to register new bean types with an associated method
64       */
65      public void registerBean(String name, Class type, Method method) {
66          registerBean(name, type);
67          if (method != null) {
68              invokeMethods.put(name, method);
69          }
70          else {
71              invokeMethods.remove(name);
72          }
73      }
74  
75      /***
76       * Allows tags to register new bean types with an associated method
77       */
78      public void registerBean(String name, Class type, String methodName) {
79          Method method = MethodUtils.getAccessibleMethod(
80              type, methodName, BeandefTag.EMPTY_ARGUMENT_TYPES
81          );
82          registerBean(name, type, method);
83      }
84  
85      // TagLibrary interface
86      //-------------------------------------------------------------------------
87      public TagScript createTagScript(
88          final String name, final Attributes attributes
89      ) throws JellyException {
90  
91          // check for standard tags first
92          TagScript answer = super.createTagScript(name, attributes);
93          if (answer != null) {
94              return answer;
95          }
96  
97          // lets try a dynamic tag
98          return new TagScript( createTagFactory(name, attributes) );
99      }
100 
101     // Implementation methods
102     //-------------------------------------------------------------------------
103 
104     /***
105      * Factory method to create a TagFactory for a given tag attribute and attributes
106      */
107     protected TagFactory createTagFactory(String name, Attributes attributes) throws JellyException {
108 
109         return new TagFactory() {
110             public Tag createTag(String name, Attributes attributes) throws JellyException {
111                 return createBeanTag(name, attributes);
112             }
113         };
114     }
115 
116     protected Tag createBeanTag(String name, Attributes attributes) throws JellyException {
117         // is the name bound to a specific class
118         Class beanType = getBeanType(name, attributes);
119         if (beanType != null) {
120             Method invokeMethod = (Method) invokeMethods.get(name);
121             return new BeanTag(beanType, name, invokeMethod);
122         }
123 
124         // its a property tag
125         return new BeanPropertyTag(name);
126     }
127 
128     protected Class getBeanType(String name, Attributes attributes) {
129         return (Class) beanTypes.get(name);
130     }
131 }