/* * Copyright 2004-2012 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.mayaa.impl.cycle.web; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletContext; import org.seasar.mayaa.impl.util.IOUtil; /** * Webコンテナ外で動作させるためのServletContextのモック。 * コンストラクタでコンテキストパス、コンテキストルートのパスを渡す。 * * @author Koji Suga (Gluegent Inc.) */ public class MockServletContext implements ServletContext { private String _contextPath; private String _contextRoot; private Map _attributes = new HashMap(10); /** * コンテキストパスとコンテキストルートを引数に取るコンストラクタ。 * コンテキストパスはパスの自動解決やrequest.contextPathで利用されます。 * コンテキストルートはディレクトリパスをフルパスで指定してください。 * * @param basePath コンテキストルート * @param contextPath コンテキストパス */ public MockServletContext(String basePath, String contextPath) { _contextRoot = basePath; _contextPath = contextPath; } /* (non-Javadoc) * @see javax.servlet.ServletContext#getAttribute(java.lang.String) */ public Object getAttribute(String name) { return _attributes.get(name); } /* (non-Javadoc) * @see javax.servlet.ServletContext#getAttributeNames() */ public Enumeration getAttributeNames() { final Iterator keyIterator = _attributes.keySet().iterator(); return new Enumeration() { public boolean hasMoreElements() { return keyIterator.hasNext(); } public Object nextElement() { return keyIterator.next(); } }; } /* (non-Javadoc) * @see javax.servlet.ServletContext#removeAttribute(java.lang.String) */ public void removeAttribute(String name) { if (_attributes.containsKey(name)) { _attributes.remove(name); } } /* (non-Javadoc) * @see javax.servlet.ServletContext#setAttribute(java.lang.String, java.lang.Object) */ public void setAttribute(String name, Object object) { _attributes.put(name, object); } /** * nullを返します。 * * @param uripath 他Webアプリケーションのコンテキストパス * @return null * @see javax.servlet.ServletContext#getContext(java.lang.String) */ public ServletContext getContext(String uripath) { return null; } /** * nullを返します。 * * @param name 初期化パラメータ名 * @return null * @see javax.servlet.ServletContext#getInitParameter(java.lang.String) */ public String getInitParameter(String name) { return null; } /** * 要素を持たないEnumerationを返します。 * * @return 要素を持たないEnumeration * @see javax.servlet.ServletContext#getInitParameterNames() */ public Enumeration getInitParameterNames() { return NULL_ENUMERATION; } /** * Servlet API のメジャーバージョン番号として 2 を返します。 * * @return 2 * @see javax.servlet.ServletContext#getMajorVersion() */ public int getMajorVersion() { return 2; } /** * Servlet API のマイナーバージョン番号として 3 を返します。 * * @return 3 * @see javax.servlet.ServletContext#getMinorVersion() */ public int getMinorVersion() { return 3; } /** * {@link java.net.URLConnection#guessContentTypeFromName(java.lang.String)} * を使ってContentTypeを取得して返します。 * ただし正確とは限りません。 * * @param file MimeTypeを判定するファイル名 * @return fileに対応するMimeType * @see javax.servlet.ServletContext#getMimeType(java.lang.String) */ public String getMimeType(String file) { return URLConnection.guessContentTypeFromName(file); } /** * nullを返します。 * * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String) */ public RequestDispatcher getNamedDispatcher(String name) { return null; } protected File getFile(String path) { if (path == null) { return null; } if (path.startsWith("/") == false) { path = "/" + path; } File file = new File(_contextRoot + path); try { return new File(file.getCanonicalPath()); } catch (IOException e) { throw new RuntimeException("Illegal path : " + path); } } /** * pathをコンテキストルートからの相対パスと見なして、ファイルとしての * 絶対パスを返します。 * セキュリティ的な考慮はしていないため、コンテキストルートより上の * 階層へ辿ることもできるので注意してください。 * * @param RealPathを取得するパス * @return ファイルとしての絶対パス * @see javax.servlet.ServletContext#getRealPath(java.lang.String) */ public String getRealPath(String path) { File file = getFile(path); if (file != null && file.exists()) { return file.getAbsolutePath(); } return null; } /** * コンテキストルートからファイルとして見つけられる場合はそのファイルの * URLを返します。見つけられない場合は現在スレッドのコンテキストクラスローダー * を使ってgetReasourceの結果を返します。 * * @param path URLを取得するリソース名 * @return pathに対応するURL。存在しない場合はnull * @see javax.servlet.ServletContext#getResource(java.lang.String) */ public URL getResource(String path) throws MalformedURLException { File file = getFile(path); if (file != null && file.exists()) { return file.toURI().toURL(); } return IOUtil.getResource(path); } /** * コンテキストルートからファイルとして見つけられる場合はそのファイルの * InputStreamを返します。見つけられない場合は現在スレッドの * コンテキストクラスローダーを使ってgetReasourceの結果URLをopenして返します。 * * @param path URLを取得するリソース名 * @return pathに対応するリソースのInputStream。存在しない場合はnull * @see javax.servlet.ServletContext#getResourceAsStream(java.lang.String) */ public InputStream getResourceAsStream(String path) { try { return IOUtil.openStream(getResource(path)); } catch (MalformedURLException e) { log(e.getMessage(), e); } return null; } /** * 空のSetを返します。 * * @param path ディレクトリのパス * @return 空のSet * @see javax.servlet.ServletContext#getResourcePaths(java.lang.String) */ public Set getResourcePaths(String path) { return new HashSet(); } /** * nullを返します。 * * @param path 対象のパス * @return null * @see javax.servlet.ServletContext#getRequestDispatcher(java.lang.String) */ public RequestDispatcher getRequestDispatcher(String path) { return null; } /** * "Mayaa MockServletContext"という文字列を返します。 * * @return "Mayaa MockServletContext" * @see javax.servlet.ServletContext#getServerInfo() */ public String getServerInfo() { return "Mayaa MockServletContext"; } /** * nullを返します。 * * @param name 対象のServlet名 * @return null * @see javax.servlet.ServletContext#getServlet(java.lang.String) * @deprecated */ public Servlet getServlet(String name) { return null; } /** * contextPathを返します。 * * @return contextPath * @see javax.servlet.ServletContext#getServletContextName() */ public String getServletContextName() { return _contextPath; } /** * 要素を持たないEnumerationを返します。 * * @return 要素を持たないEnumeration * @see javax.servlet.ServletContext#getServletNames() * @deprecated */ public Enumeration getServletNames() { return NULL_ENUMERATION; } /** * 要素を持たないEnumerationを返します。 * * @return 要素を持たないEnumeration * @see javax.servlet.ServletContext#getServlets() * @deprecated */ public Enumeration getServlets() { return NULL_ENUMERATION; } /** * java.lang.System.out.printlnを利用してmessageを出力する。 * * @param message メッセージ * @see javax.servlet.ServletContext#log(java.lang.String) */ public void log(String message) { System.out.println(message); } /** * java.lang.System.out.printlnを利用してmessageを出力する。 * その後、exceptionのprintStackTrace()を実行する。 * * @param message メッセージ * @param exception 例外 * @see javax.servlet.ServletContext#log(java.lang.Exception, java.lang.String) * @deprecated */ public void log(Exception exception, String message) { System.out.println(message); if (exception != null) { exception.printStackTrace(); } } /** * java.lang.System.out.printlnを利用してmessageを出力する。 * その後、throwableのprintStackTrace()を実行する。 * * @param message メッセージ * @param Throwable 例外 * @see javax.servlet.ServletContext#log(java.lang.String, java.lang.Throwable) */ public void log(String message, Throwable throwable) { System.out.println(message); if (throwable != null) { throwable.printStackTrace(); } } /** * 要素を持たないEnumeration。 */ private static final Enumeration NULL_ENUMERATION = new Enumeration() { public boolean hasMoreElements() { return false; } public Object nextElement() { throw new NoSuchElementException(); } }; }