View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.view.facelets.tag;
20  
21  import java.lang.reflect.Constructor;
22  import java.lang.reflect.InvocationTargetException;
23  import java.lang.reflect.Method;
24  import java.util.HashMap;
25  import java.util.Map;
26  import javax.el.ELException;
27  import javax.faces.FacesException;
28  import javax.faces.view.facelets.ComponentConfig;
29  import javax.faces.view.facelets.FaceletException;
30  import javax.faces.view.facelets.FaceletHandler;
31  import javax.faces.view.facelets.Tag;
32  import javax.faces.view.facelets.TagConfig;
33  import javax.faces.view.facelets.TagHandler;
34  
35  /**
36   *
37   * @author lu4242
38   */
39  public class ComponentTagDeclarationLibrary implements TagLibrary
40  {
41      private final Map<String, Map<String, TagHandlerFactory>> _factories;
42  
43      public ComponentTagDeclarationLibrary()
44      {
45          _factories = new HashMap<String, Map<String, TagHandlerFactory>>();
46      }
47  
48      /*
49       * (non-Javadoc)
50       * 
51       * See org.apache.myfaces.view.facelets.tag.TagLibrary#containsNamespace(java.lang.String)
52       */
53      public boolean containsNamespace(String ns)
54      {
55          return _factories.containsKey(ns);
56      }
57  
58      /*
59       * (non-Javadoc)
60       * 
61       * See org.apache.myfaces.view.facelets.tag.TagLibrary#containsTagHandler(java.lang.String, java.lang.String)
62       */
63      public boolean containsTagHandler(String ns, String localName)
64      {
65          if (containsNamespace(ns))
66          {
67              Map<String, TagHandlerFactory> map = _factories.get(ns);
68              if (map == null)
69              {
70                  return false;
71              }
72              return map.containsKey(localName);
73          }
74          else
75          {
76              return false;
77          }
78      }
79  
80      /*
81       * (non-Javadoc)
82       * 
83       * See org.apache.myfaces.view.facelets.tag.TagLibrary#createTagHandler(java.lang.String, java.lang.String,
84       * org.apache.myfaces.view.facelets.tag.TagConfig)
85       */
86      public TagHandler createTagHandler(String ns, String localName, TagConfig tag) throws FacesException
87      {
88          if (containsNamespace(ns))
89          {
90              Map<String, TagHandlerFactory> map = _factories.get(ns);
91              if (map == null)
92              {
93                  map = new HashMap<String, TagHandlerFactory>();
94                  _factories.put(ns, map);
95              }
96              TagHandlerFactory f = map.get(localName);
97              if (f != null)
98              {
99                  return f.createHandler(tag);
100             }
101         }
102         
103         return null;
104     }
105 
106     /*
107      * (non-Javadoc)
108      * 
109      * See org.apache.myfaces.view.facelets.tag.TagLibrary#containsFunction(java.lang.String, java.lang.String)
110      */
111     public boolean containsFunction(String ns, String name)
112     {
113         return false;
114     }
115 
116     /*
117      * (non-Javadoc)
118      * 
119      * See org.apache.myfaces.view.facelets.tag.TagLibrary#createFunction(java.lang.String, java.lang.String)
120      */
121     public Method createFunction(String ns, String name)
122     {
123         return null;
124     }
125 
126     /*
127     public String getNamespace()
128     {
129         return _namespace;
130     }*/
131 
132     /**
133      * Add a ComponentHandler with the specified componentType and rendererType, aliased by the tag name.
134      * 
135      * See ComponentHandler
136      * See javax.faces.application.Application#createComponent(java.lang.String)
137      * @param name
138      *            name to use, "foo" would be &lt;my:foo /&gt;
139      * @param componentType
140      *            componentType to use
141      * @param rendererType
142      *            rendererType to use
143      */
144     public final void addComponent(String namespace, String name, String componentType, String rendererType)
145     {
146         Map<String, TagHandlerFactory> map = _factories.get(namespace);
147         if (map == null)
148         {
149             map = new HashMap<String, TagHandlerFactory>();
150             _factories.put(namespace, map);
151         }
152         map.put(name, new ComponentHandlerFactory(componentType, rendererType));
153     }
154 
155     /**
156      * Add a ComponentHandler with the specified componentType and rendererType, aliased by the tag name. The Facelet
157      * will be compiled with the specified HandlerType (which must extend AbstractComponentHandler).
158      * 
159      * See AbstractComponentHandler
160      * @param name
161      *            name to use, "foo" would be &lt;my:foo /&gt;
162      * @param componentType
163      *            componentType to use
164      * @param rendererType
165      *            rendererType to use
166      * @param handlerType
167      *            a Class that extends AbstractComponentHandler
168      */
169     public final void addComponent(String namespace, String name, String componentType, String rendererType, 
170                                       Class<? extends TagHandler> handlerType)
171     {
172         Map<String, TagHandlerFactory> map = _factories.get(namespace);
173         if (map == null)
174         {
175             map = new HashMap<String, TagHandlerFactory>();
176             _factories.put(namespace, map);
177         }
178         map.put(name, new UserComponentHandlerFactory(componentType, rendererType, handlerType));
179     }
180 
181     private static class ComponentConfigWrapper implements ComponentConfig
182     {
183 
184         protected final TagConfig parent;
185 
186         protected final String componentType;
187 
188         protected final String rendererType;
189 
190         public ComponentConfigWrapper(TagConfig parent, String componentType, String rendererType)
191         {
192             this.parent = parent;
193             this.componentType = componentType;
194             this.rendererType = rendererType;
195         }
196 
197         public String getComponentType()
198         {
199             return this.componentType;
200         }
201 
202         public String getRendererType()
203         {
204             return this.rendererType;
205         }
206 
207         public FaceletHandler getNextHandler()
208         {
209             return this.parent.getNextHandler();
210         }
211 
212         public Tag getTag()
213         {
214             return this.parent.getTag();
215         }
216 
217         public String getTagId()
218         {
219             return this.parent.getTagId();
220         }
221     }
222 
223     private static class ComponentHandlerFactory implements TagHandlerFactory
224     {
225 
226         protected final String componentType;
227 
228         protected final String renderType;
229 
230         /**
231          * @param handlerType
232          */
233         public ComponentHandlerFactory(String componentType, String renderType)
234         {
235             this.componentType = componentType;
236             this.renderType = renderType;
237         }
238 
239         public TagHandler createHandler(TagConfig cfg) throws FacesException, ELException
240         {
241             ComponentConfig ccfg = new ComponentConfigWrapper(cfg, this.componentType, this.renderType);
242             return new javax.faces.view.facelets.ComponentHandler(ccfg);
243         }
244     }
245 
246     private static class UserComponentHandlerFactory implements TagHandlerFactory
247     {
248 
249         private final static Class<?>[] CONS_SIG = new Class[] { ComponentConfig.class };
250 
251         protected final String componentType;
252 
253         protected final String renderType;
254 
255         protected final Class<? extends TagHandler> type;
256 
257         protected final Constructor<? extends TagHandler> constructor;
258 
259         /**
260          * @param handlerType
261          */
262         public UserComponentHandlerFactory(String componentType, String renderType, Class<? extends TagHandler> type)
263         {
264             this.componentType = componentType;
265             this.renderType = renderType;
266             this.type = type;
267             try
268             {
269                 this.constructor = this.type.getConstructor(CONS_SIG);
270             }
271             catch (Exception e)
272             {
273                 throw new FaceletException("Must have a Constructor that takes in a ComponentConfig", e);
274             }
275         }
276 
277         public TagHandler createHandler(TagConfig cfg) throws FacesException, ELException
278         {
279             try
280             {
281                 ComponentConfig ccfg = new ComponentConfigWrapper(cfg, componentType, renderType);
282                 return constructor.newInstance(new Object[] { ccfg });
283             }
284             catch (InvocationTargetException e)
285             {
286                 throw new FaceletException(e.getCause().getMessage(), e.getCause().getCause());
287             }
288             catch (Exception e)
289             {
290                 throw new FaceletException("Error Instantiating ComponentHandler: " + this.type.getName(), e);
291             }
292         }
293     }
294 }