/* * 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); /*-------------------------------------------------------------------------------- * Internal functions *-------------------------------------------------------------------------------- */ private static void getViewSortDefaults(ServletRequest request, int confid, TopicSortHolder tsc, String on_error) throws ErrorBox { 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 ErrorBox(null,"Invalid view parameter.",on_error); } // end switch } // end try catch (NumberFormatException nfe) { // failure in parseInt logger.error("Cannot convert view parameter '" + str + "'!"); throw new ErrorBox(null,"Invalid view parameter.",on_error); } // 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 ErrorBox(null,"Invalid sort parameter.",on_error); } // end switch } // end try catch (NumberFormatException nfe) { // failure in parseInt logger.error("Cannot convert sort parameter '" + str + "'!"); throw new ErrorBox(null,"Invalid sort parameter.",on_error); } // end catch } // end if } // end getViewSortDefaults private static PostInterval getInterval(VeniceEngine engine, ServletRequest request, TopicContext topic, String on_error) throws ErrorBox { 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>=engine.getNumPostsPerPage())) first = last - engine.getNumPostsPerPage(); else first = last - (ur + engine.getNumOldPostsBeforeNew()); 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 ErrorBox(null,"Message parameter is invalid.",on_error); } // 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 ErrorBox(null,"Message parameter is invalid.",on_error); } // end catch } // end else } // end else return new PostInterval(first,last); } // end getInterval private static boolean restorePosts(ServletRequest request, ConferenceContext conf, TopicContext curr_topic) { String xtopic = request.getParameter("rtop"); if (StringUtil.isStringEmpty(xtopic)) return true; String xcount = request.getParameter("rct"); if (StringUtil.isStringEmpty(xcount)) return true; TopicContext topic; try { // get the topic corresponding to the first parameter topic = conf.getTopic(Short.parseShort(xtopic)); } // end try catch (NumberFormatException nfe) { // the topic number was invalid - forget it logger.warn("restorePosts: error translating topic number"); return true; } // end catch catch (DataException de) { // could not get the topic... logger.warn("restorePosts: DataException getting topic - " + de.getMessage(),de); return true; } // end catch catch (AccessError ae) { // no access to the topic logger.warn("restorePosts: AccessError getting topic - " + ae.getMessage(),ae); return true; } // end catch int nunread; try { // translate the number of unread posts to set nunread = Integer.parseInt(xcount); if ((nunread<=0) || (nunread>topic.getTotalMessages())) { // must be in the range [1, #messages]... logger.warn("restorePosts: unread post count out of range"); return true; } // end if } // end try catch (NumberFormatException nfe) { // the number of unread posts was invalid - forget it logger.warn("restorePosts: error translating unread post count"); return true; } // end catch try { // now try to set the unread messages topic.setUnreadMessages(nunread); } // end try catch (DataException de) { // could not get the topic... logger.warn("restorePosts: DataException setting unread messages - " + de.getMessage(),de); } // end catch return (topic.getTopicID()!=curr_topic.getTopicID()); } // end restorePosts /*-------------------------------------------------------------------------------- * 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 /*-------------------------------------------------------------------------------- * Overrides from class VeniceServlet *-------------------------------------------------------------------------------- */ protected VeniceContent doVeniceGet(HttpServletRequest request, VeniceEngine engine, UserContext user, RenderData rdat) throws ServletException, IOException, VeniceServletResult { // get the SIG SIGContext sig = getSIGParameter(request,user,true,"top"); changeMenuSIG(request,sig); // get the conference ConferenceContext conf = getConferenceParameter(request,sig,true,"top"); // get the topic, if we have it TopicContext topic = getTopicParameter(request,conf,false,"top"); if (topic!=null) { // we're handling messages within a single topic if (logger.isDebugEnabled()) logger.debug("MODE: display messages in topic"); String on_error = "confdisp?sig=" + sig.getSIGID() + "&conf=" + conf.getConfID(); setMyLocation(request,on_error + "&topic=" + topic.getTopicNumber()); // if this request is restoring the number of unread posts in another topic, try to do so boolean do_readnew = restorePosts(request,conf,topic); // determine what the post interval is we want to display PostInterval piv = getInterval(engine,request,topic,on_error); boolean read_new = do_readnew && !(StringUtil.isStringEmpty(request.getParameter("rnm"))); boolean show_adv = !(StringUtil.isStringEmpty(request.getParameter("shac"))); // Create the post display. TopicPosts tpos = null; try { // create the display tpos = new TopicPosts(request,engine,sig,conf,topic,piv.getFirst(),piv.getLast(),read_new,show_adv); } // end try catch (DataException de) { // there was a database error retrieving messages return new ErrorBox("Database Error","Database error listing messages: " + de.getMessage(),on_error); } // end catch catch (AccessError ae) { // we were unable to retrieve the message list return new ErrorBox("Access Error",ae.getMessage(),on_error); } // end catch return tpos; } // end if (messages in a topic) else { // we're displaying the conference's topic list if (logger.isDebugEnabled()) logger.debug("MODE: display topics in conference"); String on_error = "confops?sig=" + sig.getSIGID(); String my_location = "confdisp?sig=" + sig.getSIGID() + "&conf=" + conf.getConfID(); boolean read_new = !(StringUtil.isStringEmpty(request.getParameter("rnm"))); if (read_new) my_location += "&rn=1"; setMyLocation(request,my_location); // get any changes to view or sort options TopicSortHolder opts = TopicSortHolder.retrieve(request.getSession(true)); getViewSortDefaults(request,conf.getConfID(),opts,on_error); if (read_new) { // we need to generate a TopicPosts view TopicPosts tpos = null; try { // generate a topic list first List topic_list = conf.getTopicList(opts.getViewOption(conf.getConfID()), opts.getSortOption(conf.getConfID())); // now generate the topic visit order TopicVisitOrder ord = TopicVisitOrder.initialize(request.getSession(true),conf.getConfID(), topic_list); // use the new visit order to get the topic we need to visit short topic_nbr = ord.getNext(); Iterator it = topic_list.iterator(); while (it.hasNext()) { // locate the first topic to be read topic = (TopicContext)(it.next()); if (topic.getTopicNumber()==topic_nbr) break; } // end while if (topic==null) // no suitable topic found - just create the topic listing return new TopicListing(request,sig,conf,opts.getViewOption(conf.getConfID()), opts.getSortOption(conf.getConfID())); // determine what the post interval is we want to display PostInterval piv = getInterval(engine,request,topic,on_error); // create the topic posts view return new TopicPosts(request,engine,sig,conf,topic,piv.getFirst(),piv.getLast(),true,false); } // end try catch (DataException de) { // there was a database error retrieving messages return new ErrorBox("Database Error","Database error listing messages: " + de.getMessage(),on_error); } // end catch catch (AccessError ae) { // we were unable to retrieve the message list return new ErrorBox("Access Error",ae.getMessage(),on_error); } // end catch } // end if (creating a "read new" topic list view) else { // topic listing only... TopicListing tl = null; try { // create the topic lict tl = new TopicListing(request,sig,conf,opts.getViewOption(conf.getConfID()), opts.getSortOption(conf.getConfID())); } // end try catch (DataException de) { // there was a database error retrieving topics return new ErrorBox("Database Error","Database error listing topics: " + de.getMessage(),on_error); } // end catch catch (AccessError ae) { // we were unable to retrieve the topic list return new ErrorBox("Access Error",ae.getMessage(),on_error); } // end catch return tl; } // end else (not reading new messages, but just displaying topics) } // end else (topics in a conference) } // end doVeniceGet } // end class ConfDisplay