1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 package groovy.servlet;
40
41 import groovy.lang.MetaClass;
42 import groovy.util.ResourceConnector;
43 import groovy.util.ResourceException;
44
45 import java.io.File;
46 import java.io.IOException;
47 import java.net.URL;
48 import java.net.URLConnection;
49
50 import javax.servlet.ServletConfig;
51 import javax.servlet.ServletContext;
52 import javax.servlet.ServletException;
53 import javax.servlet.http.HttpServlet;
54 import javax.servlet.http.HttpServletRequest;
55
56 /***
57 * A common ground dealing with the http servlet API wrinkles.
58 *
59 * @author Christian Stein
60 */
61 public abstract class AbstractHttpServlet extends HttpServlet implements
62 ResourceConnector {
63
64 /***
65 * Content type of the HTTP response.
66 */
67 public static final String CONTENT_TYPE_TEXT_HTML = "text/html";
68
69 /***
70 * Servlet API include key name: path_info
71 */
72 public static final String INC_PATH_INFO = "javax.servlet.include.path_info";
73
74
75
76
77
78
79 /***
80 * Servlet API include key name: servlet_path
81 */
82 public static final String INC_SERVLET_PATH = "javax.servlet.include.servlet_path";
83
84 /***
85 * Debug flag logging the class the class loader of the request.
86 */
87 private boolean logRequestClassAndLoaderOnce;
88
89 /***
90 * Servlet (or the web application) context.
91 */
92 protected ServletContext servletContext;
93
94 /***
95 * Initializes all fields.
96 *
97 */
98 public AbstractHttpServlet() {
99 this.logRequestClassAndLoaderOnce = true;
100 this.servletContext = null;
101 }
102
103 /***
104 * Interface method for ResourceContainer. This is used by the GroovyScriptEngine.
105 */
106 public URLConnection getResourceConnection(String name)
107 throws ResourceException {
108 try {
109 URL url = servletContext.getResource("/" + name);
110 if (url == null) {
111 url = servletContext.getResource("/WEB-INF/groovy/" + name);
112 if (url == null) {
113 throw new ResourceException("Resource " + name + " not found");
114 }
115 }
116 return url.openConnection();
117 }
118 catch (IOException ioe) {
119 throw new ResourceException("Problem reading resource " + name);
120 }
121 }
122
123 /***
124 * Returns the include-aware uri of the script or template file.
125 *
126 * @param request
127 * the http request to analyze
128 * @return the include-aware uri either parsed from request attributes or
129 * hints provided by the servlet container
130 */
131 protected String getScriptUri(HttpServletRequest request) {
132
133 if (logRequestClassAndLoaderOnce) {
134 log("Logging request class and its class loader:");
135 log(" c = request.getClass() :\"" + request.getClass()+ "\"");
136 log(" l = c.getClassLoader() :\"" + request.getClass().getClassLoader()+ "\"");
137 log(" l.getClass() :\"" + request.getClass().getClassLoader().getClass()+ "\"");
138 logRequestClassAndLoaderOnce = false;
139 }
140
141
142
143
144
145
146
147
148
149
150 String uri = null;
151 String info = null;
152
153
154
155
156
157 uri = (String) request.getAttribute(INC_SERVLET_PATH);
158 if (uri != null) {
159
160
161
162
163
164 info = (String) request.getAttribute(INC_PATH_INFO);
165 if (info != null) {
166 uri += info;
167 }
168 return uri;
169 }
170
171
172
173
174
175
176 uri = request.getServletPath();
177 info = request.getPathInfo();
178 if (info != null) {
179 uri += info;
180 }
181
182 return uri;
183 }
184
185 /***
186 * Parses the http request for the real script or template source file.
187 *
188 * @param request
189 * the http request to analyze
190 * @param context
191 * the context of this servlet used to get the real path string
192 * @return a file object using an absolute file path name
193 */
194 protected File getScriptUriAsFile(HttpServletRequest request) {
195 String uri = getScriptUri(request);
196 String real = servletContext.getRealPath(uri);
197 File file = new File(real).getAbsoluteFile();
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 return file;
217 }
218
219 /***
220 * Overrides the generic init method.
221 *
222 * Enables a fix, that tells Groovy to use (slower) reflection than compiling
223 * metaclass proxies. This is needed due to some container implementation hide
224 * their classes from the servlet by using different class loaders. See
225 * {@link http://jira.codehaus.org/browse/GROOVY-861} for details.
226 *
227 * @param config
228 * the servlet coniguration provided by the container
229 * @throws ServletException if init() method defined in super class
230 * javax.servlet.GenericServlet throws it
231 */
232 public void init(ServletConfig config) throws ServletException {
233 super.init(config);
234 this.servletContext = config.getServletContext();
235
236
237 MetaClass.setUseReflection(true);
238 String value = config.getInitParameter("logRequestClassAndLoaderOnce");
239 if (value != null) {
240 this.logRequestClassAndLoaderOnce = Boolean.valueOf(value).booleanValue();
241 }
242
243 }
244
245 }