/* * 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.venice.ValidationException; import com.silverwrist.venice.core.*; import com.silverwrist.venice.servlets.format.*; public class ConfDisplay extends VeniceServlet { /*-------------------------------------------------------------------------------- * Internal class used to get post number defaults *-------------------------------------------------------------------------------- */ static class PostInterval { private int first; private int last; public PostInterval(int f, int l) { if (f<=l) { // the sort is good first = f; last = l; } // end if else { // reverse the order first = l; last = f; } // end else } // end constructor public int getFirst() { return first; } // end getFirst public int getLast() { return last; } // end getLast } // end class PostInterval /*-------------------------------------------------------------------------------- * Static data members *-------------------------------------------------------------------------------- */ private static Category logger = Category.getInstance(ConfDisplay.class.getName()); /*-------------------------------------------------------------------------------- * Internal functions *-------------------------------------------------------------------------------- */ private static SIGContext getSIGParameter(ServletRequest request, UserContext user) throws ValidationException, DataException { String str = request.getParameter("sig"); if (str==null) { // no SIG parameter - bail out now! logger.error("SIG parameter not specified!"); throw new ValidationException("No SIG specified."); } // end if try { // turn the string into a SIGID, and thence to a SIGContext int sigid = Integer.parseInt(str); return user.getSIGContext(sigid); } // end try catch (NumberFormatException nfe) { // error in Integer.parseInt logger.error("Cannot convert SIG parameter '" + str + "'!"); throw new ValidationException("Invalid SIG parameter."); } // end catch } // end getSIGParameter private static ConferenceContext getConferenceParameter(ServletRequest request, SIGContext sig) throws ValidationException, DataException, AccessError { String str = request.getParameter("conf"); if (str==null) { // no conference parameter - bail out now! logger.error("Conference parameter not specified!"); throw new ValidationException("No conference specified."); } // end if try { // turn the string into a ConfID, and thence to a ConferenceContext int confid = Integer.parseInt(str); return sig.getConferenceContext(confid); } // end try catch (NumberFormatException nfe) { // error in Integer.parseInt logger.error("Cannot convert conference parameter '" + str + "'!"); throw new ValidationException("Invalid conference parameter."); } // end catch } // end getConferenceParameter private static TopicContext getTopicParameter(ServletRequest request, ConferenceContext conf) throws ValidationException, DataException, AccessError { String str = request.getParameter("top"); if (StringUtil.isStringEmpty(str)) return null; // no topic specified try { // turn the string into a TopicID, and thence to a TopicContext short topicid = Short.parseShort(str); return conf.getTopic(topicid); } // end try catch (NumberFormatException nfe) { // error in Integer.parseInt logger.error("Cannot convert topic parameter '" + str + "'!"); throw new ValidationException("Invalid topic parameter."); } // end catch } // end getTopicParameter private static void getViewSortDefaults(ServletRequest request, int confid, TopicSortHolder tsc) throws ValidationException { String str = request.getParameter("view"); if (!(StringUtil.isStringEmpty(str))) { // we need to change the view parameter try { // convert the parameter to an integer and then check it against defined values int p = Integer.parseInt(str); switch (p) { case ConferenceContext.DISPLAY_NEW: case ConferenceContext.DISPLAY_ACTIVE: case ConferenceContext.DISPLAY_ALL: case ConferenceContext.DISPLAY_HIDDEN: case ConferenceContext.DISPLAY_ARCHIVED: tsc.setViewOption(confid,p); break; default: throw new ValidationException("Invalid view parameter."); } // end switch } // end try catch (NumberFormatException nfe) { // failure in parseInt logger.error("Cannot convert view parameter '" + str + "'!"); throw new ValidationException("Invalid view parameter."); } // end catch } // end if str = request.getParameter("sort"); if (!(StringUtil.isStringEmpty(str))) { // we need to change the sort parameter try { // convert the parameter to an integer and then check it against defined values int p = Integer.parseInt(str); int real_p = ((p<0) ? -p : p); switch (real_p) { case ConferenceContext.SORT_NUMBER: case ConferenceContext.SORT_NAME: case ConferenceContext.SORT_UNREAD: case ConferenceContext.SORT_TOTAL: case ConferenceContext.SORT_DATE: tsc.setSortOption(confid,p); break; default: throw new ValidationException("Invalid sort parameter."); } // end switch } // end try catch (NumberFormatException nfe) { // failure in parseInt logger.error("Cannot convert sort parameter '" + str + "'!"); throw new ValidationException("Invalid sort parameter."); } // end catch } // end if } // end getViewSortDefaults private static PostInterval getInterval(ServletRequest request, TopicContext topic) throws ValidationException { int first, last; String foo = request.getParameter("pxg"); if (!(StringUtil.isStringEmpty(foo))) { // we have a Go box parameter - try and decode it try { // look for a range specifier int p = foo.indexOf('-'); if (p<0) { // single post number - try and use it first = Integer.parseInt(foo); last = first; } // end if else if (p==0) { // "-number" - works like "0-number" last = Integer.parseInt(foo.substring(1)); first = 0; } // end if else if (p==(foo.length()-1)) { // "number-" - works like "number-end" first = Integer.parseInt(foo.substring(0,p)); last = topic.getTotalMessages() - 1; } // end else if else { // two numbers to decode first = Integer.parseInt(foo.substring(0,p)); last = Integer.parseInt(foo.substring(p+1)); } // end else return new PostInterval(first,last); } // end try catch (NumberFormatException nfe) { // if numeric conversion fails, just fall out and try to redisplay the other way } // end catch } // end if foo = request.getParameter("p1"); if (StringUtil.isStringEmpty(foo)) { // no range specified - cook up a default one last = topic.getTotalMessages(); int ur = topic.getUnreadMessages(); if ((ur==0) || (ur>=20)) // TODO: configurable first = last - 20; else first = last - (ur+2); last--; } // end if else { // we have at least one parameter... try { // convert it to an integer and range-limit it first = Integer.parseInt(foo); if (first<0) first = 0; else if (first>=topic.getTotalMessages()) first = topic.getTotalMessages() - 1; } // end try catch (NumberFormatException nfe) { // we could not translate the parameter to a number throw new ValidationException("Message parameter is invalid."); } // end catch foo = request.getParameter("p2"); if (StringUtil.isStringEmpty(foo)) last = first; // just specify ONE post... else { // OK, we have an actual "last message" parameter... try { // convert it to an integer and range-limit it last = Integer.parseInt(foo); if ((last<0) || (last>=topic.getTotalMessages())) last = topic.getTotalMessages() - 1; } // end try catch (NumberFormatException nfe) { // we could not translate the parameter to a number throw new ValidationException("Message parameter is invalid."); } // end catch } // end else } // end else return new PostInterval(first,last); } // end getInterval /*-------------------------------------------------------------------------------- * Overrides from class HttpServlet *-------------------------------------------------------------------------------- */ public String getServletInfo() { String rc = "ConfDisplay servlet - Display of conference topic and message lists\n" + "Part of the Venice Web Communities System\n"; return rc; } // end getServletInfo public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { UserContext user = getUserContext(request); RenderData rdat = createRenderData(request,response); String page_title = null; Object content = null; SIGContext sig = null; // SIG context ConferenceContext conf = null; // conference context TopicContext topic = null; // topic context try { // this outer try is to catch ValidationException try { // all commands require a SIG parameter sig = getSIGParameter(request,user); changeMenuSIG(request,sig); if (logger.isDebugEnabled()) logger.debug("found SIG #" + String.valueOf(sig.getSIGID())); } // end try catch (DataException de) { // error looking up the SIG page_title = "Database Error"; content = new ErrorBox(page_title,"Database error finding SIG: " + de.getMessage(),"top"); } // end catch if (content==null) { // we got the SIG parameter OK try { // all commands require a conference parameter conf = getConferenceParameter(request,sig); if (logger.isDebugEnabled()) logger.debug("found conf #" + String.valueOf(conf.getConfID())); } // end try catch (DataException de) { // error looking up the conference page_title = "Database Error"; content = new ErrorBox(page_title,"Database error finding conference: " + de.getMessage(),"top"); } // end catch } // end if if (content==null) { // we got the conference parameter OK try { // there's an optional topic parameter topic = getTopicParameter(request,conf); if (logger.isDebugEnabled()) { // do a little debugging output if (topic!=null) logger.debug("found topic #" + String.valueOf(topic.getTopicID())); else logger.debug("no topic specified"); } // end if } // end try catch (DataException de) { // error looking up the conference page_title = "Database Error"; content = new ErrorBox(page_title,"Database error finding topic: " + de.getMessage(),"top"); } // end catch } // end if } // end try catch (ValidationException ve) { // these all get handled in pretty much the same way page_title = "Error"; content = new ErrorBox(null,ve.getMessage(),"top"); } // end catch catch (AccessError ae) { // these all get handled in pretty much the same way page_title = "Access Error"; content = new ErrorBox(page_title,ae.getMessage(),"top"); } // end catch if (content==null) { // OK, let's handle the display now if (topic!=null) { // we're handling messages within a single topic if (logger.isDebugEnabled()) logger.debug("MODE: display messages in topic"); try { // determine what the post interval is we want to display PostInterval piv = getInterval(request,topic); boolean read_new = !(StringUtil.isStringEmpty(request.getParameter("rnm"))); boolean show_adv = !(StringUtil.isStringEmpty(request.getParameter("shac"))); // create the post display TopicPosts tpos = new TopicPosts(request,sig,conf,topic,piv.getFirst(),piv.getLast(), read_new,show_adv); content = tpos; page_title = topic.getName() + ": " + String.valueOf(topic.getTotalMessages()) + " Total; " + String.valueOf(tpos.getNewMessages()) + " New; Last: " + rdat.formatDateForDisplay(topic.getLastUpdateDate()); } // end try catch (ValidationException ve) { // there's an error in the parameters somewhere page_title = "Error"; content = new ErrorBox(null,ve.getMessage(),"top"); } // end catch catch (DataException de) { // there was a database error retrieving topics page_title = "Database Error"; content = new ErrorBox(page_title,"Database error listing messages: " + de.getMessage(),"top"); } // end catch catch (AccessError ae) { // we were unable to retrieve the topic list page_title = "Access Error"; content = new ErrorBox(page_title,ae.getMessage(),"top"); } // end catch } // end if else { // we're displaying the conference's topic list if (logger.isDebugEnabled()) logger.debug("MODE: display topics in conference"); TopicSortHolder opts = TopicSortHolder.retrieve(request.getSession(true)); try { // get any changes to view or sort options getViewSortDefaults(request,conf.getConfID(),opts); // create the topic list content = new TopicListing(request,sig,conf,opts.getViewOption(conf.getConfID()), opts.getSortOption(conf.getConfID())); page_title = "Topics in " + conf.getName(); } // end try catch (ValidationException ve) { // there was some sort of a parameter error in the display page_title = "Error"; content = new ErrorBox(null,ve.getMessage(),"top"); } // end catch catch (DataException de) { // there was a database error retrieving topics page_title = "Database Error"; content = new ErrorBox(page_title,"Database error listing topics: " + de.getMessage(),"top"); } // end catch catch (AccessError ae) { // we were unable to retrieve the topic list page_title = "Access Error"; content = new ErrorBox(page_title,ae.getMessage(),"top"); } // end catch } // end else } // end if BaseJSPData basedat = new BaseJSPData(page_title,"confdisp?" + request.getQueryString(),content); basedat.transfer(getServletContext(),rdat); } // end doGet } // end class ConfDisplay