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 }