/*
* ServletFactory.java
*
*
* Copyright (c) 2003 Rimfaxe ApS (www.rimfaxe.com).
* All rights reserved.
*
* This package is written by Lars Andersen <lars@rimfaxe.com>
* and licensed by Rimfaxe ApS.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by Rimfaxe ApS
(www.rimfaxe.com)"
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "Rimfaxe", "Rimfaxe Software", "Lars Andersen" and
* "Rimfaxe WebServer" must not be used to endorse or promote products
* derived from this software without prior written permission. For written
* permission, please contact info@rimfaxe.com
*
* 5. Products derived from this software may not be called "Rimfaxe"
* nor may "Rimfaxe" appear in their names without prior written
* permission of the Rimfaxe ApS.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
package com.rimfaxe.webserver.servletapi;
import java.util.*;
import com.rimfaxe.webserver.VirtualHost;
import com.rimfaxe.webserver.WebContext;
import com.rimfaxe.webserver.servletapi.jsp.*;
import com.rimfaxe.webserver.servletapi.RimfaxeFilterConfig;
/**
*
* @author Lars Andersen
*/
public class ServletFactory
{
HashMap servlet_wrappers = new HashMap();
HashMap filters = new HashMap();
// Static includes to force linking in binary
private static Class c1 = javax.servlet.GenericServlet.class;
private static Class c2 = javax.servlet.ServletConfig.class;
//
static ServletFactory instance = null;
/** Creates a new instance of ServletFactory */
public ServletFactory()
{
}
public static ServletFactory getInstance()
{
if (instance==null)
{
instance = new ServletFactory();
}
return instance;
}
public com.rimfaxe.webserver.servletapi.ServletWrapper getWrapper(VirtualHost vh, WebContext webcontext, String name, String cls, String urlpath, com.rimfaxe.webserver.webapp.Servlet servlet_def)
{
//System.out.println("ServletFactory, get ServletWrapper");
int res = 0;
String pretty_name = name;
String pretty_class = cls;
if ( (!name.equalsIgnoreCase("jsp")) && (!name.equalsIgnoreCase("invoker")) && (!name.equalsIgnoreCase("default")) )
{
com.rimfaxe.webserver.servletapi.ServletWrapper sw =
(com.rimfaxe.webserver.servletapi.ServletWrapper) servlet_wrappers.get("servlet__"+vh.getName()+"__"+webcontext.getUrlpath()+"__"+name);
if ( sw!=null )
{
System.out.println("Get used ServletWrapper -> "+"servlet__"+vh.getName()+"__"+webcontext.getUrlpath()+"__"+name);
return sw;
}
}
JSPhandler jsphandler = null;
JSPclass jsp_class = null;
if ( (name.equalsIgnoreCase("jsp")) )
{
//System.out.println("ServletFactory, JSP ServletWrapper");
jsphandler = new JSPhandler();
jsp_class = jsphandler.getServletClass(vh, webcontext, urlpath);
if (jsp_class!=null)
{
com.rimfaxe.webserver.servletapi.ServletWrapper sw =
(com.rimfaxe.webserver.servletapi.ServletWrapper) servlet_wrappers.get("jsp__"+vh.getName()+"__"+webcontext.getUrlpath()+"__"+jsp_class.getFullClassName());
if ( sw!=null )
{
//System.out.println("Get used JSP ServletWrapper -> "+""+jsp_class.getFullClassName());
return sw;
}
}
}
if ( (name.equalsIgnoreCase("invoker")) )
{
String invoker_class = servletInvoker(urlpath);
com.rimfaxe.webserver.servletapi.ServletWrapper sw =
(com.rimfaxe.webserver.servletapi.ServletWrapper) servlet_wrappers.get("invoker__"+vh.getName()+"__"+webcontext.getUrlpath()+"__"+invoker_class);
if ( sw!=null )
{
//System.out.println("Get used invoker ServletWrapper");
return sw;
}
}
if ( (name.equalsIgnoreCase("default")) )
{
com.rimfaxe.webserver.servletapi.ServletWrapper sw =
(com.rimfaxe.webserver.servletapi.ServletWrapper) servlet_wrappers.get("default__"+vh.getName()+"__"+webcontext.getUrlpath());
if ( sw!=null )
{
//System.out.println("Get used default ServletWrapper");
return sw;
}
}
RimfaxeServletConfig rsc = new RimfaxeServletConfig(name,webcontext.getServletContext(), servlet_def);
com.rimfaxe.webserver.servletapi.ServletWrapper swrap = new com.rimfaxe.webserver.servletapi.ServletWrapper( rsc );
StringBuffer msg = new StringBuffer();
// Is this a JSP page
if (cls.equalsIgnoreCase("nativeJSP"))
{
if (jsp_class==null)
{
res=3;
rsc.setInitParameter("com.rimfaxe.error_found", "JSP page not found");
msg.append("Error opening JSP page <b>"+urlpath+"</b> <br>");
msg.append("JSP page <b>"+urlpath+"</b> could not be found. <br>");
}
else
{
//System.out.println("JSP error = "+jsp_class.getError());
if (jsp_class.getError()>0) // JSP Not Found
{
res=2;
if (jsp_class.getError()==jsp_class.JSP_ERROR)
{
rsc.setInitParameter("com.rimfaxe.error_found", "JSP compile error");
msg.append("Error compiling JSP page <b>"+urlpath+"</b> <br>");
}
if (jsp_class.getError()==jsp_class.COMPILE_ERROR)
{
rsc.setInitParameter("com.rimfaxe.error_found", "JSP compile error");
msg.append("Error compiling JSP page <b>"+urlpath+"</b> <br>");
}
else if (jsp_class.getError()==jsp_class.LINK_ERROR)
{
rsc.setInitParameter("com.rimfaxe.error_found", "JSP link error");
msg.append("Error linking JSP page <b>"+urlpath+"</b> <br>");
}
else if (jsp_class.getError()==jsp_class.EXECUTION_ERROR)
{
rsc.setInitParameter("com.rimfaxe.error_found", "JSP execution error");
msg.append("Error executing JSP page <b>"+urlpath+"</b> <br>");
}
msg.append( jsp_class.getErrorMsg() );
}
else
{
cls = jsp_class.getFullClassName();
pretty_class = cls;
swrap.setServletClass(cls);
res = swrap.getError();
if (res==0)
servlet_wrappers.put("jsp__"+vh.getName()+"__"+webcontext.getUrlpath()+"__"+cls, swrap);
}
}
}
// Is this the standard servlet invoker
else if (cls.equalsIgnoreCase("nativeInvokerServlet"))
{
cls = servletInvoker(urlpath);
pretty_class = cls;
swrap.setServletClass(cls);
res = swrap.getError();
if (res==1) // ClassNotFound
{
rsc.setInitParameter("com.rimfaxe.error_found", "Servlet class not found");
msg.append("Error running servlet <b>"+pretty_name+"</b> <br>");
msg.append("Servlet class <b>"+pretty_class+"</b> could not be found. <br>");
}
if (res==0)
servlet_wrappers.put("invoker__"+vh.getName()+"__"+webcontext.getUrlpath()+"__"+cls, swrap);
}
// Is this the standard servlet invoker
else if (cls.equalsIgnoreCase("nativeDefaultServlet"))
{
swrap.setServletClass("com.rimfaxe.webserver.servletapi.DefaultServlet");
res = swrap.getError();
if (res==1) // ClassNotFound
{
rsc.setInitParameter("com.rimfaxe.error_found", "Servlet class not found");
msg.append("Error running servlet <b>nativeDefaultServlet</b> <br>");
msg.append("Servlet class <b>nativeDefaultServlet</b> not found. <br>");
}
if (res==0)
servlet_wrappers.put("default__"+vh.getName()+"__"+webcontext.getUrlpath(), swrap);
}
else
{
swrap.setServletClass(cls);
res = swrap.getError();
if (res==1) // ClassNotFound
{
rsc.setInitParameter("com.rimfaxe.error_found", "Servlet class not found");
msg.append("Error running servlet <b>"+pretty_name+"</b> <br>");
msg.append("Servlet class <b>"+pretty_class+"</b> not found. <br>");
}
if (res==0)
servlet_wrappers.put("servlet__"+vh.getName()+"__"+webcontext.getUrlpath()+"__"+name, swrap);
}
if (res>0)
{
rsc.setInitParameter("com.rimfaxe.error_msg", ""+msg);
swrap.setServletClass("com.rimfaxe.webserver.servletapi.standard.ErrorServlet");
}
return swrap;
}
public void loadServlet(String name, WebContext webcontext, com.rimfaxe.webserver.webapp.Servlet servlet_def)
{
RimfaxeServletConfig rsc = new RimfaxeServletConfig(name,webcontext.getServletContext(), servlet_def);
com.rimfaxe.webserver.servletapi.ServletWrapper swrap = new com.rimfaxe.webserver.servletapi.ServletWrapper( rsc );
swrap.setServletClass(servlet_def.getClassName());
//servlet_wrappers.put("servlet__"+vh.getName()+"__"+webcontext.getUrlpath()+"__"+name,swrap);
}
public String servletInvoker(String urlpath)
{
//System.out.println("Extract servletname from "+urlpath);
String cls = "unknown";
StringTokenizer tkz = new StringTokenizer(urlpath,"/?&",true);
while (tkz.hasMoreTokens())
{
String tmp = tkz.nextToken();
if (tmp.equalsIgnoreCase("/"))
{
}
else if (tmp.equalsIgnoreCase("?"))
{
return cls;
}
else
{
cls = tmp;
}
}
//System.out.println("Extract servletname "+cls);
return cls;
}
public javax.servlet.Filter getFilterInstance(WebContext webcontext, com.rimfaxe.webserver.webapp.Filter filter_desc)
{
String id = "filter_"+webcontext.getVirtualHost().getName()+"_"+webcontext.getName()+"_"+filter_desc.getKey();
javax.servlet.Filter filter = null;
try
{
filter = (javax.servlet.Filter) this.filters.get(id);
}
catch (Exception e)
{}
if (filter!=null)
{
System.out.println("Reuse filter = "+id);
}
else
{
try
{
RimfaxeFilterConfig rfc = new RimfaxeFilterConfig(filter_desc.getKey(), webcontext.getServletContext(), filter_desc);
filter = (javax.servlet.Filter) Class.forName(filter_desc.getClassName()).newInstance();
filter.init(rfc);
filters.put(id, filter);
}
catch (ClassNotFoundException cnfe)
{
System.out.println("Filter, ClassNotFound : "+filter_desc.getClassName());
}
catch (Exception e)
{
System.out.println("Filter, Exception -> "+e);
}
}
return filter;
}
}