View Javadoc

1   /*
2    * $Id: DefinitionTag.java 421151 2006-07-12 06:07:14Z wsmoak $
3    *
4    * Copyright 1999-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * 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, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.struts.tiles.taglib;
20  
21  import javax.servlet.jsp.JspException;
22  
23  import org.apache.struts.tiles.taglib.util.TagUtils;
24  import org.apache.struts.tiles.AttributeDefinition;
25  import org.apache.struts.tiles.ComponentDefinition;
26  import org.apache.struts.tiles.UntypedAttribute;
27  
28  /***
29   * This is the tag handler for <tiles:definition>, which defines
30   * a tiles (or template / component). Definition is put in requested context and can be
31   * used in <tiles:insert&gt.
32   *
33   * @version $Rev: 421151 $ $Date: 2006-07-11 23:07:14 -0700 (Tue, 11 Jul 2006) $
34   */
35  public class DefinitionTag
36      extends DefinitionTagSupport
37      implements PutTagParent, PutListTagParent {
38  
39      /* JSP Tag attributes */
40      /***
41       * Definition identifier.
42       */
43      private String id = null;
44  
45      /***
46       * Scope into which definition will be saved.
47       */
48      private String scope = null;
49  
50      /***
51       * Extends attribute value.
52       */
53      private String extendsDefinition = null;
54  
55      /* Internal properties */
56      /***
57       * Template definition
58       */
59      private ComponentDefinition definition = null;
60  
61      /***
62       * Reset member values for reuse. This method calls super.release(),
63       * which invokes TagSupport.release(), which typically does nothing.
64       */
65      public void release() {
66          super.release();
67          id = null;
68          page = null;
69          scope = null;
70          role = null;
71          extendsDefinition = null;
72      }
73  
74      /***
75       * Release internal references.
76       */
77      protected void releaseInternal() {
78          definition = null;
79      }
80  
81      /***
82       * This method is a convenience for other tags for
83       * putting content into the tile definition.
84       * Content is already typed by caller.
85       */
86      public void putAttribute(String name, Object content) {
87          definition.putAttribute(name, content);
88      }
89  
90      /***
91       * Process nested ≶put> tag.
92       * Method is called from nested ≶put> tags.
93       * Nested list is added to current list.
94       * If role is defined, nested attribute is wrapped into an untyped definition
95       * containing attribute value and role.
96       */
97      public void processNestedTag(PutTag nestedTag) throws JspException {
98          // Get real value and check role
99          // If role is set, add it in attribute definition if any.
100         // If no attribute definition, create untyped one and set role.
101         Object attributeValue = nestedTag.getRealValue();
102         AttributeDefinition def;
103 
104         if (nestedTag.getRole() != null) {
105             try {
106                 def = ((AttributeDefinition) attributeValue);
107             } catch (ClassCastException ex) {
108                 def = new UntypedAttribute(attributeValue);
109             }
110             def.setRole(nestedTag.getRole());
111             attributeValue = def;
112         }
113 
114         // now add attribute to enclosing parent (i.e. : this object)
115         putAttribute(nestedTag.getName(), attributeValue);
116     }
117 
118     /***
119      * Process nested ≶putList> tag.
120      * Method is called from nested ≶putList> tags.
121      * Nested list is added to current list.
122      * If role is defined, nested attribute is wrapped into an untyped definition
123      * containing attribute value and role.
124      */
125     public void processNestedTag(PutListTag nestedTag) throws JspException {
126         // Get real value and check role
127         // If role is set, add it in attribute definition if any.
128         // If no attribute definition, create untyped one and set role.
129         Object attributeValue = nestedTag.getList();
130 
131         if (nestedTag.getRole() != null) {
132             AttributeDefinition def = new UntypedAttribute(attributeValue);
133             def.setRole(nestedTag.getRole());
134             attributeValue = def;
135         }
136 
137         // Check if a name is defined
138         if (nestedTag.getName() == null) {
139             throw new JspException("Error - PutList : attribute name is not defined. It is mandatory as the list is added to a 'definition'.");
140         }
141 
142         // now add attribute to enclosing parent (i.e. : this object).
143         putAttribute(nestedTag.getName(), attributeValue);
144     }
145 
146     /***
147      * Get the ID.
148      * @return ID
149      */
150     public String getId() {
151         return id;
152     }
153 
154     /***
155      * Set the ID.
156      * @param id New ID.
157      */
158     public void setId(String id) {
159         this.id = id;
160     }
161 
162     /***
163      * Get the scope.
164      * @return Scope.
165      */
166     public String getScope() {
167         return scope;
168     }
169 
170     /***
171      * Set the scope.
172      * @param aScope Scope.
173      */
174     public void setScope(String aScope) {
175         scope = aScope;
176     }
177 
178     /***
179      * Set <code>extends</code> (parent) definition name.
180      * @param definitionName Name of parent definition.
181      */
182     public void setExtends(String definitionName) {
183         this.extendsDefinition = definitionName;
184     }
185 
186     /***
187      * Get <code>extends</code> (parent) definition name.
188      * @return Name of parent definition.
189      */
190     public String getExtends() {
191         return extendsDefinition;
192     }
193 
194     /***
195      * Process the start tag by creating a new definition.
196      * @throws JspException On errors processing tag.
197      */
198     public int doStartTag() throws JspException {
199         // Do we extend a definition ?
200         if (extendsDefinition != null && !extendsDefinition.equals("")) {
201             ComponentDefinition parentDef =
202                 TagUtils.getComponentDefinition(extendsDefinition, pageContext);
203 
204             definition = new ComponentDefinition(parentDef);
205 
206         } else {
207             definition = new ComponentDefinition();
208         }
209 
210         // Set definitions attributes
211         if (page != null) {
212             definition.setTemplate(page);
213         }
214 
215         if (role != null) {
216             definition.setRole(role);
217         }
218 
219         return EVAL_BODY_INCLUDE;
220     }
221 
222     /***
223      * Process the end tag by putting the definition in appropriate context.
224      * @throws JspException On errors processing tag.
225      */
226     public int doEndTag() throws JspException {
227         TagUtils.setAttribute(pageContext, id, definition, scope);
228 
229         releaseInternal();
230         return EVAL_PAGE;
231     }
232 
233 }