public static void updateTreeNode(PO po) { int nodeId = po.get_ID(); if (nodeId < 0) { return; // nothing to do, because our PO has no ID to match against a tree node } final int AD_Table_ID = po.get_Table_ID(); if (!MTree.hasTree(AD_Table_ID)) { return; } final String nodeTableName = MTree.getNodeTableName(AD_Table_ID); if (nodeTableName == null) { return; } // // services final IPOTreeSupportFactory treeSupportFactory = Services.get(IPOTreeSupportFactory.class); final String trxName = po.get_TrxName(); final IPOTreeSupport treeSupport = treeSupportFactory.get(po.get_TableName()); if (po.is_ValueChanged("IsSummary") && !po.get_ValueAsBoolean("IsSummary")) { // Move all its children to parent final List<MTreeNode> children = fetchNodes(AD_Table_ID, "Parent_ID=?", new Object[] {nodeId}, trxName); if (children.size() > 0) { throw new AdempiereException("TreeNodeHasChildren"); // TODO: translate } } if (treeSupport.isParentChanged(po)) { int parentId = treeSupport.getParent_ID(po); int oldParentId = treeSupport.getOldParent_ID(po); int seqNo = -1; // compute final String sql = "SELECT AD_Tree_ID, TreeType FROM AD_Tree WHERE AD_Table_ID=? AND AD_Client_ID=?"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, trxName); DB.setParameters(pstmt, new Object[] {AD_Table_ID, po.getAD_Client_ID()}); rs = pstmt.executeQuery(); while (rs.next()) { int AD_Tree_ID = rs.getInt(COLUMNNAME_AD_Tree_ID); String treeType = rs.getString(COLUMNNAME_TreeType); updateNode( po, AD_Tree_ID, treeType, AD_Table_ID, nodeId, parentId, oldParentId, seqNo, trxName); } } catch (SQLException e) { throw new DBException(e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } } }
private void updateNode(MTreeNode node, int parentId, int seqNo, String trxName) { // // services final IPOTreeSupportFactory treeSupportFactory = Services.get(IPOTreeSupportFactory.class); final int AD_Tree_ID = this.getAD_Tree_ID(); if (node.getAD_Tree_ID() < 0) // TODO: workaround, we should instantiate the MTreeNode by giving the tree { node.setAD_Tree_ID(this.getAD_Tree_ID()); node.setAD_Table_ID(this.getAD_Table_ID()); } if (node.getAD_Tree_ID() != AD_Tree_ID) throw new IllegalArgumentException( "AD_Tree_ID<>" + AD_Tree_ID + " (node:" + node + ", AD_Tree_ID=" + node.getAD_Tree_ID() + ")"); final int nodeId = node.getNode_ID(); final int oldParentId = node.getParent_ID(); updateNode( null, this.getAD_Tree_ID(), this.getTreeType(), this.getAD_Table_ID(), nodeId, parentId, oldParentId, seqNo, trxName); node.setParent_ID(parentId); node.setSeqNo(seqNo); treeSupportFactory .get(getSourceTableName()) .setParent_ID(this, node.getNode_ID(), parentId, trxName); listeners.onParentChanged(node.getAD_Table_ID(), nodeId, parentId, oldParentId, trxName); }
public void verifyTree() { final IPOTreeSupportFactory treeSupportFactory = Services.get(IPOTreeSupportFactory.class); final String nodeTableName = getNodeTableName(); final String sourceTableName = getSourceTableName(); final String sourceTableKey = getSourceKeyColumnName(); final int AD_Client_ID = getAD_Client_ID(); final IPOTreeSupport treeSupport = treeSupportFactory.get(getSourceTableName()); final String sourceTableWhereClause = treeSupport.getWhereClause(this); // Delete unused final StringBuilder sql = new StringBuilder(); sql.append("DELETE FROM ") .append(nodeTableName) .append(" WHERE AD_Tree_ID=") .append(getAD_Tree_ID()) .append(" AND Node_ID<>0") // don't delete root node .append(" AND Node_ID NOT IN (SELECT ") .append(sourceTableKey) .append(" FROM ") .append(sourceTableName) .append(" WHERE AD_Client_ID=") .append(AD_Client_ID); if (!Check.isEmpty(sourceTableWhereClause, true)) { sql.append(" AND (").append(sourceTableWhereClause).append(")"); } sql.append(")"); log.trace(sql.toString()); // final int deletes = DB.executeUpdateEx(sql.toString(), get_TrxName()); log.info(getName() + " Deleted #" + deletes); // Check and create root node { final Query query = new Query(getCtx(), nodeTableName, "AD_Tree_ID=? AND Node_ID=?", get_TrxName()) .setParameters(getAD_Tree_ID(), ROOT_Node_ID); if (!query.match()) { createNode(ROOT_Node_ID, ROOT_Node_ID); log.info(getName() + " Root Node Created"); } } if (!isAllNodes()) { return; } String sqlParentId = treeSupport.getParentIdSQL(); boolean updateParents = true; if (Check.isEmpty(sqlParentId, true)) { sqlParentId = "" + ROOT_Node_ID; updateParents = true; } // Insert new sql.setLength(0); sql.append("SELECT ") .append(sourceTableKey) // 1 .append(",") .append(sqlParentId) // 2 .append(" FROM ") .append(sourceTableName) .append(" WHERE AD_Client_ID=") .append(AD_Client_ID); if (!Check.isEmpty(sourceTableWhereClause, true)) { sql.append(" AND (").append(sourceTableWhereClause).append(")"); } sql.append(" AND ") .append(sourceTableKey) .append(" NOT IN (SELECT Node_ID FROM ") .append(nodeTableName) .append(" WHERE AD_Tree_ID=") .append(getAD_Tree_ID()) .append(")"); // int inserted = 0; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql.toString(), get_TrxName()); rs = pstmt.executeQuery(); while (rs.next()) { int nodeId = rs.getInt(1); int parentId = rs.getInt(2); if (nodeId == ROOT_Node_ID) throw new AdempiereException( "Tree is not supported for this table because it contains a record that has the same ID as current hardcoded root id"); createNode(nodeId, parentId); inserted++; } } catch (SQLException e) { throw new DBException(e, sql.toString()); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } // // Update parents from PO table: if (updateParents) { // TODO: implement update parents logic } log.info(getName() + " Inserted #" + inserted); }
/** * ************************************************************************ Insert id data into * Tree * * @return true if inserted */ protected static boolean insertTreeNode(PO po) { // // services final IPOTreeSupportFactory treeSupportFactory = Services.get(IPOTreeSupportFactory.class); // TODO: check self contained tree final int AD_Table_ID = po.get_Table_ID(); if (!MTree.hasTree(AD_Table_ID)) { return false; } final int id = po.get_ID(); final int AD_Client_ID = po.getAD_Client_ID(); final String treeTableName = MTree.getNodeTableName(AD_Table_ID); final String trxName = po.get_TrxName(); final Logger log = po.get_Logger(); final IPOTreeSupport treeSupport = treeSupportFactory.get(po.get_TableName()); final int AD_Tree_ID = treeSupport.getAD_Tree_ID(po); int parentId = treeSupport.getParent_ID(po); if (parentId < 0 || parentId == IPOTreeSupport.UNKNOWN_ParentID) { parentId = ROOT_Node_ID; } // // Insert final StringBuilder sb = new StringBuilder("INSERT INTO ") .append(treeTableName) .append(" (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, ") .append("AD_Tree_ID, Node_ID, Parent_ID, SeqNo) ") // .append( "SELECT t.AD_Client_ID,0, 'Y', now(), " + po.getUpdatedBy() + ", now(), " + po.getUpdatedBy() + ",") .append("t.AD_Tree_ID, ") .append(id) .append(", ") .append(parentId) .append(", 999 ") .append("FROM AD_Tree t ") .append("WHERE t.AD_Client_ID=") .append(AD_Client_ID) .append(" AND t.IsActive='Y'"); if (AD_Tree_ID > 0) { sb.append(" AND t.AD_Tree_ID=").append(AD_Tree_ID); } else // std trees { sb.append(" AND t.IsAllNodes='Y' AND t.AD_Table_ID=").append(AD_Table_ID); } // Duplicate Check sb.append(" AND NOT EXISTS (SELECT * FROM ") .append(treeTableName) .append(" e ") .append("WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=") .append(id) .append(")"); // int no = DB.executeUpdateEx(sb.toString(), trxName); if (no < 0) { log.warn("#" + no + " - AD_Table_ID=" + AD_Table_ID); return false; } log.debug("#" + no + " - AD_Table_ID=" + AD_Table_ID); // MigrationLogger.instance.logMigrationSQL(po, sb.toString()); // metas: not needed because // it's called directly from PO listeners.onNodeInserted(po); return true; } // insert_Tree