/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at .
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox ,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.servlets;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.util.ServletMultipartHandler;
import com.silverwrist.util.ServletMultipartException;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.servlets.format.*;
public abstract class VeniceServlet extends HttpServlet
{
/*--------------------------------------------------------------------------------
* Static data values
*--------------------------------------------------------------------------------
*/
private static final String LOCATION_ATTR = "com.silverwrist.venice.servlets.internal.Location";
private static Category logger = Category.getInstance(VeniceServlet.class.getName());
/*--------------------------------------------------------------------------------
* Internal functions
*--------------------------------------------------------------------------------
*/
private static final void notSupported(HttpServletRequest request, String message) throws ErrorResult
{
String protocol = request.getProtocol();
if (protocol.endsWith("1.1"))
throw new ErrorResult(HttpServletResponse.SC_METHOD_NOT_ALLOWED,message);
else
throw new ErrorResult(HttpServletResponse.SC_BAD_REQUEST,message);
} // end notSupported
private static final SIGContext getSIGParameter(String str, UserContext user, boolean required,
String on_error) throws ErrorBox
{
if (StringUtil.isStringEmpty(str))
{ // there's no SIG parameter
if (required)
{ // no SIG parameter - bail out now!
logger.error("SIG parameter not specified!");
throw new ErrorBox(null,"No SIG specified.",on_error);
} // end if
else
{ // a null SIGContext is permitted
logger.debug("no SIG specified");
return null;
} // end else
} // end if
SIGContext rc = null;
try
{ // turn the string into a SIGID, and thence to a SIGContext
int tmp_id = Integer.parseInt(str);
rc = user.getSIGContext(tmp_id);
if (rc==null)
{ // trap any null results (may not be possible with SIGs, but you never know)
logger.error("SIG #" + tmp_id + " was not found!");
throw new ErrorBox(null,"The specified SIG (#" + tmp_id + ") was not found in the database.",on_error);
} // end if
if (logger.isDebugEnabled())
logger.debug("found SIG #" + rc.getSIGID());
} // end try
catch (NumberFormatException nfe)
{ // error in Integer.parseInt
logger.error("Cannot convert SIG parameter '" + str + "'!");
throw new ErrorBox(null,"Invalid SIG parameter.",on_error);
} // end catch
catch (DataException de)
{ // error looking up the SIG
throw new ErrorBox("Database Error","Database error finding SIG: " + de.getMessage(),on_error);
} // end catch
return rc;
} // end getSIGParameter
private static TopicContext getTopicParameter(String str, ConferenceContext conf, boolean required,
String on_error) throws ErrorBox
{
if (StringUtil.isStringEmpty(str))
{ // there's no topic parameter
if (required)
{ // no topic parameter - bail out now!
logger.error("Topic parameter not specified!");
throw new ErrorBox(null,"No topic specified.",on_error);
} // end if
else
{ // a null TopicContext is permitted
logger.debug("no topic specified");
return null;
} // end else
} // end if
TopicContext rc = null;
try
{ // turn the string into a topic number, and thence to a TopicContext
short tmp_id = Short.parseShort(str);
rc = conf.getTopic(tmp_id);
if (rc==null)
{ // the topic was not found!
logger.error("ConfID #" + conf.getConfID() + " did not have topic #" + tmp_id);
throw new ErrorBox(null,"Topic #" + tmp_id + " was not found in the '" + conf.getName()
+ "' conference.",on_error);
} // end if
if (logger.isDebugEnabled())
logger.debug("found topic #" + rc.getTopicID());
} // end try
catch (NumberFormatException nfe)
{ // error in Integer.parseInt
logger.error("Cannot convert topic parameter '" + str + "'!");
throw new ErrorBox(null,"Invalid topic parameter.",on_error);
} // end catch
catch (AccessError ae)
{ // these all get handled in pretty much the same way
throw new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
catch (DataException de)
{ // error looking up the topic
throw new ErrorBox("Database Error","Database error finding topic: " + de.getMessage(),"top");
} // end catch
return rc;
} // end getTopicParameter
private static TopicMessageContext getMessageParameter(String str, ConferenceContext conf, boolean required,
String on_error) throws ErrorBox
{
if (StringUtil.isStringEmpty(str))
{ // there's no message parameter
if (required)
{ // no message parameter - bail out now!
logger.error("Message parameter not specified!");
throw new ErrorBox(null,"No message specified.",on_error);
} // end if
else
{ // a null TopicMessageContext is permitted
logger.debug("no message specified");
return null;
} // end else
} // end if
TopicMessageContext rc = null;
try
{ // turn the string into a postid, and thence to a TopicMessageContext
long tmp_id = Long.parseLong(str);
rc = conf.getMessageByPostID(tmp_id);
if (rc==null)
{ // the message was not found
logger.error("ConfID #" + conf.getConfID() + " does not contain postid " + tmp_id);
throw new ErrorBox(null,"The post with ID number " + tmp_id + " was not found in the '"
+ conf.getName() + "' conference.",on_error);
} // end if
if (logger.isDebugEnabled())
logger.debug("found post #" + rc.getPostID());
} // end try
catch (NumberFormatException nfe)
{ // error in Integer.parseInt
logger.error("Cannot convert message parameter '" + str + "'!");
throw new ErrorBox(null,"Invalid message parameter.",on_error);
} // end catch
catch (AccessError ae)
{ // these all get handled in pretty much the same way
throw new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
catch (DataException de)
{ // error looking up the conference
throw new ErrorBox("Database Error","Database error finding message: " + de.getMessage(),on_error);
} // end catch
return rc;
} // end getMessageParameter
private static TopicMessageContext getMessageParameter(String str, TopicContext topic, boolean required,
String on_error) throws ErrorBox
{
if (StringUtil.isStringEmpty(str))
{ // there's no message parameter
if (required)
{ // no message parameter - bail out now!
logger.error("Message parameter not specified!");
throw new ErrorBox(null,"No message specified.",on_error);
} // end if
else
{ // a null TopicMessageContext is permitted
logger.debug("no message specified");
return null;
} // end else
} // end if
TopicMessageContext rc = null;
try
{ // turn the string into a post number, and thence to a TopicMessageContext
int tmp_id = Integer.parseInt(str);
rc = topic.getMessage(tmp_id);
if (rc==null)
{ // could not find the message
logger.error("TopicID " + topic.getTopicID() + " does not contain message #" + tmp_id);
throw new ErrorBox(null,"There is no message #" + tmp_id + " in the '" + topic.getName() + "' topic.",
on_error);
} // end if
if (logger.isDebugEnabled())
logger.debug("found post #" + rc.getPostID());
} // end try
catch (NumberFormatException nfe)
{ // error in Integer.parseInt
logger.error("Cannot convert message parameter '" + str + "'!");
throw new ErrorBox(null,"Invalid message parameter.",on_error);
} // end catch
catch (AccessError ae)
{ // these all get handled in pretty much the same way
throw new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
catch (DataException de)
{ // error looking up the conference
throw new ErrorBox("Database Error","Database error finding message: " + de.getMessage(),on_error);
} // end catch
return rc;
} // end getMessageParameter
/*--------------------------------------------------------------------------------
* Internal operations intended for use by derived classes
*--------------------------------------------------------------------------------
*/
protected static final boolean isImageButtonClicked(ServletRequest request, String name)
{
String val = request.getParameter(name + ".x");
return (val!=null);
} // end isImageButtonClicked
protected final void putUserContext(HttpServletRequest request, UserContext ctxt)
{
Variables.putUserContext(request.getSession(true),ctxt);
} // end putUserContext
protected final void clearUserContext(HttpServletRequest request)
{
Variables.clearUserContext(request.getSession(true));
} // end clearUserContext
protected static final List getCountryList(ServletContext ctxt) throws ServletException
{
return Variables.getCountryList(ctxt);
} // end getCountryList
protected final List getCountryList() throws ServletException
{
return Variables.getCountryList(getServletContext());
} // end getCountryList
protected final List getLanguageList(ServletContext ctxt) throws ServletException
{
return Variables.getLanguageList(ctxt);
} // end getLanguageList
protected final List getLanguageList() throws ServletException
{
return Variables.getLanguageList(getServletContext());
} // end getLanguageList
protected final void changeMenuTop(HttpServletRequest request)
{
Variables.setMenuTop(getServletContext(),request.getSession(true));
} // end changeMenuTop
protected final void changeMenuSIG(HttpServletRequest request, SIGContext sig)
{
Variables.setMenuSIG(request.getSession(true),sig);
} // end changeMenuSIG
protected final void clearMenu(HttpServletRequest request)
{
Variables.clearMenu(request.getSession(true));
} // end clearMenu
protected final String getStandardCommandParam(ServletRequest request)
{
String foo = request.getParameter("cmd");
if (foo==null)
return "???";
else
return foo;
} // end getStandardCommandParam
protected final void setMyLocation(ServletRequest request, String loc)
{
request.setAttribute(LOCATION_ATTR,loc);
} // end setMyLocation
protected final static SIGContext getSIGParameter(ServletRequest request, UserContext user, boolean required,
String on_error) throws ErrorBox
{
return getSIGParameter(request.getParameter("sig"),user,required,on_error);
} // end getSIGParameter
protected final static SIGContext getSIGParameter(ServletMultipartHandler mphandler, UserContext user,
boolean required, String on_error) throws ErrorBox
{
if (mphandler.isFileParam("sig"))
throw new ErrorBox(null,"Internal Error: SIG should be a normal param",on_error);
return getSIGParameter(mphandler.getValue("sig"),user,required,on_error);
} // end getSIGParameter
protected static ConferenceContext getConferenceParameter(String str, SIGContext sig, boolean required,
String on_error) throws ErrorBox
{
if (StringUtil.isStringEmpty(str))
{ // there's no conference parameter
if (required)
{ // no conference parameter - bail out now!
logger.error("Conference parameter not specified!");
throw new ErrorBox(null,"No conference specified.",on_error);
} // end if
else
{ // a null ConferenceContext is permitted
logger.debug("no conference specified");
return null;
} // end else
} // end if
ConferenceContext rc = null;
try
{ // turn the string into a ConfID, and thence to a ConferenceContext
int tmp_id = Integer.parseInt(str);
rc = sig.getConferenceContext(tmp_id);
if (rc==null)
{ // couldn't find the conference
logger.error("SIG #" + sig.getSIGID() + " does not contain conference #" + tmp_id);
throw new ErrorBox(null,"The conference #" + tmp_id + " could not be found in the '" + sig.getName()
+ "' SIG.",on_error);
} // end if
if (logger.isDebugEnabled())
logger.debug("found conf #" + rc.getConfID());
} // end try
catch (NumberFormatException nfe)
{ // error in Integer.parseInt
logger.error("Cannot convert conference parameter '" + str + "'!");
throw new ErrorBox(null,"Invalid conference parameter.",on_error);
} // end catch
catch (AccessError ae)
{ // these all get handled in pretty much the same way
throw new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
catch (DataException de)
{ // error looking up the conference
throw new ErrorBox("Database Error","Database error finding conference: " + de.getMessage(),on_error);
} // end catch
return rc;
} // end getConferenceParameter
protected final static ConferenceContext getConferenceParameter(ServletRequest request, SIGContext sig,
boolean required, String on_error)
throws ErrorBox
{
return getConferenceParameter(request.getParameter("conf"),sig,required,on_error);
} // end getConferenceParameter
protected final static ConferenceContext getConferenceParameter(ServletMultipartHandler mphandler,
SIGContext sig, boolean required,
String on_error) throws ErrorBox
{
if (mphandler.isFileParam("conf"))
throw new ErrorBox(null,"Internal Error: conference should be a normal param",on_error);
return getConferenceParameter(mphandler.getValue("conf"),sig,required,on_error);
} // end getConferenceParameter
protected final static TopicContext getTopicParameter(ServletRequest request, ConferenceContext conf,
boolean required, String on_error) throws ErrorBox
{
return getTopicParameter(request.getParameter("top"),conf,required,on_error);
} // end getTopicParameter
protected final static TopicContext getTopicParameter(ServletMultipartHandler mphandler,
ConferenceContext conf, boolean required,
String on_error) throws ErrorBox
{
if (mphandler.isFileParam("top"))
throw new ErrorBox(null,"Internal Error: topic should be a normal param",on_error);
return getTopicParameter(mphandler.getValue("top"),conf,required,on_error);
} // end getTopicParameter
protected final static TopicMessageContext getMessageParameter(ServletRequest request,
ConferenceContext conf, boolean required,
String on_error) throws ErrorBox
{
return getMessageParameter(request.getParameter("msg"),conf,required,on_error);
} // end getMessageParameter
protected final static TopicMessageContext getMessageParameter(ServletMultipartHandler mphandler,
ConferenceContext conf, boolean required,
String on_error) throws ErrorBox
{
if (mphandler.isFileParam("msg"))
throw new ErrorBox(null,"Internal Error: message should be a normal param",on_error);
return getMessageParameter(mphandler.getValue("msg"),conf,required,on_error);
} // end getMessageParameter
protected final static TopicMessageContext getMessageParameter(ServletRequest request, TopicContext topic,
boolean required, String on_error)
throws ErrorBox
{
return getMessageParameter(request.getParameter("msg"),topic,required,on_error);
} // end getMessageParameter
protected final static TopicMessageContext getMessageParameter(ServletMultipartHandler mphandler,
TopicContext topic, boolean required,
String on_error) throws ErrorBox
{
if (mphandler.isFileParam("msg"))
throw new ErrorBox(null,"Internal Error: message should be a normal param",on_error);
return getMessageParameter(mphandler.getValue("msg"),topic,required,on_error);
} // end getMessageParameter
/*--------------------------------------------------------------------------------
* Overrideable operations
*--------------------------------------------------------------------------------
*/
protected String getMyLocation(HttpServletRequest request, VeniceEngine engine, UserContext user,
RenderData rdat)
{
return (String)(request.getAttribute(LOCATION_ATTR));
} // end getMyLocation
protected VeniceContent doVeniceGet(HttpServletRequest request, VeniceEngine engine,
UserContext user, RenderData rdat)
throws ServletException, IOException, VeniceServletResult
{
notSupported(request,"GET method not supported");
return null;
} // end doVeniceGet
protected VeniceContent doVenicePost(HttpServletRequest request, VeniceEngine engine,
UserContext user, RenderData rdat)
throws ServletException, IOException, VeniceServletResult
{
notSupported(request,"POST method not supported for normal form posts");
return null;
} // end doVenicePost
protected VeniceContent doVenicePost(HttpServletRequest request, ServletMultipartHandler mphandler,
VeniceEngine engine, UserContext user, RenderData rdat)
throws ServletException, IOException, VeniceServletResult
{
notSupported(request,"POST method not supported for multipart/form-data posts");
return null;
} // end doVenicePost
/*--------------------------------------------------------------------------------
* Overrides from class HttpServlet
*--------------------------------------------------------------------------------
*/
public final void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
ServletContext ctxt = getServletContext();
VeniceEngine engine = Variables.getVeniceEngine(ctxt);
VeniceContent content = null;
// Make all log messages for the request carry the remote address.
NDC.push(request.getRemoteAddr());
try
{ // get the user context
UserContext user = Variables.getUserContext(ctxt,request,request.getSession(true));
boolean record_uname = user.isLoggedIn();
if (record_uname)
NDC.push(user.getUserName());
try
{ // and now we proceed!
RenderData rdat = RenderConfig.createRenderData(ctxt,user,request,response);
try
{ // run the actual "get" in the servlet
content = doVeniceGet(request,engine,user,rdat);
} // end try
catch (VeniceServletResult res)
{ // special VeniceServletResult catch here - figure out what result it is
if (res instanceof VeniceContent)
content = (VeniceContent)res; // this is content
else if (res instanceof ContentResult)
{ // this contains content
ContentResult cres = (ContentResult)res;
content = cres.getContent();
} // end else if
else if (res instanceof ExecuteResult)
{ // direct-execution result
ExecuteResult xres = (ExecuteResult)res;
Variables.flushCookies(request,response);
xres.execute(rdat);
return;
} // end else if
else // unrecognized VeniceServletResult
content = null;
} // end catch
catch (RuntimeException re)
{ // record that we caught a runtime exception in here!
logger.error("VeniceServlet.doGet caught " + re.getClass().getName() + " in doVeniceGet",re);
throw re;
} // end catch
Variables.flushCookies(request,response);
if (content!=null)
{ // display the content!
BaseJSPData base = new BaseJSPData(getMyLocation(request,engine,user,rdat),content);
base.transfer(ctxt,rdat);
} // end if
else // there is no content - display the null response
rdat.nullResponse();
} // end try
finally
{ // pop the username from the NDC if we used it
if (record_uname)
NDC.pop();
} // end finally
} // end try
finally
{ // pop the nested diagnostic context
NDC.pop();
} // end finally
} // end doGet
public final void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
ServletContext ctxt = getServletContext();
VeniceEngine engine = Variables.getVeniceEngine(ctxt);
ServletMultipartHandler mphandler = null;
VeniceContent content = null;
// Make all log messages for the request carry the remote address.
NDC.push(request.getRemoteAddr());
try
{ // get the user context
UserContext user = Variables.getUserContext(ctxt,request,request.getSession(true));
boolean record_uname = user.isLoggedIn();
if (record_uname)
NDC.push(user.getUserName());
try
{ // and now we proceed!
RenderData rdat = RenderConfig.createRenderData(ctxt,user,request,response);
if (ServletMultipartHandler.canHandle(request))
{ // if this is a multipart/form-data request, invoke our special handler code
try
{ // create the multipart handler
mphandler = new ServletMultipartHandler(request);
} // end try
catch (ServletMultipartException e)
{ // this is an error message we need to generate and just bail out on
logger.error("ServletMultipartException caught in doVenicePost!",e);
BaseJSPData base = new BaseJSPData(getMyLocation(request,engine,user,rdat),
new ErrorBox(null,"Internal Error: " + e.getMessage(),null));
base.transfer(ctxt,rdat);
return;
} // end if
} // end if
try
{ // call the appropriate doVenicePost method
if (mphandler!=null)
content = doVenicePost(request,mphandler,engine,user,rdat);
else
content = doVenicePost(request,engine,user,rdat);
} // end try
catch (VeniceServletResult res)
{ // special VeniceServletResult catch here - figure out what result it is
if (res instanceof VeniceContent)
content = (VeniceContent)res; // this is content
else if (res instanceof ContentResult)
{ // this contains content
ContentResult cres = (ContentResult)res;
content = cres.getContent();
} // end else if
else if (res instanceof ExecuteResult)
{ // direct-execution result
ExecuteResult xres = (ExecuteResult)res;
Variables.flushCookies(request,response);
xres.execute(rdat);
return;
} // end else if
else // unrecognized VeniceServletResult
content = null;
} // end catch
catch (RuntimeException re)
{ // record that we caught a runtime exception in here!
logger.error("VeniceServlet.doPost caught " + re.getClass().getName() + " in doVenicePost",re);
throw re;
} // end catch
Variables.flushCookies(request,response);
if (content!=null)
{ // display the content!
BaseJSPData base = new BaseJSPData(getMyLocation(request,engine,user,rdat),content);
base.transfer(ctxt,rdat);
} // end if
else // there is no content - display the null response
rdat.nullResponse();
} // end try
finally
{ // pop the username from the NDC if we used it
if (record_uname)
NDC.pop();
} // end finally
} // end try
finally
{ // pop the nested diagnostic context
NDC.pop();
} // end finally
} // end doPost
} // end class VeniceServlet