Project Tiles has retired. For details please refer to its Attic page.
GetAsStringModel xref
View Javadoc

1   /*
2    * $Id: GetAsStringModel.java 1625204 2014-09-16 02:21:04Z nlebas $
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  
22  package org.apache.tiles.template;
23  
24  import java.io.IOException;
25  import java.io.Writer;
26  import java.util.Deque;
27  
28  import org.apache.tiles.Attribute;
29  import org.apache.tiles.TilesContainer;
30  import org.apache.tiles.access.TilesAccess;
31  import org.apache.tiles.autotag.core.runtime.ModelBody;
32  import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
33  import org.apache.tiles.request.Request;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  /**
38   * <p>
39   * <strong> Render the value of the specified template attribute to the current
40   * Writer</strong>
41   * </p>
42   *
43   * <p>
44   * Retrieve the value of the specified template attribute property, and render
45   * it to the current Writer as a String. The usual toString() conversions is
46   * applied on found value.
47   * </p>
48   *
49   * @version $Rev: 1625204 $ $Date: 2014-09-16 12:21:04 +1000 (Tue, 16 Sep 2014) $
50   * @since 2.2.0
51   */
52  public class GetAsStringModel {
53  
54      /**
55       * The logging object.
56       */
57      private Logger log = LoggerFactory.getLogger(getClass());
58  
59      /**
60       * The attribute resolver to use.
61       */
62      private AttributeResolver attributeResolver;
63  
64      /**
65       * Constructor that uses the defaut attribute resolver.
66       *
67       * @since 3.0.0
68       */
69      public GetAsStringModel() {
70          this(new DefaultAttributeResolver());
71      }
72  
73      /**
74       * Constructor.
75       *
76       * @param attributeResolver The attribute resolver to use.
77       * @since 2.2.0
78       */
79      public GetAsStringModel(AttributeResolver attributeResolver) {
80          this.attributeResolver = attributeResolver;
81      }
82  
83      /**
84       * Executes the operation.
85       * @param ignore If <code>true</code>, if an exception happens during
86       * rendering, of if the attribute is null, the problem will be ignored.
87       * @param preparer The preparer to invoke before rendering the attribute.
88       * @param role A comma-separated list of roles. If present, the attribute
89       * will be rendered only if the current user belongs to one of the roles.
90       * @param defaultValue The default value of the attribute. To use only if
91       * the attribute was not computed.
92       * @param defaultValueRole The default comma-separated list of roles. To use
93       * only if the attribute was not computed.
94       * @param defaultValueType The default type of the attribute. To use only if
95       * the attribute was not computed.
96       * @param name The name of the attribute.
97       * @param value The attribute to use immediately, if not null.
98       * @param request The request.
99       * @param modelBody The body.
100      * @throws IOException If an I/O error happens during rendering.
101      * @since 2.2.0
102      */
103     public void execute(boolean ignore, String preparer, String role,
104             Object defaultValue, String defaultValueRole,
105             String defaultValueType, @Parameter(required = true) String name,
106             Attribute value, Request request, ModelBody modelBody)
107             throws IOException {
108         TilesContainer container = TilesAccess.getCurrentContainer(request);
109         Deque<Object> composeStack = ComposeStackUtil.getComposeStack(request);
110         Attribute attribute = resolveAttribute(container, ignore, preparer,
111                 role, defaultValue, defaultValueRole, defaultValueType, name,
112                 value, request);
113         if (attribute != null) {
114             composeStack.push(attribute);
115         }
116         modelBody.evaluateWithoutWriting();
117         container = TilesAccess.getCurrentContainer(request);
118         Writer writer = request.getWriter();
119         if (attribute != null) {
120             attribute = (Attribute) composeStack.pop();
121         }
122         renderAttribute(attribute, container, writer, ignore, request);
123     }
124 
125     /**
126      * Resolves the attribute. and starts the context.
127      *
128      * @param container The Tiles container to use.
129      * @param ignore If <code>true</code>, if an exception happens during
130      * rendering, of if the attribute is null, the problem will be ignored.
131      * @param preparer The preparer to invoke before rendering the attribute.
132      * @param role A comma-separated list of roles. If present, the attribute
133      * will be rendered only if the current user belongs to one of the roles.
134      * @param defaultValue The default value of the attribute. To use only if
135      * the attribute was not computed.
136      * @param defaultValueRole The default comma-separated list of roles. To use
137      * only if the attribute was not computed.
138      * @param defaultValueType The default type of the attribute. To use only if
139      * the attribute was not computed.
140      * @param name The name of the attribute.
141      * @param value The attribute to use immediately, if not null.
142      * @param request The request.
143      * @return The resolved attribute.
144      */
145     private Attribute resolveAttribute(TilesContainer container,
146             boolean ignore, String preparer, String role, Object defaultValue,
147             String defaultValueRole, String defaultValueType, String name,
148             Attribute value, Request request) {
149         if (preparer != null) {
150             container.prepare(preparer, request);
151         }
152         Attribute attribute = attributeResolver.computeAttribute(container,
153                 value, name, role, ignore, defaultValue, defaultValueRole,
154                 defaultValueType, request);
155         container.startContext(request);
156         return attribute;
157     }
158 
159     /**
160      * Renders the attribute as a string.
161      *
162      * @param attribute The attribute to use, previously resolved.
163      * @param container The Tiles container to use.
164      * @param writer The writer into which the attribute will be written.
165      * @param ignore If <code>true</code>, if an exception happens during
166      * rendering, of if the attribute is null, the problem will be ignored.
167      * @param request The request.
168      * @throws IOException If an I/O error happens during rendering.
169      */
170     private void renderAttribute(Attribute attribute, TilesContainer container,
171             Writer writer, boolean ignore, Request request)
172             throws IOException {
173         try {
174             if (attribute == null && ignore) {
175                 return;
176             }
177             Object value = container.evaluate(attribute, request);
178             if(value != null) {
179             	writer.write(value.toString());
180             }
181         } catch (IOException e) {
182             if (!ignore) {
183                 throw e;
184             } else if (log.isDebugEnabled()) {
185                 log.debug("Ignoring exception", e);
186             }
187         } catch (RuntimeException e) {
188             if (!ignore) {
189                 throw e;
190             } else if (log.isDebugEnabled()) {
191                 log.debug("Ignoring exception", e);
192             }
193         } finally {
194             container.endContext(request);
195         }
196     }
197 }