Note: Robocode Repository is now back up on a temporary server until the new Rails-based site is ready.
Source: Bots List: PageBean
//  $RCSfile: BotList.java,v $
// $Revision: 1.4 $
//     $Date: 2001/09/08 21:18:01 $
//   $Author: dan $
//   Company: Developer Forge
// Copyright: Copyright (c) 2001


package com.robocode.apps.repository.pagebeans;

import java.net.URLEncoder;
import java.sql.*;
import java.util.Date;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import com.df.lang.reflect.PropertyCache;
import com.df.servlet.*;
import com.df.servlet.jsp.*;
import com.df.servlet.jsp.table.*;
import com.df.text.property.validator.*;
import com.df.util.DateUtils;
import com.robocode.servlet.jsp.*;
import com.robocode.sql.RoboCodeDatabaseUtil;


/**
 *  The BotList class implements the action methods associated with the buttons
 *  on the the BotList.jsp page.  This class also performs the logic associated
 *  with validating the fields on the page and performing their associated
 *  actions.
 *
 *  Updates:
 *    09/02/2001  1.0.0  Dan Lynn
 *      Created the BotList PageBean class.
 *    09/13/2001  1.0.1  Dan Lynn
 *      Fixed bug where I was revalidating the request parameters upon every
 *      page access.  This was causing the validation state to be reset when
 *      bounced back by a validation failure.  Now, I just read the request
 *      params upon the page access when the user types the URL or a bookmark
 *      is used to access the page.
 *
 *  @version  1.0.1 09/13/2001
 *  @author   Dan Lynn
 */


public class BotList extends DefaultPageBean {

  // instance properties -------------------------------------------------------
  private String botName = "";
  private String authorName = "";
  private String uploadDate = "";
  private int downloads = 0;
  private boolean loginState = false;

  // component properties - - - - - - - - - - - - - - - - - - - - - - - - - - -
  /** caches the data for the results table */
  private JdbcHtmlTableModel results = null;


  // constructors --------------------------------------------------------------
  /**
   *  Constructs a new instance of BotList.
   *
   *  @return	  new instance of BotList class
   */
  public BotList() {
    super();
    addPropertyValidator(new DateValidator(), "uploadDate", "search");
//		rememberProperties("botName,authorName,uploadDate,loginState");
  }


  // getters/setters -----------------------------------------------------------
  public void setBotName(String botName) {
    this.botName = botName;
  }
  public String getBotName() {
    return botName;
  }

  public void setAuthorName(String authorName) {
    this.authorName = authorName;
  }
  public String getAuthorName() {
    return authorName;
  }

  public void setUploadDate(String uploadDate) {
    this.uploadDate = uploadDate;
  }
  public String getUploadDate() {
    return uploadDate;
  }

  public int getDownloads() {
    return downloads;
  }
  public void setDownloads(int downloads) {
    this.downloads = downloads;
  }

  public boolean getLoginState() {
    return loginState;
  }
  public void setLoginState(boolean loginState) {
    this.loginState = loginState;
  }

  // component getters/setters - - - - - - - - - - - - - - - - - - - - - - - - -
  public JdbcHtmlTableModel getResults() {
    return results;
  }


  // instance methods ----------------------------------------------------------
  /**
   *  Populate the results list based upon the current search criteria before
   *  the JSP page is rendered.  Performs processing upon entry into this page
   *  from ANY page including this page (in case looping back for next record
   *  or such).
   *
   *  @param      controller    reference to the Controller associated with this
   *                            web application
   *  @param      pageContext   gives access to the current JSP's PageContext
   *  @param      samePage      true is this page is the same as the last page -
   *                            else false (based on HistoryPage title)
   *  @return     false if further processing of the JSP page should terminate -
   *              else true
   */
  public boolean pageAccess(
    final Controller controller,
    PageContext pageContext,
    boolean samePage
  ) throws Exception {
    System.out.println("BotList.pageAccess()");

    // if REFERER header is null then pageAccess() is the result of a bookmark
    //   thus, validate and store any request params into PageBean properties.
    //   Note that validating the properties clears any other validation results.
    //   But, since we only validate upon a typed URL or bookmark we don't have
    //   to worry about erasing the validation messages caused by bouncing back
    //   to this page via a validation failure.
    if (ServletUtils.getReferer(pageContext) == null)
      PageBeanUtils.validateAndSetAllProperties(controller, pageContext, this, "search");

    // if the preceeding validation failed then clear and skip query
    if (!isValid()) {
      results.clear();      // clear previous results
      forgetProperties();   // clear previously remembered filter criteria
      return true;  // skip performing query on invalid search criteria
    }

    // define/create custom 'results' JdbcHtmlTableModel if doesn't already exist
    if (results == null) {
      results = new JdbcHtmlTableModel() {
        public String getLinkAt(int row, String name) {
          if ("authorName".equals(name))
            return "BotList.jsp?authorName="+URLEncoder.encode((String)results.getValueAt(row, "authorName"));
          return "BotDetail.jsp?id="+results.getValueAt(row, "id");
        }
        public Object getValueAt(int row, String name) {
          if (name.equalsIgnoreCase("uploadDate")) {
            Object uploadDateObj = super.getValueAt(row, "uploadDate");
            if ("".equals(uploadDateObj))
              return "Not Uploaded";
            return DateUtils.formattedDateString((java.sql.Timestamp)uploadDateObj, "MM-dd-yy");
          }
          else if (name.equalsIgnoreCase("downloads")) {  // gets value of date because downloads will default to zero
            Object uploadDateObj = super.getValueAt(row, "uploadDate");
            if ("".equals(uploadDateObj))
              return "Not Uploaded";
          }
          return super.getValueAt(row, name);
        }
        public void rowPopulated(int row) { // adds to traversal list for use by TrackList.jsp page
          controller.addListPage((String)results.getLinkAt(row, null), (String)results.getValueAt(row, "botName"));
        }
      };
    }

    // track loginState property so that we can refresh when it changes
    setLoginState(controller.isLoggedIn());

    // populate the results list if search criteria have changed
    if (havePropertiesChanged()) {
      // create a ResultSet then populate the results list with it
      String query = null;
      if (((JspController)controller).isAdmin()) {  // is Admin (implies logged-in)
        query = "select BOTS.ID,BOTNAME,USERNAME AUTHORNAME,UPLOADDATE,DOWNLOADS "+
          "from BOTS,USERS "+
          "where AUTHORUSERID=USERS.ID and BOTNAME like ? and USERNAME like ? ";
      }
      else {  // not Admin
        if (controller.isLoggedIn())  // is Logged-in
          query = "select distinct BOTS.ID,BOTNAME,USERNAME AUTHORNAME,UPLOADDATE,DOWNLOADS "+
            "from BOTS,USERS,BOTSGROUPS,USERSGROUPS "+
            "where AUTHORUSERID=USERS.ID and BOTNAME like ? and USERNAME like ? "+
            "and BOTSGROUPS.BOTID=BOTS.ID and BOTSGROUPS.GROUPID=USERSGROUPS.GROUPID "+
            "and USERSGROUPS.USERID="+((JspController)controller).getUserId()+" ";
        else  // not Logged-in
          query = "select distinct BOTS.ID,BOTNAME,USERNAME AUTHORNAME,UPLOADDATE,DOWNLOADS "+
            "from BOTS,USERS,BOTSGROUPS,GROUPS "+
            "where AUTHORUSERID=USERS.ID and BOTNAME like ? and USERNAME like ? "+
            "and BOTSGROUPS.BOTID=BOTS.ID and BOTSGROUPS.GROUPID=GROUPS.ID "+
            "and GROUPS.GROUPNAME='Public' ";
      }
      if (uploadDate != null && !"".equals(uploadDate))
        query += "and UPLOADDATE >= ? ";
//      System.out.println("  query="+query);
      Connection connection = RoboCodeDatabaseUtil.getConnection();
      PreparedStatement preparedStatement = connection.prepareStatement(query);
      preparedStatement.setString(1, "%"+botName+"%");
      preparedStatement.setString(2, "%"+authorName+"%");
      if (uploadDate!=null && !"".equals(uploadDate))
        preparedStatement.setDate(3, DateUtils.covertDateUtilToSQL(DateUtils.parse(uploadDate)));
      controller.clearListPages();  // clear previous traversal list for UserDetail page
      results.populate(preparedStatement.executeQuery());
      connection.close(); // return to pool

      rememberProperties("botName,authorName,uploadDate,loginState");
    } // end if (search criteria changed)
    return true;  // continue processing
  } // end pageAccess()


  // action methods - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  /**
   *  Action method that redirects to the detail page with an 'id=0' request
   *  parameter.  The detail page recognizes this as a being a request to
   *  display a blank form so that a new item may be entered.
   *
   *  @param      controller    reference to the Controller associated with this
   *                            web application
   *  @param      pageContext   gives access to the current JSP's PageContext
   *  @return     false to signify that further processing of the controller JSP
   *              page should terminate
   */
  public boolean newBot(Controller controller, PageContext pageContext) throws java.io.IOException {
    System.out.println("BotList.newBot()");
    ((HttpServletResponse)pageContext.getResponse()).sendRedirect("BotDetail.jsp?id=0");
    return false;
  }


  /**
   *  Action method to be executed when the 'Search' button is clicked in the
   *  JSP page.  Since the PageBean framework automatically assigns the form
   *  fields to this PageBean's properties, this method simply builds an URL
   *  based upon the search criteria fields then redirects to it.  Thus, the
   *  browser's URL will contain the search criteria in case this search is
   *  bookmarked.
   *
   *  @param      controller    reference to the Controller associated with this
   *                            web application
   *  @param      pageContext   gives access to the current JSP's PageContext
   *  @return     false to signify that further processing of the controller JSP
   *              page should terminate
   */
  public boolean search(Controller controller, PageContext pageContext) throws java.io.IOException, java.lang.reflect.InvocationTargetException, java.lang.IllegalAccessException {
    System.out.println("BotList.search()");
    // build URL so that it can be bookmarked (actually don't need the request params for page to work)
    String urlStr = "BotList.jsp";
    urlStr = ServletUtils.addParamToURL(urlStr, "botName", botName);
    urlStr = ServletUtils.addParamToURL(urlStr, "authorName", authorName);
    urlStr = ServletUtils.addParamToURL(urlStr, "uploadDate", uploadDate);
    ((HttpServletResponse)pageContext.getResponse()).sendRedirect(urlStr);
    return false;
  }

} // end BotList class