This project has retired. For details please refer to its Attic page.
RenderTag xref
View Javadoc

1   /*
2    * $Id: RenderTag.java 749983 2009-03-04 12:41:31Z apetrelli $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  package org.apache.tiles.jsp.taglib;
22  
23  import java.io.IOException;
24  
25  import javax.servlet.jsp.PageContext;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.tiles.Attribute;
30  import org.apache.tiles.AttributeContext;
31  import org.apache.tiles.ListAttribute;
32  import org.apache.tiles.TilesContainer;
33  import org.apache.tiles.jsp.context.JspUtil;
34  
35  /***
36   * <p>
37   * Abstracts class for all tags which render (an attribute, a template, or
38   * definition).
39   * </p>
40   * <p>
41   * Properly invokes the defined preparer and invokes the abstract render method
42   * upon completion.
43   * </p>
44   * This tag takes special care to ensure that the attribute context is reset to
45   * it's original state after the execution of the tag is complete. This ensures
46   * that all all included attributes in subsequent tiles are scoped properly and
47   * do not bleed outside their intended scope.
48   *
49   * @since 2.1.1
50   * @version $Rev: 749983 $ $Date: 2009-03-04 13:41:31 +0100 (mer, 04 mar 2009) $
51   */
52  public abstract class RenderTag extends TilesBodyTag implements
53          PutAttributeTagParent, PutListAttributeTagParent {
54  
55      /***
56       * The log instance for this tag.
57       */
58      private final Log log = LogFactory.getLog(RenderTag.class);
59  
60      /***
61       * The role to check. If the user is in the specified role, the tag is taken
62       * into account; otherwise, the tag is ignored (skipped).
63       *
64       * @since 2.1.1
65       */
66      protected String role;
67  
68      /***
69       * The view preparer to use before the rendering.
70       *
71       * @since 2.1.1
72       */
73      protected String preparer;
74  
75      /***
76       * This flag, if <code>true</code>, flushes the content before rendering.
77       *
78       * @since 2.1.1
79       */
80      protected boolean flush;
81  
82      /***
83       * This flag, if <code>true</code>, ignores exception thrown by preparers
84       * and those caused by problems with definitions.
85       *
86       * @since 2.1.1
87       */
88      protected boolean ignore;
89  
90      /***
91       * The Tiles container that can be used inside the tag.
92       *
93       * @since 2.1.1
94       */
95      protected TilesContainer container;
96  
97      /***
98       * The attribute context to use to store and read attribute values.
99       *
100      * @since 2.1.1
101      */
102     protected AttributeContext attributeContext;
103 
104     /***
105      * Returns the role to check. If the user is in the specified role, the tag is
106      * taken into account; otherwise, the tag is ignored (skipped).
107      *
108      * @return The role to check.
109      * @since 2.1.1
110      */
111     public String getRole() {
112         return role;
113     }
114 
115     /***
116      * Sets the role to check. If the user is in the specified role, the tag is
117      * taken into account; otherwise, the tag is ignored (skipped).
118      *
119      * @param role The role to check.
120      * @since 2.1.1
121      */
122     public void setRole(String role) {
123         this.role = role;
124     }
125 
126     /***
127      * Returns the preparer name.
128      *
129      * @return The preparer name.
130      * @since 2.1.1
131      */
132     public String getPreparer() {
133         return preparer;
134     }
135 
136     /***
137      * Sets the preparer name.
138      *
139      * @param preparer The preparer name.
140      * @since 2.1.1
141      */
142     public void setPreparer(String preparer) {
143         this.preparer = preparer;
144     }
145 
146     /***
147      * Returns the flush flag. If <code>true</code>, current page out stream
148      * is flushed before insertion.
149      *
150      * @return The flush flag.
151      * @since 2.1.1
152      */
153     public boolean isFlush() {
154         return flush;
155     }
156 
157     /***
158      * Sets the flush flag. If <code>true</code>, current page out stream
159      * is flushed before insertion.
160      *
161      * @param flush The flush flag.
162      * @since 2.1.1
163      */
164     public void setFlush(boolean flush) {
165         this.flush = flush;
166     }
167 
168     /***
169      * Returns the ignore flag. If it is set to true, and the attribute
170      * specified by the name does not exist, simply return without writing
171      * anything. The default value is false, which will cause a runtime
172      * exception to be thrown.
173      *
174      * @return The ignore flag.
175      * @since 2.1.1
176      */
177     public boolean isIgnore() {
178         return ignore;
179     }
180 
181     /***
182      * Sets the ignore flag. If this attribute is set to true, and the attribute
183      * specified by the name does not exist, simply return without writing
184      * anything. The default value is false, which will cause a runtime
185      * exception to be thrown.
186      *
187      * @param ignore The ignore flag.
188      * @since 2.1.1
189      */
190     public void setIgnore(boolean ignore) {
191         this.ignore = ignore;
192     }
193 
194     /*** {@inheritDoc} */
195     @Override
196     protected void reset() {
197         super.reset();
198         preparer = null;
199         flush = false;
200         ignore = false;
201         container = null;
202         attributeContext = null;
203         role = null;
204     }
205 
206     /*** {@inheritDoc} */
207     public int doStartTag() throws TilesJspException {
208         container = JspUtil.getCurrentContainer(pageContext);
209         if (container != null) {
210             startContext(pageContext);
211             return EVAL_BODY_BUFFERED;
212         } else {
213             throw new TilesJspException("TilesContainer not initialized");
214         }
215     }
216 
217     /*** {@inheritDoc} */
218     public int doEndTag() throws TilesJspException {
219         try {
220             render();
221             if (flush) {
222                 pageContext.getOut().flush();
223             }
224 
225             return EVAL_PAGE;
226         } catch (IOException io) {
227             String message = "IO Error executing tag: " + io.getMessage();
228             log.error(message, io);
229             throw new TilesJspException(message, io);
230         } finally {
231             endContext(pageContext);
232         }
233     }
234 
235     /***
236      * Render the specified content.
237      *
238      * @throws TilesJspException if a jsp exception occurs.
239      * @throws IOException if an io exception occurs.
240      */
241     protected abstract void render() throws TilesJspException, IOException;
242 
243     /***
244      * Starts the context when entering the tag.
245      *
246      * @param context The page context to use.
247      */
248     protected void startContext(PageContext context) {
249         if (container != null) {
250             attributeContext = container.startContext(pageContext);
251         }
252     }
253 
254     /***
255      * Ends the context when exiting the tag.
256      *
257      * @param context The page context to use.
258      */
259     protected void endContext(PageContext context) {
260         if (attributeContext != null && container != null) {
261             container.endContext(pageContext);
262         }
263     }
264 
265     /***
266      * <p>
267      * Process nested &lg;put&gt; tag.
268      * <p/>
269      * <p>
270      * Places the value of the nested tag within the
271      * {@link org.apache.tiles.AttributeContext}.It is the responsibility
272      * of the descendent to check security. Security will be managed by
273      * called tags.
274      * </p>
275      *
276      * @param nestedTag the put tag desciendent.
277      */
278     public void processNestedTag(PutAttributeTag nestedTag) {
279         Attribute attribute = new Attribute(
280             nestedTag.getValue(), null,
281             nestedTag.getRole(), nestedTag.getType());
282 
283         attributeContext.putAttribute(nestedTag.getName(), attribute, nestedTag
284                 .isCascade());
285     }
286 
287     /*** {@inheritDoc} */
288     public void processNestedTag(PutListAttributeTag nestedTag) {
289         ListAttribute attribute = new ListAttribute(nestedTag.getAttributes());
290         attribute.setRole(nestedTag.getRole());
291         attribute.setInherit(nestedTag.getInherit());
292 
293         attributeContext.putAttribute(nestedTag.getName(), attribute, nestedTag
294                 .isCascade());
295     }
296 }