DbTreeWalker.java :  » Forum » nemesis-forum » org » nemesis » forum » impl » Java Open Source

Java Open Source » Forum » nemesis forum 
nemesis forum » org » nemesis » forum » impl » DbTreeWalker.java
/*
 * NEMESIS-FORUM.
 * Copyright (C) 2002  David Laurent(lithium2@free.fr). All rights reserved.
 * 
 * Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
 * 
 * Copyright (C) 2001 Yasna.com. All rights reserved.
 * 
 * Copyright (C) 2000 CoolServlets.com. All rights reserved.
 * 
 * NEMESIS-FORUM. is free software; you can redistribute it and/or
 * modify it under the terms of the Apache Software License, Version 1.1,
 * or (at your option) any later version.
 * 
 * NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
 * application are parts of NEMESIS-FORUM and are distributed under
 * same terms of licence.
 * 
 * 
 * NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
 * and software developed by CoolServlets.com (http://www.coolservlets.com).
 * and software developed by Yasna.com (http://www.yasna.com).
 * 
 */
package org.nemesis.forum.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nemesis.forum.Message;
import org.nemesis.forum.TreeWalker;
import org.nemesis.forum.util.jdbc.DbConnectionManager;
/**
 * Database implementation of the TreeWalker interface. This class is relatively
 * inefficient compared to how it will eventually be implemented. However,
 * a schema change is needed before that optimization is needed (represent
 * tree structure directly in schema).
 */
public class DbTreeWalker implements TreeWalker {
  static protected Log log = LogFactory.getLog(DbTreeWalker.class);
  /** DATABASE QUERIES **/
  private static final String GET_CHILD =
    "SELECT yazdMessageTree.childID, yazdMessage.creationDate FROM "
      + "yazdMessageTree, yazdMessage WHERE "
      + "yazdMessageTree.childID=yazdMessage.messageID AND "
      + "yazdMessageTree.parentID=? ORDER BY yazdMessage.creationDate";
  private static final String CHILD_COUNT = "SELECT count(*) FROM yazdMessageTree WHERE parentID=?";
  private static final String INDEX_OF_CHILD =
    "SELECT yazdMessageTree.childID, yazdMessage.creationDate "
      + "FROM yazdMessageTree, yazdMessage WHERE yazdMessageTree.childID=yazdMessage.messageID "
      + "AND yazdMessageTree.parentID=? ORDER BY yazdMessage.creationDate";
  
  private static final String GET_CHILD_APPROVED =
    "SELECT yazdMessageTree.childID, yazdMessage.creationDate FROM "
      + "yazdMessageTree, yazdMessage WHERE "
      + "yazdMessageTree.childID=yazdMessage.messageID AND "
      + "yazdMessageTree.parentID=? AND yazdMessage.approved=?  ORDER BY yazdMessage.creationDate";
  private static final String CHILD_COUNT_APPROVED = "SELECT count(*) FROM yazdMessageTree, yazdMessage WHERE yazdMessageTree.childID=yazdMessage.messageID AND yazdMessageTree.parentID=? AND yazdMessage.approved=? ";
  private static final String INDEX_OF_CHILD_APPROVED =
    "SELECT yazdMessageTree.childID, yazdMessage.creationDate "
      + "FROM yazdMessageTree, yazdMessage WHERE yazdMessageTree.childID=yazdMessage.messageID "
      + "AND yazdMessageTree.parentID=? AND yazdMessage.approved=?  ORDER BY yazdMessage.creationDate";


  private DbForumThread thread;
  private DbForumFactory factory;
  private boolean approved;
  private boolean filter=false;

  public DbTreeWalker(DbForumThread thread, DbForumFactory factory) {
    this.thread = thread;
    this.factory = factory;
  }
  
  public DbTreeWalker(boolean approved, DbForumThread thread, DbForumFactory factory) {
      this.thread = thread;
      this.factory = factory;
      this.approved=approved;
      this.filter=true;
  }

  /**
   * Returns the root of the tree. Returns null only if the tree has no nodes.
   *
   * @returns the root of the tree
   */
  public Message getRoot() {
    return thread.getRootMessage();
  }

  /**
   * Returns the child of parent at index index in the parent's child array.
   * This should not return null if index is a valid index for parent (that
   * is index >= 0 && index < getChildCount(parent)).
   *
   * @param parent the parent message.
   * @param index the index of the child.
   * @returns the child of parent at index.
   */
  public Message getChild(Message parent, int index) {
    Message message = null;
    Connection con = null;
    PreparedStatement pstmt = null;
    try {
      con = DbConnectionManager.getConnection();
      if(filter){
        pstmt = con.prepareStatement(GET_CHILD_APPROVED);
        pstmt.setInt(1, parent.getID());
        pstmt.setInt(2, approved ? 1:0);
      }  
      else{
        pstmt = con.prepareStatement(GET_CHILD);
        pstmt.setInt(1, parent.getID());
      }
        
      
      ResultSet rs = pstmt.executeQuery();
      while (rs.next() && index > 0) {
        index--;
      }
      if (index == 0) {
        int messageID = rs.getInt(1);
        message = thread.getMessage(messageID);
      }
    } catch (Exception e) {
      log.error("Error in DbMessageTreeWalker:getChild(" + index + ")-" , e);
      
    } finally {
      try {
        pstmt.close();
      } catch (Exception e) {
        log.error("" , e);
      }
      try {
        con.close();
      } catch (Exception e) {
        log.error("" , e);
      }
    }
    return message;
  }
  



  /**
   * Returns the number of children of parent. Returns 0 if the node is a
   * leaf or if it has no children.
   *
   * @param parent a node in the tree, obtained from this data source.
   * @returns the number of children of the node parent.
   */
  public int getChildCount(Message parent) {
    int childCount = 0;
    Connection con = null;
    PreparedStatement pstmt = null;
    try {
      con = DbConnectionManager.getConnection();
      
      if(filter){
        pstmt = con.prepareStatement(CHILD_COUNT_APPROVED);
        pstmt.setInt(1, parent.getID());
        pstmt.setInt(2, approved ? 1:0);
      }  
      else{
        pstmt = con.prepareStatement(CHILD_COUNT);
        pstmt.setInt(1, parent.getID());
      }
      
      ResultSet rs = pstmt.executeQuery();
      rs.next();
      childCount = rs.getInt(1);
    } catch (Exception e) {
      log.error("Error in DbTreeWalker:getChildCount()-" ,e);
      
    } finally {
      try {
        pstmt.close();
      } catch (Exception e) {
        log.error("" , e);
      }
      try {
        con.close();
      } catch (Exception e) {
        log.error("" , e);
      }
    }
    return childCount;
  }

  /**
   * Returns the total number of recursive children of a parent. Returns 0
   * if there are no children. This method is not intended to aid in
   * navigation of a Thread but is included as an added utility.
   */
  public int getRecursiveChildCount(Message parent) {
    int numChildren = 0;
    int num = getChildCount(parent);
    numChildren += num;
    for (int i = 0; i < num; i++) {
      Message child = getChild(parent, i);
      if (child != null) {
        numChildren += getRecursiveChildCount(child);
      }
    }
    return numChildren;
  }

  /**
   * Returns the index of child in parent.
   */
  public int getIndexOfChild(Message parent, Message child) {
    int index = 0;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
      con = DbConnectionManager.getConnection();
      
      if(filter){
        pstmt = con.prepareStatement(INDEX_OF_CHILD_APPROVED);
        pstmt.setInt(1, parent.getID());
        pstmt.setInt(2, approved ? 1:0);
      }  
      else{
        pstmt = con.prepareStatement(INDEX_OF_CHILD);
        pstmt.setInt(1, parent.getID());
      }
            
      
      rs = pstmt.executeQuery();
      while (rs.next()) {
        if (rs.getInt(1) == child.getID()) {
          break;
        }
        index++;
      }
    } catch (Exception e) {
      log.error("Error in DbTreeWalker:getIndexOfChild()-" , e);
    } finally {
      try {
        pstmt.close();
      } catch (Exception e) {
        log.error("" , e);
      }
      try {
        con.close();
      } catch (Exception e) {
        log.error("" , e);
      }
    }
    return index;
  }

  /**
   * Returns true if node is a leaf. A node is a leaf when it has no children
   * messages.
   *
   * @param node a node in the tree, obtained from this data source
   * @returns true if node is a leaf
   */
  public boolean isLeaf(Message node) {
    return (getChildCount(node) == 0);
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.