View Javadoc

1   /**
2    * This file Copyright (c) 2003-2010 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.taglibs;
35  
36  import info.magnolia.cms.core.AggregationState;
37  import info.magnolia.cms.core.Content;
38  import info.magnolia.context.MgnlContext;
39  import info.magnolia.context.WebContext;
40  import info.magnolia.module.templating.engine.RenderingEngine;
41  import info.magnolia.objectfactory.Components;
42  
43  import java.io.IOException;
44  import java.util.ArrayList;
45  import java.util.Iterator;
46  import java.util.List;
47  
48  import javax.servlet.http.HttpServletRequest;
49  import javax.servlet.jsp.tagext.BodyTagSupport;
50  
51  /**
52   * Delegates to an appropriate ParagraphRenderer, or include a JSP.
53   * This is typically used to render a paragraph. Within contentNodeIterator, parameters are provided
54   * automatically by the loop.
55   * @jsp.tag name="includeTemplate" body-content="JSP"
56   *
57   * @author marcel Salathe
58   * @author Sameer Charles
59   * @author Fabrizio Giustina
60   * @version $Revision: 34596 $ ($Author: pbaerfuss $)
61   */
62  public class Include extends BodyTagSupport {
63      private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Include.class);
64  
65      protected RenderingEngine renderingEngine = Components.getSingleton(RenderingEngine.class);
66  
67      /**
68       * File to be included (e.g. /templates/jsp/x.jsp).
69       * @deprecated
70       */
71      private String path;
72  
73      /**
74       * Attributes to be passed to the included template (set by nested Attribute tags).
75       */
76      private transient List attributes;
77  
78      /**
79       * The instance contentNode (i.e. paragraph) you wish to show.
80       */
81      private transient Content contentNode;
82  
83      /**
84       * The name of the contentNode (i.e. paragraph) you wish to show.
85       */
86      private String contentNodeName;
87  
88      /**
89       * Set to true if the content should not be rendered in edit mode (edit bars, ...)
90       */
91      private boolean noEditBars = false;
92  
93      /**
94       * @deprecated use the contentNode attribute instead
95       * @see #setContentNode(Content)
96       * @jsp.attribute required="false" rtexprvalue="true" type="info.magnolia.cms.core.Content"
97       */
98      public void setContainer(Content contentNode) {
99          this.setContentNode(contentNode);
100     }
101 
102     /**
103      * @param contentNode the instance contentNode (i.e. paragraph) you wish to show
104      * @jsp.attribute required="false" rtexprvalue="true" type="info.magnolia.cms.core.Content"
105      */
106     public void setContentNode(Content contentNode) {
107         this.contentNode = contentNode;
108     }
109 
110     /**
111      * @deprecated file to be included (e.g. "/templates/jsp/x.jsp").
112      * Just use basic jsp tags (i.e. <jsp:include/>) if you need to include a jsp in your templates.
113      * @jsp.attribute required="false" rtexprvalue="true"
114      */
115     public void setPath(String path) {
116         this.path = path;
117     }
118 
119     /**
120      * The name of the contentNode (i.e. paragraph) you wish to show.
121      * @jsp.attribute required="false" rtexprvalue="true"
122      */
123     public void setContentNodeName(String contentNodeName) {
124         this.contentNodeName = contentNodeName;
125     }
126 
127     /**
128      * @param name name of attribute to pass with the include
129      * @param value value of attribute to pass with the include
130      */
131     public void setAttribute(String name, Object value) {
132         if (attributes == null) {
133             attributes = new ArrayList();
134         }
135         Object[] attributesArray = new Object[]{name, value};
136         attributes.add(attributesArray);
137     }
138 
139     /**
140      * Set to true if the content should not be rendered in edit mode (edit bars, ...)
141      * @jsp.attribute required="false" rtexprvalue="true" type="boolean"
142      */
143     public void setNoEditBars(boolean noEditBars) {
144         this.noEditBars = noEditBars;
145     }
146 
147     public int doAfterBody() {
148         HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
149         if ((attributes != null) && (attributes.size() > 0)) {
150             Iterator i = attributes.iterator();
151             while (i.hasNext()) {
152                 Object[] s = (Object[]) i.next();
153                 req.setAttribute((String) s[0], s[1]);
154             }
155         }
156         return SKIP_BODY;
157     }
158 
159     public int doEndTag() {
160         boolean localContentNodeSet = false;
161         Content oldContentNode = Resource.getLocalContentNode();
162 
163         // remove the collection name - the new anchor point for all tags is the current content
164         String oldLocalContentNodeCollectionName = Resource.getLocalContentNodeCollectionName();
165         Resource.setLocalContentNodeCollectionName(null);
166 
167         try {
168             // get content
169             Content content = this.contentNode;
170             if (content == null) {
171                 // was there a node name passed
172                 if (this.contentNodeName != null) {
173                     content = Resource.getCurrentActivePage().getContent(this.contentNodeName);
174                     if (content != null) {
175                         Resource.setLocalContentNode(content);
176                         localContentNodeSet = true;
177                     }
178                 }
179                 // use current (first local then global)
180                 else {
181                     content = Resource.getLocalContentNode();
182                     if (content == null) {
183                         content = Resource.getGlobalContentNode();
184                         if (content != null) {
185                             Resource.setLocalContentNode(content);
186                             localContentNodeSet = true;
187                         }
188                     }
189                 }
190                 if (content == null) {
191                     throw new Exception("no content node found"); //$NON-NLS-1$
192                 }
193             }
194 
195             if (content != Resource.getCurrentActivePage() && !localContentNodeSet && content != null) {
196                 Resource.setLocalContentNode(content);
197                 localContentNodeSet = true;
198             }
199 
200             final AggregationState aggregationState = MgnlContext.getAggregationState();
201             boolean orgShowPreview = aggregationState.isPreviewMode();
202             if(noEditBars && !orgShowPreview){
203                 aggregationState.setPreviewMode(true);
204             }
205 
206             if (this.path != null) { // TODO
207                 log.warn("You are using the deprecated path attribute of the include tag. Your jsp will be included for now, but you might want to update your code to avoid bad surprises in the future.");
208                 pageContext.include(this.path);
209             } else {
210                 WebContext webContext = MgnlContext.getWebContext();
211                 webContext.setPageContext(pageContext);
212                 try{
213                     renderingEngine.render(content, pageContext.getOut());
214                 }
215                 finally{
216                     webContext.setPageContext(null);
217                 }
218             }
219             if(noEditBars){
220                 aggregationState.setPreviewMode(orgShowPreview);
221             }
222 
223         } catch (IOException e) {
224             // should never happen
225             throw new RuntimeException(e);
226         } catch (Exception e) {
227             log.error(e.getMessage(), e);
228         }
229 
230         finally {
231             // if we set the local content node we have to reset it again else we keep the node
232             if(localContentNodeSet){
233                 if(oldContentNode != null){
234                     Resource.setLocalContentNode(oldContentNode);
235                 }
236                 else{
237                     Resource.removeLocalContentNode();
238                 }
239             }
240             // reset the former collection name
241             Resource.setLocalContentNodeCollectionName(oldLocalContentNodeCollectionName);
242         }
243 
244         this.removeAttributes();
245         return EVAL_PAGE;
246     }
247 
248     private void removeAttributes() {
249         HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
250         if ((attributes != null) && (attributes.size() > 0)) {
251             Iterator i = attributes.iterator();
252             while (i.hasNext()) {
253                 Object[] s = (Object[]) i.next();
254                 req.removeAttribute((String) s[0]);
255             }
256         }
257         attributes = null;
258     }
259 
260     public void release() {
261         this.path = null;
262         this.attributes = null;
263         this.contentNode = null;
264         super.release();
265     }
266 
267 }