package com.teamkonzept.webman.mainint;
import com.teamkonzept.db.*;
import com.teamkonzept.lib.*;
import com.teamkonzept.webman.*;
import com.teamkonzept.web.*;
import com.teamkonzept.webman.db.*;
import com.teamkonzept.webman.mainint.events.*;
import java.util.Stack;
import java.sql.*;
/**
provides several Util methods for trees
* @author $Author: alex $
* @version $Revision: 1.5 $
*/
public class TreeUtils implements ParameterTypes
{
/**
* mischen zweier teilbaeume (zwei TKDBResults)
*
* @param
*/
public static TKDBResult mergeIntoTree( TKDBResult tree, TKDBResult branch, String whichNodeId ) throws Throwable
{
int i = 0;
int j = 0;
TKDBResult resTree = (TKDBResult) tree.clone();
resTree.removeAllElements();
TKDBResultRow treeRow = (tree==null)? null : (TKDBResultRow)(tree.get( i++ ));
TKDBResultRow branchRow = (branch==null)? null : (TKDBResultRow)(branch.get( j++ ));
while( true ) {
if( treeRow == null && branchRow == null ) { break; }
int treeLeft = getDBResultRowColumnVal( treeRow, "LEFT_NR" );
int branchLeft = getDBResultRowColumnVal( branchRow, "LEFT_NR" );
if( treeRow == null ) {
resTree.addElement( branchRow );
branchRow = (TKDBResultRow)(branch.get( j++ ));
}
else if( branchRow == null ) {
resTree.addElement( treeRow );
treeRow = (TKDBResultRow)(tree.get( i++ ));
}
else if( treeLeft == branchLeft ) {
int branchNodeId = getDBResultRowColumnVal( branchRow, "NODE_ID" );
int branchConNodeId = getDBResultRowColumnVal( branchRow, whichNodeId );
if( branchNodeId != branchConNodeId ) {
resTree.addElement( branchRow );
}
else {
resTree.addElement( treeRow );
}
treeRow = (TKDBResultRow)(tree.get( i++ ));
branchRow = (TKDBResultRow)(branch.get( j++ ));
}
else if( treeLeft < branchLeft ) {
resTree.addElement( treeRow );
treeRow = (TKDBResultRow)(tree.get( i++ ));
}
else if( treeLeft > branchLeft ) {
resTree.addElement( branchRow );
branchRow = (TKDBResultRow)(branch.get( j++ ));
}
}
return resTree;
}
/**
* ermitteln der maximalen tiefe eines baumes
*
* @param
*/
public static int getMaxDepth( TKDBResult tree, String treeName ) throws Throwable
{
int depth = 0;
int maxDepth = 0;
int lastLeft = -1;
int lastRight = -1;
int thisParent;
Stack parents = new Stack();
for(int i = 0; i < tree.size(); i++) {
TKDBResultRow resultRow = (TKDBResultRow)(tree.get( i ));
int thisLeft = Integer.parseInt( (String) resultRow.getColumn( "LEFT_NR" ) );
int thisRight = Integer.parseInt( (String) resultRow.getColumn( "RIGHT_NR" ) );
String tmp = (String) resultRow.getColumn( treeName+"_NODE_PARENT" );
thisParent = ( tmp == null || tmp.equals("") )?Integer.parseInt( (String) resultRow.getColumn( treeName+"_NODE_ID" ) ):Integer.parseInt( tmp );
if( thisLeft > lastLeft && thisRight < lastRight ) { // absteigen
depth++;
parents.push( new Integer( thisParent ) );
}
else if( !parents.empty() ) { // aufsteigen
if( !(parents.peek().equals( new Integer (thisParent))) ) {
while( !parents.empty() ) {
if( parents.pop().equals( new Integer( thisParent )) ) {
parents.push( new Integer( thisParent ) );
break;
}
depth--;
}
}
}
maxDepth = (depth >= maxDepth) ? depth : maxDepth;
lastLeft = thisLeft;
lastRight = thisRight;
}
return maxDepth;
}
/**
*
* lesen einer spalte einer TKDBResultRow und als int zurueck
*
* @param
*/
public static int getDBResultRowColumnVal( TKDBResultRow row, String name )
{
if( row != null ) {
String sVal = (String) row.getColumn( name );
if( sVal.equals( "" ) ) return -1;
int val = Integer.parseInt( sVal );
return val;
}
else return -1;
}
/**
* keepOpenNodes
*
* schleift Liste der offenen nodes durch: Lesen des Vectors und einsetzen ins templ.
*
* @param Template
*/
public static void keepOpenNodes(TKEvent evt, TKHTMLTemplate tmpl ) throws Throwable
{
TKVector openNodes = new TKVector();
if( evt.getParams().hasMultiple( PARAMETER, "OPEN_NODES" ) ) {
openNodes = evt.getParams().getVector( PARAMETER, "OPEN_NODES" );
}
else {
//openNodes.put( 0, evt.getParameter( PARAMETER, "OPEN_NODES" )==null?"-1":evt.getParameter( PARAMETER, "OPEN_NODES" ) );
openNodes.put( 0, evt.getParameter( PARAMETER, "OPEN_NODES" ) );
}
// die liste der offenen nodes kommt ins template
if( openNodes.get( 0 ) != null ) {
TKStandardIterator iterator1 = new TKStandardIterator( openNodes, tmpl.getListIterator(), "OPEN_NODES", "OPEN_NODES" );
tmpl.setListIterator( iterator1 );
}
}
/**
*
* CHECK fuers Schliessen oeder LOESCHEN
* liste von offenen nodes holen und fuer jeden offenen node checken, ob er kind
* des closeNodeId ist: ist er kind, dann raus aus der liste der offenen nodes
* openNodeId kommt dann zu der liste dazu
*
* CHECK fuers Oeffnen
* fuer den zu oeffnenden node nachsehen, ob er Kind eines schon offenen node
* ist, wenn ja, dann den schon offenen raus und schliesslich den neuen rein in die Liste
*
* @param
*/
public static TKVector updateOpenNodes( TKVector openNodes, String openNodeId, String closeNodeId, String me, Class isChildQuery ) throws Throwable
{
if( !closeNodeId.equals( "-1" ) )
{ // beim schliessen/loeschen checken, ob offene nodes vom
int size = openNodes.size(); // schliessen/loeschen des me betroffen sind
TKQuery q;
int i = 0;
while( i<size ) {
String id = (String) openNodes.get( i );
if( id!=null )
{
if (id.equals(me))
{
openNodes.removeElementAt( i );
size--;
}
else
{
q = TKDBManager.newQuery( isChildQuery );
q.setQueryParams( "PARENT_ID", new Integer(me) );
q.setQueryParams( "CHILD_ID", new Integer(id) );
q.execute();
ResultSet rs = q.fetchResultSet();
if( rs.next() ) {
int isChild = rs.getInt("ISCHILD");
if( isChild == 1 ) {
openNodes.removeElementAt( i ); // dieser knoten ist nach dem
size--; // schliessen nich mehr offen -> raus aus der liste
}
else {
i++;
}
}
}
}
}
}
else { // check beim Oeffnen: ist einer der offenen nodes Parent des openNodeId?
int size = openNodes.size();
TKQuery q;
int i = 0;
while( i<size ) {
String id = (String) openNodes.get( i );
if( id!=null ) {
q = TKDBManager.newQuery( isChildQuery );
q.setQueryParams( "PARENT_ID", new Integer(id) );
q.setQueryParams( "CHILD_ID", new Integer(openNodeId) );
q.execute();
ResultSet rs = q.fetchResultSet();
if( rs.next() ) {
int isChild = rs.getInt("ISCHILD");
if( isChild == 1 ) {
openNodes.removeElementAt( i ); // dieser knoten ist im gleichen Ast wie der zu oeffnende
size--;
}
else {
i++;
}
}
}
}
}
if( !openNodes.contains( openNodeId ) && openNodeId != null ) openNodes.addElement( openNodeId );
if( openNodes.size() >= 2 && openNodes.contains("-1") ) {
openNodes.removeElement("-1");
//log.println("------ entferne -1 -----");
}
return openNodes;
}
}
|