001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.mocks;
018:
019: import java.io.File;
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.net.MalformedURLException;
023: import java.net.URL;
024: import java.util.ArrayList;
025: import java.util.HashMap;
026: import java.util.HashSet;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.Set;
031:
032: import javax.servlet.RequestDispatcher;
033: import javax.servlet.Servlet;
034:
035: import org.apache.commons.digester.Digester;
036: import org.apache.commons.digester.Rule;
037: import org.apache.commons.logging.Log;
038: import org.apache.commons.logging.LogFactory;
039: import org.apache.oro.text.GlobCompiler;
040: import org.apache.oro.text.regex.Pattern;
041: import org.apache.oro.text.regex.PatternCompiler;
042: import org.apache.oro.text.regex.PatternMatcher;
043: import org.apache.oro.text.regex.Perl5Matcher;
044:
045: import com.mockrunner.mock.web.MockServletConfig;
046:
047: public class ResourceLocatingServletContext extends
048: BaseMockServletContext {
049: protected final static Log log = LogFactory
050: .getLog(ResourceLocatingServletContext.class);
051:
052: private final File rootPath;
053: private final Map pathOverrides = new HashMap();
054: private final List servletInfoList = new ArrayList();
055: private final List servletMappingInfoList = new ArrayList();
056: private final Map servletInstanceMap = new HashMap();
057:
058: public ResourceLocatingServletContext(File rootPath) {
059: super ();
060: this .rootPath = rootPath;
061: }
062:
063: public ResourceLocatingServletContext(File rootPath,
064: boolean loadServlet) {
065: super ();
066: this .rootPath = rootPath;
067:
068: if (loadServlet)
069: loadServlets();
070: }
071:
072: public final void addPathOverride(String path, File file) {
073: pathOverrides.put(path, file);
074: }
075:
076: public URL getResource(String path) throws MalformedURLException {
077: if (pathOverrides.containsKey(path)) {
078: return ((File) pathOverrides.get(path)).toURL();
079: } else {
080: return new File(rootPath, path).toURL();
081: }
082: }
083:
084: public String getRealPath(String path) {
085: if (pathOverrides.containsKey(path)) {
086: return ((File) pathOverrides.get(path)).getAbsolutePath();
087: } else {
088: return new File(rootPath, path).getAbsolutePath();
089: }
090: }
091:
092: public InputStream getResourceAsStream(String path) {
093: try {
094: return getResource(path).openStream();
095: } catch (IOException e) {
096: // TODO Auto-generated catch block
097: e.printStackTrace();
098: return null;
099: }
100: }
101:
102: public Set getResourcePaths(String path) {
103: File start = new File(rootPath, path);
104: File[] children = start.listFiles();
105: HashSet pathes = new HashSet();
106: for (int i = 0; i < children.length; i++) {
107: File child = children[i];
108: String relativePath = child.getPath().substring(
109: rootPath.getPath().length()).replace('\\', '/');
110:
111: if (child.isDirectory()) {
112: pathes.add(relativePath + "/");
113: } else {
114: pathes.add(relativePath);
115: }
116: }
117:
118: Iterator itr = pathOverrides.keySet().iterator();
119: while (itr.hasNext()) {
120: pathes.add(itr.next());
121: }
122:
123: return pathes;
124: }
125:
126: public RequestDispatcher getRequestDispatcher(String arg0) {
127: Servlet servlet = findServletByPath(arg0);
128:
129: if (servlet == null) {
130: throw new IllegalArgumentException(
131: "Failed to find servlet for the path: " + arg0);
132: }
133:
134: return new ResourceLocatingRequestDispatcher(servlet, arg0,
135: null);
136: }
137:
138: protected Servlet findServletByPath(String path) {
139: Servlet servlet = null;
140:
141: for (Iterator it = this .servletMappingInfoList.iterator(); it
142: .hasNext();) {
143: ServletMappingInfo servletMappingInfo = (ServletMappingInfo) it
144: .next();
145: Pattern pattern = servletMappingInfo.getPattern();
146:
147: if (pattern != null) {
148: PatternMatcher matcher = new Perl5Matcher();
149:
150: if ((matcher.matches(path, pattern))
151: || (matcher.matches(path + "/", pattern))) {
152: servlet = (Servlet) this .servletInstanceMap
153: .get(servletMappingInfo.getServletName());
154: break;
155: }
156: }
157: }
158:
159: return servlet;
160: }
161:
162: protected void loadServlets() {
163: this .servletInfoList.clear();
164: this .servletMappingInfoList.clear();
165:
166: Digester digester = new Digester();
167:
168: digester.addObjectCreate("web-app/servlet", ServletInfo.class);
169: digester.addBeanPropertySetter("web-app/servlet/servlet-name",
170: "servletName");
171: digester.addBeanPropertySetter("web-app/servlet/servlet-class",
172: "servletClass");
173: digester.addCallMethod("web-app/servlet/init-param",
174: "addInitParam", 2);
175: digester.addCallParam("web-app/servlet/init-param/param-name",
176: 0);
177: digester.addCallParam("web-app/servlet/init-param/param-value",
178: 1);
179: digester.addRule("web-app/servlet", new ServletRule(
180: this .servletInfoList));
181:
182: digester.addObjectCreate("web-app/servlet-mapping",
183: ServletMappingInfo.class);
184: digester.addBeanPropertySetter(
185: "web-app/servlet-mapping/servlet-name", "servletName");
186: digester.addBeanPropertySetter(
187: "web-app/servlet-mapping/url-pattern", "urlPattern");
188: digester.addRule("web-app/servlet-mapping",
189: new ServletMappingRule(this .servletMappingInfoList));
190:
191: File webInfPath = new File(this .rootPath, "WEB-INF");
192: File webDescriptorFile = new File(webInfPath, "web.xml");
193: log.debug("parsing webDescriptorFile: " + webDescriptorFile);
194:
195: try {
196: digester.parse(webDescriptorFile);
197: } catch (Exception e) {
198: log.error("Failed to parse webDescriptorFile: "
199: + webDescriptorFile, e);
200: }
201:
202: for (Iterator it = this .servletInfoList.iterator(); it
203: .hasNext();) {
204: ServletInfo servletInfo = (ServletInfo) it.next();
205:
206: try {
207: Servlet servlet = (Servlet) Class.forName(
208: servletInfo.getServletClass()).newInstance();
209: MockServletConfig servletConfig = new MockServletConfig();
210: servletConfig.setServletContext(this );
211:
212: Map initParamMap = servletInfo.getInitParamMap();
213:
214: for (Iterator itParam = initParamMap.keySet()
215: .iterator(); itParam.hasNext();) {
216: String paramName = (String) itParam.next();
217: String paramValue = (String) initParamMap
218: .get(paramName);
219: servletConfig.setInitParameter(paramName,
220: paramValue);
221: }
222:
223: servlet.init(servletConfig);
224:
225: this .servletInstanceMap.put(servletInfo
226: .getServletName(), servlet);
227: } catch (Exception e) {
228: log.error("Failed to load and initialize servlet: "
229: + servletInfo);
230: }
231: }
232: }
233:
234: public static class ServletInfo {
235: protected String servletName;
236: protected String servletClass;
237: protected Map initParamMap = new HashMap();
238:
239: public void setServletName(String servletName) {
240: this .servletName = servletName;
241: }
242:
243: public String getServletName() {
244: return this .servletName;
245: }
246:
247: public void setServletClass(String servletClass) {
248: this .servletClass = servletClass;
249: }
250:
251: public String getServletClass() {
252: return this .servletClass;
253: }
254:
255: public void addInitParam(String paramName, String paramValue) {
256: this .initParamMap.put(paramName, paramValue);
257: }
258:
259: public Map getInitParamMap() {
260: return this .initParamMap;
261: }
262:
263: public String toString() {
264: return "ServletInfo [" + this .servletName + ", "
265: + this .servletClass + ", " + this .initParamMap
266: + "]";
267: }
268: }
269:
270: public static class ServletMappingInfo {
271: protected String servletName;
272: protected String urlPattern;
273: protected Pattern pattern;
274:
275: public void setServletName(String servletName) {
276: this .servletName = servletName;
277: }
278:
279: public String getServletName() {
280: return this .servletName;
281: }
282:
283: public void setUrlPattern(String urlPattern) {
284: this .urlPattern = urlPattern;
285: this .pattern = null;
286:
287: try {
288: PatternCompiler compiler = new GlobCompiler();
289: this .pattern = compiler.compile(this .urlPattern);
290: } catch (Exception e) {
291: log.error("Invalid url pattern: " + this .urlPattern);
292: }
293: }
294:
295: public String getUrlPattern() {
296: return this .urlPattern;
297: }
298:
299: public Pattern getPattern() {
300: return this .pattern;
301: }
302:
303: public String toString() {
304: return "ServletMappingInfo [" + this .urlPattern + ", "
305: + this .servletName + "]";
306: }
307: }
308:
309: public static class ServletRule extends Rule {
310: private List servletInfoList;
311:
312: public ServletRule(List servletInfoList) {
313: this .servletInfoList = servletInfoList;
314: }
315:
316: public void end(String namespace, String name) {
317: try {
318: ServletInfo servletInfo = (ServletInfo) digester
319: .peek(0);
320: this .servletInfoList.add(servletInfo);
321: } catch (Exception e) {
322: log.error("Exception occurred in ServletRule", e);
323: }
324: }
325: }
326:
327: public static class ServletMappingRule extends Rule {
328: private List servletMappingInfoList;
329:
330: public ServletMappingRule(List servletMappingInfoList) {
331: this .servletMappingInfoList = servletMappingInfoList;
332: }
333:
334: public void end(String namespace, String name) {
335: try {
336: ServletMappingInfo servletMappingInfo = (ServletMappingInfo) digester
337: .peek(0);
338: this .servletMappingInfoList.add(servletMappingInfo);
339: } catch (Exception e) {
340: log
341: .error(
342: "Exception occurred in ServletMappingRule",
343: e);
344: }
345: }
346: }
347:
348: }
|