/****************************************************************************** Copyright (C) 2017 Adaxa Pty Ltd. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *****************************************************************************/ package org.compiere.model; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; import org.compiere.util.CCache; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Util; /** * Favorite Tree Model * * @author Logilite Technologies * @since June 20, 2017 */ public class MTreeFavorite extends X_AD_Tree_Favorite { /** * generated serial id */ private static final long serialVersionUID = 1468891496751650494L; public static final String SQL_GET_TREE_FAVORITE_ID = "SELECT AD_Tree_Favorite_ID FROM AD_Tree_Favorite WHERE IsActive='Y' AND AD_User_ID=?"; public static final String SQL_GET_TREE_FAVORITE_NODE = "SELECT AD_Tree_Favorite_Node_ID, Parent_ID, SeqNo, Name, IsSummary, AD_Menu_ID, IsCollapsible, IsFavourite " + " FROM AD_Tree_Favorite_Node WHERE IsActive='Y' AND AD_Tree_Favorite_ID=? AND AD_Client_ID IN (0,?) " + " ORDER BY COALESCE(Parent_ID, -1), SeqNo, Name "; /** Cache for AD_Tree_Favorite_ID */ private static CCache cache_TreeFavID = new CCache("AD_Tree_Favorite_ID", 30); private ArrayList m_buffer = new ArrayList(); private MTreeNode root = null; /** * UUID based Constructor * @param ctx Context * @param AD_Tree_Favorite_UU UUID key * @param trxName Transaction */ public MTreeFavorite(Properties ctx, String AD_Tree_Favorite_UU, String trxName) { super(ctx, AD_Tree_Favorite_UU, trxName); if (! Util.isEmpty(AD_Tree_Favorite_UU)) loadNode(); } /** * Construct Tree Favorite Model * * @param ctx * @param AD_Tree_Favorite_ID * @param trxName */ public MTreeFavorite(Properties ctx, int AD_Tree_Favorite_ID, String trxName) { super(ctx, AD_Tree_Favorite_ID, trxName); if (AD_Tree_Favorite_ID > 0) loadNode(); } /** * @param ctx * @param rs * @param trxName */ public MTreeFavorite(Properties ctx, ResultSet rs, String trxName) { super(ctx, rs, trxName); } /** * Get root node * @return root node */ public MTreeNode getRoot() { return root; } // getRoot /** * Load Node Into Tree */ private void loadNode() { MRole role = MRole.get(getCtx(), Env.getAD_Role_ID(Env.getCtx())); PreparedStatement pstmt = null; ResultSet rs = null; try { root = new MTreeNode(0, 0, "User Favourite Root", "User Favourite Root", 0, 0, null, true, false, false); pstmt = DB.prepareStatement(SQL_GET_TREE_FAVORITE_NODE, get_TrxName()); pstmt.setInt(1, getAD_Tree_Favorite_ID()); pstmt.setInt(2, Env.getAD_Client_ID(Env.getCtx())); rs = pstmt.executeQuery(); while (rs.next()) { int nodeID = rs.getInt(1); int parentID = rs.getInt(2); int seqNo = rs.getInt(3); String name = rs.getString(4); String description = null; boolean isSummary = (rs.getString(5).equals("Y")); boolean isCollapsible = rs.getString(7).equals("Y"); boolean isFavourite = rs.getString("IsFavourite").equals("Y"); int menuID = 0; String img = null; Boolean access = null; if (!isSummary) { menuID = rs.getInt(6); MMenu menu = (MMenu) MTable.get(Env.getCtx(), MMenu.Table_ID).getPO(menuID, null); access = getAccessForMenuItem(role, menu); if (access != null) { name = menu.getDisplayedName(); description = menu.get_Translation(MMenu.COLUMNNAME_Description); img = menu.getAction(); } } if (access != null || isSummary) addToTree(nodeID, parentID, seqNo, name, description, menuID, img, isSummary, isCollapsible, isFavourite); } } catch (SQLException e) { log.log(Level.SEVERE, SQL_GET_TREE_FAVORITE_NODE, e); throw new AdempiereException(e); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } } // loadNode /** * Add Node Into Tree * * @param favNodeID * @param parentID * @param seqNo * @param name * @param description * @param menuID * @param imgSrc * @param isSummary * @param isCollapsible * @param isFavourite */ private void addToTree( int favNodeID, int parentID, int seqNo, String name, String description, int menuID, String imgSrc, boolean isSummary, boolean isCollapsible, boolean isFavourite) { MTreeNode child = new MTreeNode(favNodeID, seqNo, name, description, parentID, menuID, imgSrc, isSummary, isCollapsible, isFavourite); MTreeNode parent = null; if (root != null) parent = root.findNode(parentID); // Parent found if (parent != null && parent.getAllowsChildren()) { parent.add(child); 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 child) { // Ability to add nodes if (!child.isSummary() || !child.getAllowsChildren()) return; for (int i = 0; i < m_buffer.size(); i++) { MTreeNode node = (MTreeNode) m_buffer.get(i); if (node.getParent_ID() == child.getParent_ID()) { try { child.add(node); } catch (Exception e) { log.severe("Adding " + node.getName() + " to " + child.getName() + ": " + e.getMessage()); } m_buffer.remove(i); i--; } else if (node.getParent_ID() == child.getNode_ID()) { try { child.add(node); } catch (Exception e) { log.severe("Adding " + node.getName() + " to " + child.getName() + ": " + e.getMessage()); } m_buffer.remove(i); i--; } } } // checkBuffer /** * Get Favorite Tree ID for a specific User * * @param userID * @return Favorite Tree_ID */ public static int getFavoriteTreeID(int userID) { if (cache_TreeFavID.containsKey(userID)) return cache_TreeFavID.get(userID); int id = DB.getSQLValue(null, SQL_GET_TREE_FAVORITE_ID, userID); if (id > 0) cache_TreeFavID.put(userID, id); return id; } // getFavoriteTreeID /** * Get access for the menu from specified role * * @param role * @param menu * @return true if role can access the menu item */ public static Boolean getAccessForMenuItem(MRole role, I_AD_Menu menu) { Boolean access = null; if (MMenu.ACTION_Window.equals(menu.getAction())) access = role.getWindowAccess(menu.getAD_Window_ID()); else if (MMenu.ACTION_Process.equals(menu.getAction()) || MMenu.ACTION_Report.equals(menu.getAction())) access = role.getProcessAccess(menu.getAD_Process_ID()); else if (MMenu.ACTION_Form.equals(menu.getAction())) access = role.getFormAccess(menu.getAD_Form_ID()); else if (MMenu.ACTION_WorkFlow.equals(menu.getAction())) access = role.getWorkflowAccess(menu.getAD_Workflow_ID()); else if (MMenu.ACTION_Task.equals(menu.getAction())) access = role.getTaskAccess(menu.getAD_Task_ID()); else if (MMenu.ACTION_Info.equals(menu.getAction())) access = role.getInfoAccess(menu.getAD_InfoWindow_ID()); return access; } // getAccessForMenuItem }