|
What this is
Other links
The source code
/**
* CSTreeBean.java
* Version 0.3, September 12, 2000
*
* Copyright (C) 2000 CoolServlets.com. All rights reserved.
*
* Derived from CoolServlets tree classes. Maintainer: Kevin Sangeelee
*
* ===================================================================
* The Apache Software License, Version 1.1
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* CoolServlets.com (http://www.coolservlets.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Jive" and "CoolServlets.com" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact webmaster@coolservlets.com.
*
* 5. Products derived from this software may not be called "Jive",
* nor may "Jive" appear in their name, without prior written
* permission of CoolServlets.com.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL COOLSERVLETS.COM OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of CoolServlets.com. For more information
* on CoolServlets.com, please see <http://www.coolservlets.com>.
*/
package com.coolservlets.beans;
import java.sql.*;
import java.util.*;
import javax.servlet.http.*;
import com.coolservlets.beans.tree.*;
/**
* A CSTreeBean is a server-side JSP JavaBean that generates trees populated from a JDBC
* data source, and renders the trees as HTML. State information is maintained using URI
* parameters.
*/
public class CSTreeBean {
private static Hashtable trees = new Hashtable();
private Hashtable openNodes = new Hashtable(); // holds an easy-lookup of open nodes while rendering HTML
private String jdbcDriver;
private String jdbcURL;
private String jdbcUser;
private String jdbcPassword;
private String treeName; // unique name of this tree
private String tableName; // name of the (denormalised) table or view
private String labelCols; // comma separated list of columns that hold labels
private String urlCols; // comma separated list of corresponding urls
private String whereClause = "";
private String treePage; // Which page to send tree URL links to
private String leafPage; // Which page to send tree leaf links to
private String leafTarget; // Which frame to send non-tree URL links to
private String openImage="fldo.gif"; // image for open nodes
private String closedImage="fldc.gif"; // image for closed nodes
private String leafImage="rgn.gif"; // image for leaf nodes
private String treeStyle; // Text style of the table
private int open = 0; // Passed by URL to this bean stating which node to open (or close)
private int absopen; // what - no abs()??
private String oldopen = ""; // Automatically maintained URL parameter listing open nodes
private boolean reload = false;
// Getter and Setter methods
public String getJdbcDriver() { return this.jdbcDriver; }
public void setJdbcDriver(String str) { this.jdbcDriver = str; }
public String getJdbcURL() { return this.jdbcURL; }
public void setJdbcURL(String str) { this.jdbcURL = str; }
public String getJdbcUser() { return this.jdbcUser; }
public void setJdbcUser(String str) { this.jdbcUser = str; }
public String getJdbcPassword() { return this.jdbcPassword; }
public void setJdbcPassword(String str) { this.jdbcPassword = str; }
public String getLabelCols() { return this.labelCols; }
public void setLabelCols(String str) { this.labelCols = str; }
public String getUrlCols() { return this.urlCols; }
public void setUrlCols(String str) { this.urlCols = str; }
public String getTreeName() { return this.treeName; }
public void setTreeName(String str) { this.treeName = str; }
public String getTableName() { return this.tableName; }
public void setTableName(String str) { this.tableName = str; }
public String getWhereClause() { return this.whereClause; }
public void setWhereClause(String str) { this.whereClause = str; }
//public String get() { return this.; }
//public void set(String str) { this. = str; }
public String getTreePage() { return treePage; }
public void setTreePage(String treePage) { this.treePage = treePage; }
public String getLeafPage() { return leafPage; }
public void setLeafPage(String leafPage) { this.leafPage = leafPage; }
public String getLeafTarget() { return leafTarget; }
public void setLeafTarget(String leafTarget) { this.leafTarget = leafTarget; }
public String getTreeStyle() { return treeStyle; }
public void setTreeStyle(String treeStyle) { this.treeStyle = treeStyle; }
public int getOpen() { return open; }
public void setOpen(int open) { this.open = open; absopen = open < 0 ? -open : open; }
public String getOldopen() { return oldopen; }
public void setOldopen(String oldopen) { this.oldopen = oldopen; }
public boolean getReload() { return reload; }
public void setReload(boolean reload) { this.reload = reload; }
public void setOpenImage(String str) { this.openImage = str; }
public void setClosedImage(String str) { this.closedImage = str; }
public void setLeafImage(String str) { this.leafImage = str; }
// Now on to the real stuff...
/**
* Populates the tree specified in the bean parameter 'treeName', or the default tree
* if none was specified. The trees are held statically in a Hashtable, keyed on the tree
* name.
*
* A tree is populated from a denormalised table or a view using JDBC. Ordinarily, this operation
* happens only once when the tree is first accessed.
*
* This method should probably be reorganised to lend itself more to populating from sources other
* than JDBC.
*/
public synchronized boolean populateJdbc() {
boolean sqlerror = false;
/** Try to get the named tree from the Hashtable. If no name is provided, use 'default'.
If a tree matches, then it must already be populated.
*/
if(treeName == null || treeName.length() == 0) {
treeName = "default";
}
if(trees.get(treeName) != null && reload == false) {
return true; // already populated
}
System.out.println("Populating tree from the database.");
// Get a database connection
Connection con = null;
try {
Class.forName(jdbcDriver);
con = DriverManager.getConnection (jdbcURL, jdbcUser, jdbcPassword);
}
catch(ClassNotFoundException e) {
System.out.println(e.toString());
return false;
}
catch(SQLException e) {
System.out.println(e.toString());
return false;
}
String[] labelColumns = csvToArray(labelCols);
String[] urlColumns = csvToArray(urlCols);
String[] labels = new String[30]; // hardwired maximum depth of 30 levels (!!)
String[] urls = new String[30]; // hardwired maximum depth of 30 levels (!!)
TreeNode tn[] = new TreeNode[30];
int nodeID = 1;
Tree root;
root = new Tree("root");
TreeNode node = null;
try {
Statement stmt = con.createStatement();
StringBuffer sql = new StringBuffer(300);
sql.append("select distinct ").append(labelCols).append(",").append(urlCols);
sql.append(" from ").append(tableName);
sql.append(" ").append(whereClause).append(" order by ").append(labelCols);
ResultSet rs = stmt.executeQuery( sql.toString() );
int i,j = 0;
while(rs.next()) { // iterate through the denormalised view
/** This reading of a 'line' has been decoupled from the main populating logic below
* so that different types of data source can be added.
*/
for(i=0; i < labelColumns.length; i++) { // for each column
if(((labels[i] = rs.getString(labelColumns[i]))) == null || labels[i].length() == 0)
break;
if((urls[i] = rs.getString(urlColumns[i])) != null && urls[i].length() == 0)
urls[i] = null; // force empty url columns to null for easy testing later...
}
for(j=0; j < i-1; j++) {
if(tn[j] == null || !labels[j].equals(tn[j].getName())) { // then this is the first or a new item
tn[j] = new TreeNode(nodeID++, labels[j], urls[j]);
if(j > 0)
tn[j-1].addChild(tn[j]);
else
root.addChild(tn[j]);
continue;
}
}
if(j > 0)
tn[j-1].addChild( new TreeLeaf( labels[j], urls[j]) );
else
root.addChild(new TreeLeaf(labels[j],urls[j]));
}
trees.put(treeName, root); // Store the tree in the static Hashtable
} catch(SQLException e) {
System.out.println(e.toString());
sqlerror = true;
}
try {
con.close();
}
catch(SQLException ignored) {}
return !sqlerror;
}
/**
* This method is just a call to the method below with a null argument, meaning that the tree
* shouldn't get it's state from the session.
*/
public final String renderHTML() {
return renderHTML((HttpServletRequest)null);
}
/**
* This method first of all builds a Hashtable of open nodes from the request parameter
* for easy lookup later. It then submits the root node of the tree named in the bean
* parameter 'treeName' (or the default tree) for rendering as HTML. If a HttpServletRequest
* is supplied, the method will try to obtain '<treeName>.oldopen' from the session.
*/
public final String renderHTML( HttpServletRequest req ) {
if(populateJdbc() == false) { // ensures the tree is populated
return "<p>The CDTreeBean has not been successfully initialised. Check the server's stdout for details.";
}
// Try to obtain 'oldopen' from the session if a request object was passed
if(req != null) {
HttpSession s = req.getSession(false);
String tmp = s != null ? (String)s.getAttribute(treeName + ".oldopen") : null;
if(tmp != null && tmp.length() > 0)
oldopen = tmp;
}
// Make a hash table of the currently open nodes (from the URL parameter)
StringTokenizer st = new StringTokenizer(oldopen, ":");
String token;
while(st.hasMoreElements()) {
try {
token = st.nextToken();
openNodes.put(Integer.valueOf(token), token);
// strb.append(token).append(":");
} catch(NumberFormatException e) {
System.out.println("Warning: TreeBean was passed dodgy parameters!");
}
}
// now add the requested node to the open list (if not a close-request)
if(open >= 0) {
openNodes.put(new Integer(open), String.valueOf(open));
// strb.append(open);
} else {
openNodes.remove(new Integer(-open));
}
StringBuffer strb = new StringBuffer();
Enumeration on = openNodes.elements();
while(on.hasMoreElements()) {
strb.append(on.nextElement()).append(":");
}
this.oldopen = strb.toString();
// Try to write 'oldopen' to the session if a request object was passed
if(req != null) {
HttpSession s = req.getSession(false);
if(s != null)
s.setAttribute(treeName + ".oldopen", oldopen);
}
StringBuffer html = new StringBuffer(renderHTML((Tree)trees.get(treeName)));
return html.toString();
}
private boolean isVisible(TreeNode node) {
if(openNodes.containsKey(new Integer(node.getId())))
return true;
return false;
}
/**
* Renders the specified tree as HTML by iterating over all it's children. Will call itself
* recursively for any visible node children.
*/
private final String renderHTML(Tree tree) {
StringBuffer buf = new StringBuffer();
buf.append("\n<TABLE border=\"0\"");
if(treeStyle != null && treeStyle.length() > 0)
buf.append(" class=\"").append(treeStyle).append("\"");
buf.append(">\n");
for( int i=0; i < tree.size(); i++ ) {
TreeObject treeObject = tree.getChild(i);
if( treeObject.getType() == Tree.NODE ) {
TreeNode node = (TreeNode)treeObject;
buf.append( renderNodeHTML(node) );
if( isVisible(node) ) {
buf.append("<tr> | " ); String link = node.getLink(); if( link != null ) { buf.append( "<a href='"); if(leafPage != null && leafPage.length() > 0) // if a leafPage is specified, then prepend to the link buf.append(leafPage); buf.append(link).append("' "); if(leafTarget != null && leafTarget.length() > 0) buf.append("target='").append(leafTarget).append("'"); buf.append(">" ).append( node.getName() ).append( "</a>" ); } else { buf.append( node.getName() ); } buf.append( "</td>" ); return buf.toString(); } /** * Renders the specified tree leaf as HTML. */ private final String renderLeafHTML( TreeLeaf leaf ) { StringBuffer buf = new StringBuffer(); buf.append( "<tr> | ").append(" | " ); return buf.toString(); } /** * Accepts a comma separated list of tokens and returns them as a string array. */ private String[] csvToArray(String csv) { StringTokenizer st = new StringTokenizer(csv,","); String[] buf = new String[st.countTokens()]; int i = 0; while(st.hasMoreTokens()) buf[i++] = st.nextToken(); return buf; } public String adjustScrollPosition() { // return "<SCRIPT> window.location.href=\"#A\"; if(window.scrollTo) scrollTo(0,(document.body ? document.body.scrollTop : pageYOffset) - 20); "; return "<SCRIPT> window.location.href=\"#A\"; window.scroll(0, -20); "; } } |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.