View Javadoc

1   /**
2    * Copyright (C) 2005-2009 Alfresco Software Limited.
3    *
4    * This file is part of the Spring Surf Extension project.
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.springframework.extensions.surf.render;
20  
21  import javax.servlet.ServletContext;
22  import javax.servlet.http.HttpServletRequest;
23  import javax.servlet.http.HttpServletResponse;
24  import javax.servlet.jsp.tagext.BodyContent;
25  import javax.servlet.jsp.tagext.BodyTagSupport;
26  import javax.servlet.jsp.tagext.Tag;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.springframework.beans.BeansException;
31  import org.springframework.context.ApplicationContext;
32  import org.springframework.context.ApplicationContextAware;
33  import org.springframework.extensions.surf.WebFrameworkServiceRegistry;
34  import org.springframework.extensions.surf.exception.TagExecutionException;
35  import org.springframework.extensions.surf.util.FakeHttpServletResponse;
36  import org.springframework.extensions.surf.util.FakeJspPageContext;
37  import org.springframework.extensions.surf.util.FakeJspWriter;
38  import org.springframework.extensions.surf.util.WrappedHttpServletRequest;
39  import org.springframework.web.context.ServletContextAware;
40  
41  /**
42   * Service for running JSP tags
43   * 
44   * @author muzquiano
45   */
46  public class TagService implements ApplicationContextAware, ServletContextAware
47  {
48      private static final Log logger = LogFactory.getLog(TagService.class);
49          
50      private ServletContext servletContext;
51      private ApplicationContext applicationContext;
52      private WebFrameworkServiceRegistry webFrameworkServiceRegistry;
53      
54      /* (non-Javadoc)
55       * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
56       */
57      public void setApplicationContext(ApplicationContext applicationContext)
58          throws BeansException
59      {
60          this.applicationContext = applicationContext;
61      }
62          
63      /**
64       * Gets the application context.
65       * 
66       * @return the application context
67       */
68      public ApplicationContext getApplicationContext()
69      {
70          return this.applicationContext;
71      }
72      
73      /* (non-Javadoc)
74       * @see org.springframework.web.context.ServletContextAware#setServletContext(javax.servlet.ServletContext)
75       */
76      public void setServletContext(ServletContext servletContext)
77      {
78          this.servletContext = servletContext;
79      }
80      
81      /**
82       * Gets the servlet context.
83       * 
84       * @return the servlet context
85       */
86      public ServletContext getServletContext()
87      {
88          return this.servletContext;
89      }
90      
91      /**
92       * Sets the service registry.
93       * 
94       * @param webFrameworkServiceRegistry the new service registry
95       */
96      public void setServiceRegistry(WebFrameworkServiceRegistry webFrameworkServiceRegistry)
97      {
98          this.webFrameworkServiceRegistry = webFrameworkServiceRegistry;
99      }
100     
101     /**
102      * Gets the service registry.
103      * 
104      * @return the service registry
105      */
106     public WebFrameworkServiceRegistry getServiceRegistry()
107     {
108         return this.webFrameworkServiceRegistry;
109     }
110 
111     /**
112      * Executes the given tag within the context of the given servlet request.
113      * 
114      * @param tag the tag
115      * @param request the request
116      * @param realResponse the response
117      * 
118      * @return the string
119      */
120     public String execute(Tag tag, HttpServletRequest request, HttpServletResponse realResponse)
121         throws TagExecutionException
122     {
123         return execute(tag, request, realResponse, null);
124     }
125 
126     /**
127      * Executes the given tag within the context of the given servlet request.
128      * The supplied body content is taken to be the body tag.
129      * 
130      * Body content cannot contain additional tags for processing.  This method
131      * will not parse the contents of the body and process those tags.  Rather,
132      * it will insert the contents of the body into the output stream at the
133      * appropriate point.
134      * 
135      * @param tag the tag
136      * @param request the request
137      * @param realResponse the response
138      * @param bodyContentString the body content string
139      * 
140      * @return the string
141      */
142     public String execute(Tag tag, HttpServletRequest request, HttpServletResponse realResponse,
143             String bodyContentString) throws TagExecutionException
144     {
145         // Extract the servlet context from the request (session)
146         // Then proceed into the workhorse method
147         ServletContext context = request.getSession().getServletContext();
148         return execute(tag, context, request, realResponse, bodyContentString);
149     }
150 
151     /**
152      * Executes the given tag within the context of the given servlet
153      * context and request.
154      * 
155      * @param tag the tag
156      * @param context the context
157      * @param request the request
158      * @param realResponse the response
159      * 
160      * @return the string
161      */
162     public String execute(Tag tag, ServletContext context, HttpServletRequest request,
163             HttpServletResponse realResponse) throws TagExecutionException
164     {
165         return execute(tag, context, request, realResponse, null);
166     }
167     
168     /**
169      * Executes the given tag within the context of the given servlet
170      * context and request.
171      * 
172      * The supplied body content is taken to be the body tag.
173      * 
174      * Body content cannot contain additional tags for processing.  This method
175      * will not parse the contents of the body and process those tags.  Rather,
176      * it will insert the contents of the body into the output stream at the
177      * appropriate point.
178      * 
179      * This is the main workhorse method and is a lightweight implementation
180      * of a tag runner.
181      * 
182      * @param tag the tag
183      * @param context the context
184      * @param request the request
185      * @param realResponse the response
186      * @param bodyContentString the body content string
187      * 
188      * @return the string
189      */
190     public String execute(Tag tag, ServletContext context, HttpServletRequest request,
191             HttpServletResponse realResponse, String bodyContentString)
192         throws TagExecutionException
193     {
194         // Manufacture a request implementation within which the tag will run
195         WrappedHttpServletRequest tagRequest = new WrappedHttpServletRequest(request);
196         
197         // Manufacture a response implementation within which the tag will run
198         FakeHttpServletResponse tagResponse = new FakeHttpServletResponse(realResponse);
199         
200         // Execute the tag.  This proceeds by "running" the tag as per the JSP tag mechanism.
201         String response = null;
202         try
203         {
204             // Manufacture a jsp writer against which the tag will run
205             FakeJspWriter tagJspWriter = new FakeJspWriter(
206                     tagResponse.getWriter());
207             
208             // Manufacture a jsp page context against which the tag will run
209             FakeJspPageContext tagJspPageContext = new FakeJspPageContext(
210                     context, tagRequest, tagResponse, tagJspWriter);
211             
212             // Start the tag runner
213             tag.setPageContext(tagJspPageContext);
214             int startTagReturn = tag.doStartTag();
215             if (tag instanceof BodyTagSupport)
216             {
217                 if (startTagReturn == tag.EVAL_BODY_INCLUDE)
218                 {   
219                     BodyTagSupport support = ((BodyTagSupport)tag);
220                     
221                     BodyContent bc = tagJspPageContext.pushBody();
222                     support.setBodyContent(bc);
223                     
224                     support.doInitBody();
225                     support.doAfterBody();
226                     
227                     tagJspPageContext.popBody();
228                 }
229             }
230             
231             // If we have body content, copy it into the output stream
232             if (bodyContentString != null)
233             {
234                 tagJspWriter.print(bodyContentString);
235             }
236             tag.doEndTag();
237             tag.release();
238 
239             // Pick off the output and return it
240             response = tagResponse.getContentAsString();
241         }
242         catch (Exception ex)
243         {
244             throw new TagExecutionException("Unable to process tag: " + tag.toString(), ex);
245         }
246         
247         return response;
248     }
249     
250 }