📄 mtree.java
字号:
/******************************************************************************
* The contents of this file are subject to the Compiere License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.compiere.org/license.html
* 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 Compiere ERP & CRM Smart Business Solution. The Initial
* Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke
* are Copyright (C) 1999-2005 Jorg Janke.
* All parts are Copyright (C) 1999-2005 ComPiere, Inc. All Rights Reserved.
* Contributor(s): ______________________________________.
*****************************************************************************/
package org.compiere.model;
import java.awt.*;
import java.sql.*;
import java.util.*;
import java.util.logging.*;
import javax.sql.*;
import org.compiere.print.*;
import org.compiere.util.*;
/**
* Builds Tree.
* Creates tree structure - maintained in VTreePanel
*
* @author Jorg Janke
* @version $Id: MTree.java,v 1.38 2005/10/26 00:37:41 jjanke Exp $
*/
public class MTree extends MTree_Base
{
/**
* Default Constructor.
* Need to call loadNodes explicitly
* @param ctx context for security
* @param AD_Tree_ID The tree to build
*/
public MTree (Properties ctx, int AD_Tree_ID, String trxName)
{
super (ctx, AD_Tree_ID, trxName);
} // MTree
/**
* Construct & Load Tree
* @param AD_Tree_ID The tree to build
* @param editable True, if tree can be modified
* - includes inactive and empty summary nodes
* @param ctx context for security
* @param clientTree the tree is displayed on the java client (not on web)
*/
public MTree (Properties ctx, int AD_Tree_ID,
boolean editable, boolean clientTree, String trxName)
{
this (ctx, AD_Tree_ID, trxName);
m_editable = editable;
int AD_User_ID = Env.getContextAsInt(ctx, "AD_User_ID");
m_clientTree = clientTree;
log.info("AD_Tree_ID=" + AD_Tree_ID
+ ", AD_User_ID=" + AD_User_ID
+ ", Editable=" + editable
+ ", OnClient=" + clientTree);
//
loadNodes(AD_User_ID);
} // MTree
/** Is Tree editable */
private boolean m_editable = false;
/** Root Node */
private MTreeNode m_root = null;
/** Buffer while loading tree */
private ArrayList<MTreeNode> m_buffer = new ArrayList<MTreeNode>();
/** Prepared Statement for Node Details */
private RowSet m_nodeRowSet;
/** The tree is displayed on the Java Client (i.e. not web) */
private boolean m_clientTree = true;
/** Logger */
private static CLogger s_log = CLogger.getCLogger(MTree.class);
/**************************************************************************
* Get default (oldest) complete AD_Tree_ID for KeyColumn.
* Called from GridController
* @param keyColumnName key column name, eg. C_Project_ID
* @param AD_Client_ID client
* @return AD_Tree_ID
*/
public static int getDefaultAD_Tree_ID (int AD_Client_ID, String keyColumnName)
{
s_log.config(keyColumnName);
if (keyColumnName == null || keyColumnName.length() == 0)
return 0;
String TreeType = null;
if (keyColumnName.equals("AD_Menu_ID"))
TreeType = TREETYPE_Menu;
else if (keyColumnName.equals("C_ElementValue_ID"))
TreeType = TREETYPE_ElementValue;
else if (keyColumnName.equals("M_Product_ID"))
TreeType = TREETYPE_Product;
else if (keyColumnName.equals("C_BPartner_ID"))
TreeType = TREETYPE_BPartner;
else if (keyColumnName.equals("AD_Org_ID"))
TreeType = TREETYPE_Organization;
else if (keyColumnName.equals("C_Project_ID"))
TreeType = TREETYPE_Project;
else if (keyColumnName.equals("M_ProductCategory_ID"))
TreeType = TREETYPE_ProductCategory;
else if (keyColumnName.equals("M_BOM_ID"))
TreeType = TREETYPE_BoM;
else if (keyColumnName.equals("C_SalesRegion_ID"))
TreeType = TREETYPE_SalesRegion;
else if (keyColumnName.equals("C_Campaign_ID"))
TreeType = TREETYPE_Campaign;
else if (keyColumnName.equals("C_Activity_ID"))
TreeType = TREETYPE_Activity;
else
{
s_log.log(Level.SEVERE, "Could not map " + keyColumnName);
return 0;
}
int AD_Tree_ID = 0;
String sql = "SELECT AD_Tree_ID, Name FROM AD_Tree "
+ "WHERE AD_Client_ID=? AND TreeType=? AND IsActive='Y' AND IsAllNodes='Y' "
+ "ORDER BY IsDefault DESC, AD_Tree_ID";
try
{
PreparedStatement pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, AD_Client_ID);
pstmt.setString(2, TreeType);
ResultSet rs = pstmt.executeQuery();
if (rs.next())
AD_Tree_ID = rs.getInt(1);
rs.close();
pstmt.close();
}
catch (SQLException e)
{
s_log.log(Level.SEVERE, sql, e);
}
return AD_Tree_ID;
} // getAD_Tree_ID
/*************************************************************************
* Load Nodes and Bar
* @param AD_User_ID user for tree bar
*/
private void loadNodes (int AD_User_ID)
{
// SQL for TreeNodes
StringBuffer sql = new StringBuffer("SELECT "
+ "tn.Node_ID,tn.Parent_ID,tn.SeqNo,tb.IsActive "
+ "FROM ").append(getNodeTableName()).append(" tn"
+ " LEFT OUTER JOIN AD_TreeBar tb ON (tn.AD_Tree_ID=tb.AD_Tree_ID"
+ " AND tn.Node_ID=tb.Node_ID AND tb.AD_User_ID=?) " // #1
+ "WHERE tn.AD_Tree_ID=?"); // #2
if (!m_editable)
sql.append(" AND tn.IsActive='Y'");
sql.append(" ORDER BY COALESCE(tn.Parent_ID, -1), tn.SeqNo");
log.finest(sql.toString());
// The Node Loop
try
{
// load Node details - addToTree -> getNodeDetail
getNodeDetails();
//
PreparedStatement pstmt = DB.prepareStatement(sql.toString(), get_TrxName());
pstmt.setInt(1, AD_User_ID);
pstmt.setInt(2, getAD_Tree_ID());
// Get Tree & Bar
ResultSet rs = pstmt.executeQuery();
m_root = new MTreeNode (0, 0, getName(), getDescription(), 0, true, null, false, null);
while (rs.next())
{
int node_ID = rs.getInt(1);
int parent_ID = rs.getInt(2);
int seqNo = rs.getInt(3);
boolean onBar = (rs.getString(4) != null);
//
if (node_ID == 0 && parent_ID == 0)
;
else
addToTree (node_ID, parent_ID, seqNo, onBar); // calls getNodeDetail
}
rs.close();
pstmt.close();
//
m_nodeRowSet.close();
m_nodeRowSet = null;
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql.toString(), e);
m_nodeRowSet = null;
}
// Done with loading - add remainder from buffer
if (m_buffer.size() != 0)
{
log.finest("clearing buffer - Adding to: " + m_root);
for (int i = 0; i < m_buffer.size(); i++)
{
MTreeNode node = (MTreeNode)m_buffer.get(i);
MTreeNode parent = m_root.findNode(node.getParent_ID());
if (parent != null && parent.getAllowsChildren())
{
parent.add(node);
checkBuffer(node);
m_buffer.remove(i);
i = -1; // start again with i=0
}
}
}
// Nodes w/o parent
if (m_buffer.size() != 0)
{
log.severe ("Nodes w/o parent - adding to root - " + m_buffer);
for (int i = 0; i < m_buffer.size(); i++)
{
MTreeNode node = (MTreeNode)m_buffer.get(i);
m_root.add(node);
checkBuffer(node);
m_buffer.remove(i);
i = -1;
}
if (m_buffer.size() != 0)
log.severe ("Still nodes in Buffer - " + m_buffer);
} // nodes w/o parents
// clean up
if (!m_editable && m_root.getChildCount() > 0)
trimTree();
// diagPrintTree();
if (CLogMgt.isLevelFinest() || m_root.getChildCount() == 0)
log.fine("ChildCount=" + m_root.getChildCount());
} // loadNodes
/**
* Add Node to Tree.
* If not found add to buffer
* @param node_ID Node_ID
* @param parent_ID Parent_ID
* @param seqNo SeqNo
* @param onBar on bar
*/
private void addToTree (int node_ID, int parent_ID, int seqNo, boolean onBar)
{
// Create new Node
MTreeNode child = getNodeDetail (node_ID, parent_ID, seqNo, onBar);
if (child == null)
return;
// Add to Tree
MTreeNode parent = null;
if (m_root != null)
parent = m_root.findNode (parent_ID);
// Parent found
if (parent != null && parent.getAllowsChildren())
{
parent.add(child);
// see if we can add nodes from buffer
if (m_buffer.size() > 0)
checkBuffer(child);
}
else
m_buffer.add(child);
} // addToTree
/**
* Check the buffer for nodes which have newNode as Parents
* @param newNode new node
*/
private void checkBuffer (MTreeNode newNode)
{
// Ability to add nodes
if (!newNode.isSummary() || !newNode.getAllowsChildren())
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -