You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@locus.apache.org on 2000/01/12 07:35:22 UTC

cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util Constants.java FileUtil.java URLUtil.java WARUtil.java

costin      00/01/11 22:35:22

  Modified:    src/share/org/apache/tomcat/core Context.java
                        ContextManager.java Request.java
                        ServletContextFacade.java
               src/share/org/apache/tomcat/servlets DefaultServlet.java
               src/share/org/apache/tomcat/util Constants.java
                        FileUtil.java URLUtil.java WARUtil.java
  Log:
  Cleaned up getResource() - will create a subrequest, pass it to the mapping stage,
  get the translated result.
  
  Minor cleanup in Request ( eliminate duplicated code, eliminate unused public methods )
  
  Added some comments in DefaultServlet - someone needs to rewrite it from 0, but
  it's not in core :-)
  
  Revision  Changes    Path
  1.27      +53 -52    jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- Context.java	2000/01/12 00:57:31	1.26
  +++ Context.java	2000/01/12 06:35:20	1.27
  @@ -67,6 +67,7 @@
   import java.net.*;
   import java.util.*;
   import javax.servlet.http.*;
  +import javax.servlet.*;
   
   //
   // WARNING: Some of the APIs in this class are used by J2EE. 
  @@ -229,70 +230,70 @@
   	return this.rsProvider;
       }
   
  -    public URL getResource(String path)	throws MalformedURLException {
  -        URL url = null;
  +    /** Will return an URL that can be used to read the resource pointed by
  +     * req, using the context base and the mapped path
  +     */
  +    public URL getResourceURL(Request req)
  +	throws MalformedURLException
  +    {
  +	String mappedPath = req.getMappedPath();
  +	if( mappedPath == null ) {
  +	    mappedPath=req.getPathInfo();
  +	}
  +	
  +        URL docBase = getDocumentBase();
   
  -        if (path == null) {
  -            String msg = sm.getString("scfacade.getresource.npe");
  -            throw new NullPointerException(msg);
  -        } else if (! path.equals("") &&
  -	    ! path.startsWith("/")) {
  -	    String msg = sm.getString("scfacade.getresource.iae", path);
  -	    throw new IllegalArgumentException(msg);
  +	// again, the special case of serving from wars
  +	// XXX Need an architecture to deal with other cases, like database-stored files,
  +	// etc.
  +	if (docBase.getProtocol().equalsIgnoreCase("war")) {
  +	    return WARUtil.createURL( this, mappedPath );
   	}
   
  -	// XXX
  -	// this could use a once over - after war perhaps
  -        URL docBase = getDocumentBase();
  +	return new URL(docBase.getProtocol(), docBase.getHost(),
  +		       docBase.getPort(), docBase.getFile() + mappedPath);
  +    }
   
  -	Request lr=contextM.createRequest( this, path );
  +    public RequestDispatcher getRequestDispatcher(String path) {
  +	if ( path == null   || 
  +	     ! path.startsWith("/")) {
  +	    return null; // spec say "return null if we can't return a dispather
  +	}
  +	//	Request subReq=context.getContextManager().createRequest( path );
  +	//        RequestDispatcherImpl requestDispatcher = new RequestDispatcherImpl(subReq);
  +	
  +	RequestDispatcherImpl requestDispatcher = new RequestDispatcherImpl(this);
  +	requestDispatcher.setPath( path ) ;
  +	
  +	return requestDispatcher;
  +    }
   
  -	getContextManager().processRequest(lr);
   
  -	String mappedPath = path;
   
  -	if (lr != null &&
  -	    lr.getMappedPath() != null &&
  -	    lr.getMappedPath().trim().length() > 0) {
  -	    mappedPath = lr.getMappedPath();
  +    /** Implements getResource() - use a sub-request to let interceptors do the job.
  +     */
  +    public URL getResource(String path)	throws MalformedURLException {
  +        URL url = null;
  +
  +	if ("".equals(path)) 
  +	    return getDocumentBase();
  +	
  +	// deal with exceptional cases
  +        if (path == null) 
  +            throw new MalformedURLException(sm.getString("scfacade.getresource.npe"));
  +        else if ( ! path.startsWith("/")) {
  +	    throw new MalformedURLException(sm.getString("scfacade.getresource.iae", path));
   	}
   
  -	if (path.equals("")) {
  -	    url = docBase;
  -	} else if (docBase.getProtocol().equalsIgnoreCase("war")) {
  -	    if (isWARExpanded()) {
  -		File f = new File(getWARDir().toString());
  -		String absPath = f.getAbsolutePath();
  -
  -		// take care of File.getAbsolutePath() troubles
  -		// on jdk1.1.x/win
  -
  -		absPath = FileUtil.patch(absPath);
  -
  -                if (! absPath.startsWith("/")) {
  -                    absPath = "/" + absPath;
  -                }
  -
  -		url = new URL("file://localhost" + absPath + "/" +
  -		    mappedPath);
  -	    } else {
  -                String documentBase = getDocumentBase().toString();
  -
  -                if (documentBase.endsWith("/")) {
  -                    documentBase = documentBase.substring(0,
  -                        documentBase.length() - 1);
  -                }
  -
  -                url = new URL(documentBase + "!" + mappedPath);
  -	    }
  -	} else {
  -            url = new URL(docBase.getProtocol(), docBase.getHost(),
  -                docBase.getPort(), docBase.getFile() + mappedPath);
  -        }
  +	// Create a Sub-Request, do the request processing stage
  +	// that will take care of aliasing and set the paths
  +	Request lr=contextM.createRequest( this, path );
  +	getContextManager().processRequest(lr);
   
  -        return url;
  +	return getResourceURL( lr );
       }
   
  +    
       Context getContext(String path) {
   	if (! path.startsWith("/")) {
               String msg = sm.getString("sfcacade.context.iae", path);
  
  
  
  1.14      +2 -1      jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java
  
  Index: ContextManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ContextManager.java	2000/01/12 00:57:31	1.13
  +++ ContextManager.java	2000/01/12 06:35:20	1.14
  @@ -332,7 +332,7 @@
   	// assert urlPath!=null
   
   	// deal with paths with parameters in it
  -	String queryString;
  +	String queryString=null;
   	int i = urlPath.indexOf("?");
   	int len=urlPath.length();
   	if (i>-1) {
  @@ -345,6 +345,7 @@
   	RequestAdapterImpl reqA=new RequestAdapterImpl();
   	lr.setRequestAdapter( reqA);
   	lr.setLookupPath( urlPath );
  +	lr.setQueryString( queryString );
   	lr.setContext( ctx );
   
   	// XXX set query string too 
  
  
  
  1.18      +44 -123   jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java
  
  Index: Request.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- Request.java	2000/01/12 00:57:31	1.17
  +++ Request.java	2000/01/12 06:35:20	1.18
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java,v 1.17 2000/01/12 00:57:31 costin Exp $
  - * $Revision: 1.17 $
  - * $Date: 2000/01/12 00:57:31 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java,v 1.18 2000/01/12 06:35:20 costin Exp $
  + * $Revision: 1.18 $
  + * $Date: 2000/01/12 06:35:20 $
    *
    * ====================================================================
    *
  @@ -92,7 +92,7 @@
       protected Vector cookies = new Vector();
   
       protected String contextPath;
  -    protected String lookupPath;
  +    protected String lookupPath; // everything after contextPath before ?
       protected String servletPath;
       protected String pathInfo;
   
  @@ -126,7 +126,7 @@
   
       // LookupResult - used by sub-requests and
       // set by interceptors
  -    ServletWrapper wrapper = null;
  +    ServletWrapper handler = null;
       String mappedPath = null;
       String resolvedServlet = null;
       String resouceName=null;
  @@ -222,27 +222,12 @@
       }
   
       public String[] getParameterValues(String name) {
  -	if(!didParameters) {
  -	    String qString=getQueryString();
  -	    if(qString!=null) {
  -		processFormData(qString);
  -	    }
  -	}
  -	if (!didReadFormData) {
  -	    readFormData();
  -	}
  -
  +	handleParameters();
           return (String[])parameters.get(name);
       }
   
       public Enumeration getParameterNames() {
  -	if(!didParameters) {
  -	    processFormData(getQueryString());
  -	}
  -	if (!didReadFormData) {
  -	    readFormData();
  -	}
  -
  +	handleParameters();
           return parameters.keys();
       }
   
  @@ -252,14 +237,8 @@
        * query string, if any.
        */
       public Hashtable getParametersCopy() {
  -       if(!didParameters) {
  -           processFormData(getQueryString());
  -       }
  -       if (!didReadFormData) {
  -           readFormData();
  -       }
  -
  -       return (Hashtable) parameters.clone();
  +	handleParameters();
  +	return (Hashtable) parameters.clone();
       }
   
       public String getAuthType() {
  @@ -294,30 +273,15 @@
       }
       
       String getPathTranslated() {
  -        String pathTranslated = null;
  -	String pathInfo = getPathInfo();
  -
  -	if (pathInfo != null) {
  -            if (pathInfo.equals("")) {
  -                pathInfo = "/";
  -            }
  -
  -    	    try {
  -                URL url = 
  -		    context.getResource(pathInfo);
  -
  -                if (url != null &&
  -                    url.getProtocol().equals("file")) {
  -                    pathTranslated = FileUtil.patch(url.getFile());
  -                }
  -            } catch (MalformedURLException e) {
  -            }
  -        }
  -	
  -	// XXX
  -	// resolve this against the context
  -
  -        return pathTranslated;
  +	try {
  +	    URL url = context.getResourceURL(this);
  +	    
  +	    if (url != null &&	url.getProtocol().equals("file")) {
  +		return FileUtil.patch(url.getFile());
  +	    }
  +	} catch (MalformedURLException e) {
  +	}
  +	return null;
       }
   
   
  @@ -344,46 +308,20 @@
   	    return false;
   	return context.getRequestSecurityProvider().isSecure(context, getFacade());
       }
  -    
  +
       RequestDispatcher getRequestDispatcher(String path) {
  -        if (path == null) {
  -	    String msg = sm.getString("hsrf.dispatcher.iae", path);
  -	    throw new IllegalArgumentException(msg);
  -	}
  +        if (path == null)
  +	    return null;
   
   	if (! path.startsWith("/")) {
  -	    String lookupPath = getLookupPath();
  -
  -            // Cut off the last slash and everything beyond
  -	    int index = lookupPath.lastIndexOf("/");
  -	    lookupPath = lookupPath.substring(0, index);
  -
  -            // Deal with .. by chopping dirs off the lookup path
  -	    while (path.startsWith("../")) { 
  -		if (lookupPath.length() > 0) {
  -		    index = lookupPath.lastIndexOf("/");
  -		    lookupPath = lookupPath.substring(0, index);
  -		} 
  -                else {
  -                    // More ..'s than dirs, return null
  -                    return null;
  -                }
  -
  -		index = path.indexOf("../") + 3;
  -		path = path.substring(index);
  -	    }
  -
  -	    path = lookupPath + "/" + path;
  +	    path= FileUtil.catPath( getLookupPath(), path );
  +	    if( path==null) return null;
   	}
   
  -	RequestDispatcher requestDispatcher =
  -	    context.getFacade().getRequestDispatcher(path);
  -
  -        return requestDispatcher;
  +	return context.getRequestDispatcher(path);
       }
   
   
  -    
       Principal getUserPrincipal() {
   	if( context.getRequestSecurityProvider() == null )
   	    return null;
  @@ -475,7 +413,7 @@
   	    // XXX need a better test
   	    // XXX need to use adapter for hings
   	    didCookies=true;
  -	    processCookies();
  +	    RequestUtil.processCookies( this, cookies );
   	}
   
   	Cookie[] cookieArray = new Cookie[cookies.size()];
  @@ -564,13 +502,16 @@
       }
   
       public ServletWrapper getWrapper() {
  -	return wrapper;
  +	return handler;
       }
       
  -    public void setWrapper(ServletWrapper wrapper) {
  -	this.wrapper=wrapper;
  +    public void setWrapper(ServletWrapper handler) {
  +	this.handler=handler;
       }
   
  +    /** The file - result of mapping the request ( using aliases and other
  +     *  mapping rules. Usefull only for static resources.
  +     */
       public String getMappedPath() {
   	return mappedPath;
       }
  @@ -729,40 +670,20 @@
   	return RequestUtil.getReader( this );
       }
   
  -
  -    private void readFormData() {
  -	didReadFormData = true;
  -	if(!didParameters) {
  -	    processFormData(getQueryString());
  +    private void handleParameters() {
  +   	if(!didParameters) {
  +	    String qString=getQueryString();
  +	    if(qString!=null) {
  +		didParameters=true;
  +		RequestUtil.processFormData( qString, parameters );
  +	    }
   	}
  -
  -	Hashtable postParameters=RequestUtil.readFormData( this );
  -	if(postParameters!=null)
  -	    parameters = RequestUtil.mergeParameters(parameters, postParameters);
  -    }
  -
  -    public void processCookies() {
  -	RequestUtil.processCookies( this, cookies );
  -    }
  -
  -    // XXX
  -    // general comment -- we've got one form of this method that takes
  -    // a string, another that takes an inputstream -- they don't work
  -    // well together. FIX
  -
  -    public void processFormData(String data) {
  -	didParameters=true;
  -	RequestUtil.processFormData( data, parameters );
  -    }
  -
  -    public void processFormData(InputStream in, int contentLength) 
  -        throws UnsupportedEncodingException
  -    {
  -        byte[] buf = new byte[contentLength]; // XXX garbage collection!
  -	int read = RequestUtil.readData( in, buf, contentLength );
  -        // XXX if charset is ever anything other than the default, this must be fixed.
  -        String s = new String(buf, 0, read, Constants.CharacterEncoding.Default);
  -        processFormData(s);
  +	if (!didReadFormData) {
  +	    didReadFormData = true;
  +	    Hashtable postParameters=RequestUtil.readFormData( this );
  +	    if(postParameters!=null)
  +		parameters = RequestUtil.mergeParameters(parameters, postParameters);
  +	}
       }
   
       // -------------------- End utils
  
  
  
  1.14      +1 -11     jakarta-tomcat/src/share/org/apache/tomcat/core/ServletContextFacade.java
  
  Index: ServletContextFacade.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletContextFacade.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ServletContextFacade.java	2000/01/12 00:57:31	1.13
  +++ ServletContextFacade.java	2000/01/12 06:35:20	1.14
  @@ -150,17 +150,7 @@
       }
   
       public RequestDispatcher getRequestDispatcher(String path) {
  -	if ( path == null   || 
  -	    ! path.startsWith("/")) {
  -	    return null; // spec say "return null if we can't return a dispather
  -	}
  -	//	Request subReq=context.getContextManager().createRequest( path );
  -	//        RequestDispatcherImpl requestDispatcher = new RequestDispatcherImpl(subReq);
  -
  -	RequestDispatcherImpl requestDispatcher = new RequestDispatcherImpl(context);
  -	requestDispatcher.setPath( path ) ;
  -	
  -	return requestDispatcher;
  +	return context.getRequestDispatcher( path );
       }
   
       public RequestDispatcher getNamedDispatcher(String name) {
  
  
  
  1.2       +3 -0      jakarta-tomcat/src/share/org/apache/tomcat/servlets/DefaultServlet.java
  
  Index: DefaultServlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/servlets/DefaultServlet.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultServlet.java	2000/01/11 03:02:15	1.1
  +++ DefaultServlet.java	2000/01/12 06:35:20	1.2
  @@ -108,6 +108,9 @@
   	    requestURI = request.getRequestURI();
   	}
   
  +	// XXX XXX BAD BAD BAD - that means another request,
  +	// with the same informations !!!!!!!
  +	// It should use getMappedPath instead !!!
           URL url = getServletContext().getResource(pathInfo);
   
   	if (url != null) {
  
  
  
  1.4       +3 -7      jakarta-tomcat/src/share/org/apache/tomcat/util/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/Constants.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Constants.java	2000/01/09 03:21:16	1.3
  +++ Constants.java	2000/01/12 06:35:21	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/Constants.java,v 1.3 2000/01/09 03:21:16 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2000/01/09 03:21:16 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/Constants.java,v 1.4 2000/01/12 06:35:21 costin Exp $
  + * $Revision: 1.4 $
  + * $Date: 2000/01/12 06:35:21 $
    *
    * ====================================================================
    *
  @@ -87,10 +87,6 @@
               public static final String Resource =
                   "/org/apache/tomcat/deployment/web.dtd";
           }
  -    }
  -
  -    public static class MIME {
  -        public static final String WAR = "war";
       }
   
       public static class SESSION {
  
  
  
  1.3       +32 -4     jakarta-tomcat/src/share/org/apache/tomcat/util/FileUtil.java
  
  Index: FileUtil.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/FileUtil.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FileUtil.java	1999/11/12 23:33:03	1.2
  +++ FileUtil.java	2000/01/12 06:35:21	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/FileUtil.java,v 1.2 1999/11/12 23:33:03 costin Exp $
  - * $Revision: 1.2 $
  - * $Date: 1999/11/12 23:33:03 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/FileUtil.java,v 1.3 2000/01/12 06:35:21 costin Exp $
  + * $Revision: 1.3 $
  + * $Date: 2000/01/12 06:35:21 $
    *
    * ====================================================================
    *
  @@ -94,9 +94,37 @@
   	return fs;
       }
   
  +
  +    /** Will concatenate 2 paths, dealing with ..
  +     * ( /a/b/c + d = /a/b/d, /a/b/c + ../d = /a/d )
  +     * Used in Request.getRD
  +     * @return null if error occurs
  +     */
  +    public static String catPath(String lookupPath, String path) {
  +	// Cut off the last slash and everything beyond
  +	int index = lookupPath.lastIndexOf("/");
  +	lookupPath = lookupPath.substring(0, index);
  +	
  +	// Deal with .. by chopping dirs off the lookup path
  +	while (path.startsWith("../")) { 
  +	    if (lookupPath.length() > 0) {
  +		index = lookupPath.lastIndexOf("/");
  +		lookupPath = lookupPath.substring(0, index);
  +	    } 
  +	    else {
  +		// More ..'s than dirs, return null
  +		return null;
  +	    }
  +	    
  +	    index = path.indexOf("../") + 3;
  +	    path = path.substring(index);
  +	}
  +	
  +	return lookupPath + "/" + path;
  +    }
  +    
       public static String patch(String path) {
           String patchPath = path.trim();
  -
   
           // Move drive spec to the front of the path
           if (patchPath.length() >= 3 &&
  
  
  
  1.5       +10 -7     jakarta-tomcat/src/share/org/apache/tomcat/util/URLUtil.java
  
  Index: URLUtil.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/URLUtil.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- URLUtil.java	2000/01/08 15:34:29	1.4
  +++ URLUtil.java	2000/01/12 06:35:21	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/URLUtil.java,v 1.4 2000/01/08 15:34:29 costin Exp $
  - * $Revision: 1.4 $
  - * $Date: 2000/01/08 15:34:29 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/URLUtil.java,v 1.5 2000/01/12 06:35:21 costin Exp $
  + * $Revision: 1.5 $
  + * $Date: 2000/01/12 06:35:21 $
    *
    * ====================================================================
    *
  @@ -75,13 +75,16 @@
    */
   
   public class URLUtil {
  +
       public static URL resolve(String s)
  -    throws MalformedURLException {
  +	throws MalformedURLException
  +    {
           return resolve(s, null);
       }
   
       public static URL resolve(String s, URL url)
  -    throws MalformedURLException {
  +	throws MalformedURLException
  +    {
           URL resolve = null;
   
   	// construct a URL via the following heuristics:
  @@ -124,8 +127,8 @@
   
           if (! resolve.getProtocol().equalsIgnoreCase("war") &&
               resolve.getFile().toLowerCase().endsWith(
  -                "." + Constants.MIME.WAR)) {
  -            URL u = new URL(Constants.MIME.WAR + ":" +
  +                "." + "war")) {
  +            URL u = new URL("war" + ":" +
                   resolve.toString());
   
               resolve = u;
  
  
  
  1.3       +43 -3     jakarta-tomcat/src/share/org/apache/tomcat/util/WARUtil.java
  
  Index: WARUtil.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/WARUtil.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- WARUtil.java	1999/11/01 21:52:52	1.2
  +++ WARUtil.java	2000/01/12 06:35:21	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/WARUtil.java,v 1.2 1999/11/01 21:52:52 costin Exp $
  - * $Revision: 1.2 $
  - * $Date: 1999/11/01 21:52:52 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/WARUtil.java,v 1.3 2000/01/12 06:35:21 costin Exp $
  + * $Revision: 1.3 $
  + * $Date: 2000/01/12 06:35:21 $
    *
    * ====================================================================
    *
  @@ -64,6 +64,7 @@
   
   package org.apache.tomcat.util;
   
  +import org.apache.tomcat.core.*;
   import java.util.zip.ZipInputStream;
   import java.util.zip.ZipEntry;
   import java.io.File;
  @@ -129,4 +130,43 @@
   
           return s;
       }
  +
  +    
  +    /** Construct a URL from a base and a relative path
  +     */
  +    public static URL createURL( Context ctx, String mappedPath )
  +	throws MalformedURLException
  +    {
  +	// XXX need rework, we should remove war until we know better
  +	// or have an architecture for it
  +	URL docBase = ctx.getDocumentBase();
  +	URL url=null;
  +	if (ctx.isWARExpanded()) {
  +	    File f = new File(ctx.getWARDir().toString());
  +	    String absPath = f.getAbsolutePath();
  +	    
  +	    // take care of File.getAbsolutePath() troubles
  +	    // on jdk1.1.x/win
  +	    
  +	    absPath = FileUtil.patch(absPath);
  +	    
  +	    if (! absPath.startsWith("/")) {
  +		absPath = "/" + absPath;
  +	    }
  +	    
  +	    url = new URL("file://localhost" + absPath + "/" +
  +			  mappedPath);
  +	} else {
  +	    String documentBase = docBase.toString();
  +	    
  +	    if (documentBase.endsWith("/")) {
  +		documentBase = documentBase.substring(0,
  +						      documentBase.length() - 1);
  +	    }
  +	    
  +	    url = new URL(documentBase + "!" + mappedPath);
  +	}
  +	return url;
  +    }
  +    
   }