ro.cs.om.utils.organigram.OrganigramUtils.java Source code

Java tutorial

Introduction

Here is the source code for ro.cs.om.utils.organigram.OrganigramUtils.java

Source

/*******************************************************************************
 * This file is part of Termitaria, a project management tool 
 *  Copyright (C) 2008-2013 CodeSphere S.R.L., www.codesphere.ro
 *   
 *  Termitaria is free software; you can redistribute it and/or 
 *  modify it under the terms of the GNU Affero General Public License 
 *  as published by the Free Software Foundation; either version 3 of 
 *  the License, or (at your option) any later version.
 *  
 *  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.  See the 
 *  GNU Affero General Public License for more details.
 *  
 *  You should have received a copy of the GNU Affero General Public License 
 *  along with Termitaria. If not, see  <http://www.gnu.org/licenses/> .
 ******************************************************************************/
package ro.cs.om.utils.organigram;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;

import net.sf.json.JSONObject;

import org.springframework.security.core.context.SecurityContextHolder;

import ro.cs.om.business.BLDepartment;
import ro.cs.om.business.BLOrganisation;
import ro.cs.om.common.ApplicationObjectSupport;
import ro.cs.om.common.ConfigParametersProvider;
import ro.cs.om.common.IConstant;
import ro.cs.om.entity.OrgTree;
import ro.cs.om.entity.OrgTreeNode;
import ro.cs.om.entity.Organisation;
import ro.cs.om.entity.Person;
import ro.cs.om.exception.BusinessException;
import ro.cs.om.utils.file.FileUtils;
import ro.cs.om.utils.image.ImageUtils;
import ro.cs.om.web.security.UserAuth;

import com.lowagie.text.Document;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;

/**
 * @author dan.damian
 *
 */
public class OrganigramUtils extends ApplicationObjectSupport {

    private static String REPLACE_THEME = "replaceTheme";

    private static String ORGANISATION_NODE_PICTURE_LOCATION = "themes".concat(File.separator).concat(REPLACE_THEME)
            .concat(File.separator).concat("images").concat(File.separator).concat("organigram")
            .concat(File.separator).concat("Org.jpg");

    private static String DEPARTMENT_NODE_PICTURE_LOCATION = "themes".concat(File.separator).concat(REPLACE_THEME)
            .concat(File.separator).concat("images").concat(File.separator).concat("organigram")
            .concat(File.separator).concat("Dept.jpg");

    //Parameters for drawing
    public static int H_SPACE = 0;
    public static int V_SPACE = 0;
    public static int NODE_WIDTH = 0;
    public static int NODE_HEIGHT = 0;
    private static int LABEL_MAX_LENGTH = 0;
    private static Color LINE_COLOR = null;
    private static Color TEXT_COLOR_TITLE = null;
    private static Color TEXT_COLOR_MANAGER = null;

    private static OrganigramUtils theInstance = null;

    static {
        theInstance = new OrganigramUtils();
        try {
            H_SPACE = ConfigParametersProvider.getConfigStringAsInt("organigram.H_SPACE");
            V_SPACE = ConfigParametersProvider.getConfigStringAsInt("organigram.V_SPACE");
            NODE_WIDTH = ConfigParametersProvider.getConfigStringAsInt("organigram.NODE_WIDTH");
            NODE_HEIGHT = ConfigParametersProvider.getConfigStringAsInt("organigram.NODE_HEIGHT");
            LABEL_MAX_LENGTH = ConfigParametersProvider.getConfigStringAsInt("organigram.LABEL_MAX_LENGTH");
            LINE_COLOR = ConfigParametersProvider.getConfigStringAsColor("organigram.LINE_COLOR");
            TEXT_COLOR_TITLE = ConfigParametersProvider.getConfigStringAsColor("organigram.TEXT_COLOR_TITLE");
            TEXT_COLOR_MANAGER = ConfigParametersProvider.getConfigStringAsColor("organigram.TEXT_COLOR_MANAGER");
        } catch (Exception ex) {

        }
    }

    private OrganigramUtils() {
    }

    public static OrganigramUtils getInstance() {
        return theInstance;
    }

    /**
     * Draw a Node from the Organigram
     * @author dan.damian 
     */
    private void drawNode(Graphics2D g, OrgTreeNode node, String nodeOrgImg, String nodeDeptImg, boolean root) {
        //First draw the Node Info
        drawNodeInfo(g, node, nodeOrgImg, nodeDeptImg);
        if (!root) {
            //If it's not a root Node draw top Line
            drawTopLine(g, node);
        }

        if (node.getChildrenNumber() > 0) {
            //If it has children
            drawBottomLine(g, node);
            //It it has more than one child
            if (node.getChildrenNumber() > 1) {
                drawHorizontalLine(g, node);
            }
            //For all it's children
            for (int i = 0; i < node.getChildrenNumber(); i++) {
                //Do the same...
                drawNode(g, node.getChildren().get(i), nodeOrgImg, nodeDeptImg, false);
            }
        }

    }

    /**
     * Draw Node's Informations and the Rectangle representing the Node itself
     * @author dan.damian 
     */
    private void drawNodeInfo(Graphics2D g, OrgTreeNode node, String nodeOrgImg, String nodeDeptImg) {
        //Draw a Rectangle representing the Node

        String imgUrl = nodeDeptImg;
        if (node.getNodeType() != IConstant.NOM_TREE_NODE_TYPE_DEPARTMENT) {
            imgUrl = nodeOrgImg;
        }

        try {
            g.drawImage(ImageIO.read(new File(imgUrl)), node.getXPosition(), node.getYPosition(), Color.blue, null);
        } catch (IOException e) {
            g.drawRect(node.getXPosition(), node.getYPosition(), NODE_WIDTH, NODE_HEIGHT);
        }

        String label = node.getNodeName();
        //If Department Name it's too big will short it a little
        if (label.length() > LABEL_MAX_LENGTH) {
            label = label.substring(0, LABEL_MAX_LENGTH - 3);
            label += "...";
        }

        //Switch to Text Color for Title
        g.setColor(TEXT_COLOR_TITLE);
        g.drawString(label, node.getXPosition() + (NODE_WIDTH - label.length() * 6) / 2, node.getYPosition() + 15);

        //Retrieving Department's Manager
        Person manager = null;
        try {
            manager = BLDepartment.getInstance().getDepartmentsManager(node.getDepartmentId());
        } catch (Exception ex) {
        }

        String managerName = "";

        if (manager != null) {
            managerName = manager.getFirstName().concat(" ").concat(manager.getLastName());

            if (managerName.length() > LABEL_MAX_LENGTH) {
                managerName = managerName.substring(0, LABEL_MAX_LENGTH - 3);
                managerName += "...";
            }
        }
        //Switch to Text Color for Manager      
        g.setColor(TEXT_COLOR_MANAGER);
        g.drawString(managerName, node.getXPosition() + (NODE_WIDTH - managerName.length() * 6) / 2,
                node.getYPosition() + 40);
        //Back to line Color
        g.setColor(LINE_COLOR);
    }

    /**
     * Draws the Top Line 
     * @author dan.damian 
     */
    private void drawTopLine(Graphics2D g, OrgTreeNode node) {
        g.drawLine(node.getXPosition() + (NODE_WIDTH / 2), node.getYPosition() - (V_SPACE / 2),
                node.getXPosition() + (NODE_WIDTH / 2), node.getYPosition() - 2);
    }

    /**
     * Draws the Bottom Line
     * @author dan.damian 
     */
    private void drawBottomLine(Graphics2D g, OrgTreeNode node) {
        g.drawLine(node.getXPosition() + (NODE_WIDTH / 2), node.getYPosition() + NODE_HEIGHT,
                node.getXPosition() + (NODE_WIDTH / 2), node.getYPosition() + NODE_HEIGHT + V_SPACE / 2);
    }

    /**
     * Draws the Horizontal Line
     * @author dan.damian 
     */
    private void drawHorizontalLine(Graphics2D g, OrgTreeNode node) {
        g.drawLine(node.getChildren().get(0).getXPosition() + (NODE_WIDTH / 2),
                node.getYPosition() + NODE_HEIGHT + (V_SPACE / 2),
                node.getChildren().get(node.getChildrenNumber() - 1).getXPosition() + (NODE_WIDTH / 2),
                node.getYPosition() + NODE_HEIGHT + (V_SPACE / 2));
    }

    /**
     * Creates the PDF file containing a JPEG Picture representing our Organigram.
     * It then writes this PDF File in an OutputStream.
     * Particular the OutputStream it's ServletOutputStream.
     * @author dan.damian 
     */
    public void createPDFOrganigram(OutputStream os, OrgTree tree) throws Exception {
        //The PDF Document
        Document document = new Document();
        //Organigram dimensions
        int height = calculateOrganigramHeight(tree);
        int width = calculateOrganigramWidth(tree);
        //Setting Document's dimensions
        document.setPageSize(new Rectangle(width + 200, height + 200));

        PdfWriter.getInstance(document, os);
        document.open();

        // Retrieving the Organization
        Organisation org = BLOrganisation.getInstance().get(tree.getRoot().getOrganizationId());
        document.add(new Paragraph(org.getName()));

        // Create an Image
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // Get the Image's Graphics, and draw.
        Graphics2D g = img.createGraphics();
        g.setColor(Color.white);
        g.fillRect(0, 0, width, height);

        //Start drawing the Organigram with one node, it's root...
        g.setColor(LINE_COLOR);

        String themeCode = ((UserAuth) SecurityContextHolder.getContext().getAuthentication().getPrincipal())
                .getThemeCode();

        String orgPicLocation = ORGANISATION_NODE_PICTURE_LOCATION.replace(REPLACE_THEME, themeCode);
        String deptPicLocation = DEPARTMENT_NODE_PICTURE_LOCATION.replace(REPLACE_THEME, themeCode);

        logger.debug("Org = " + ORGANISATION_NODE_PICTURE_LOCATION + ", " + orgPicLocation);
        logger.debug("Dept = " + DEPARTMENT_NODE_PICTURE_LOCATION + ", " + deptPicLocation);

        //Location of the Image file that will represent an Organization Box
        String nodeOrgImage = FileUtils.getInstance().getRealPathForResource(orgPicLocation);

        //Location of the Image file that will represent a Department Box
        String nodeDeptImage = FileUtils.getInstance().getRealPathForResource(deptPicLocation);

        logger.debug("nodeOrgImage = " + nodeOrgImage);
        logger.debug("nodeDeptImage = " + nodeDeptImage);

        drawNode(g, tree.getRoot(), nodeOrgImage, nodeDeptImage, true);

        //Add the Image to PDF
        com.lowagie.text.Image image = com.lowagie.text.Image
                .getInstance(ImageUtils.getInstance().bufferedImageToByteArray(img));
        document.add(image);

        //Close the Document
        document.close();
    }

    /**
     * ******************************************************************************************************************************************************
     *                         OrgStructTree                                                                                 *   
     * ******************************************************************************************************************************************************
     */

    /**
     * Calculates Organigram Width based in informations from Organigram Tree
     * @author dan.damian 
     * @return 
     */
    public int calculateOrganigramWidth(OrgTree tree) {
        return H_SPACE + tree.getLeafsNo() * NODE_WIDTH + (tree.getLeafsNo() - 1) * H_SPACE + H_SPACE;
    }

    /**
     * Calculates Organigram Height based in informations from Organigram Tree
     * @author dan.damian 
     * @return
     */
    public int calculateOrganigramHeight(OrgTree tree) {
        return V_SPACE + tree.getLevels() * NODE_HEIGHT + (tree.getLevels() - 1) * V_SPACE + V_SPACE;
    }

    /**
     * Returns a JSON Partial Representation of this OrgDeptTree Object
     * @author dan.damian 
     */
    public String generateJSONTree(OrgTree tree) throws BusinessException {
        logger.debug("generateJSONTree BEGIN");
        JSONObject rootJSON = new JSONObject();
        if (tree == null) {
            return null;
        }

        rootJSON.accumulate("xPosition", tree.getRoot().getXPosition() + 100);
        rootJSON.accumulate("yPosition", tree.getRoot().getYPosition());
        rootJSON.accumulate("label", tree.getRoot().getNodeName());
        rootJSON.accumulate("departmentId", tree.getRoot().getDepartmentId());
        rootJSON.accumulate("level", 0);
        rootJSON.accumulate("leafNo", tree.getRoot().getLeafNo());
        Person generalDirector = BLDepartment.getInstance().getDepartmentsManager(tree.getRoot().getDepartmentId());
        String generalDirectorsName = "";
        if (generalDirector != null) {
            generalDirectorsName = generalDirector.getFirstName().concat(" ").concat(generalDirector.getLastName());
        }
        rootJSON.accumulate("manager", generalDirectorsName);

        for (int i = 0; i < tree.getRoot().getChildrenNumber(); i++) {
            OrgTreeNode node = tree.getRoot().getChildren().get(i);
            rootJSON.accumulate("children", getNode(node));
        }
        rootJSON.accumulate("vspace", OrganigramUtils.V_SPACE);
        rootJSON.accumulate("hspace", OrganigramUtils.H_SPACE);
        rootJSON.accumulate("nodeWidth", OrganigramUtils.NODE_WIDTH);
        rootJSON.accumulate("nodeHeight", OrganigramUtils.NODE_HEIGHT);

        rootJSON.accumulate("organigramWidth", OrganigramUtils.getInstance().calculateOrganigramWidth(tree));
        rootJSON.accumulate("organigramHeight", OrganigramUtils.getInstance().calculateOrganigramHeight(tree));

        logger.debug("generateJSONTree END");

        return rootJSON.toString();
    }

    /**
     * Returns a JSON Partial Representation of this OrgDeptTreeNode object
     * @author dan.damian
     */
    public JSONObject getNode(OrgTreeNode node) throws BusinessException {
        JSONObject nodeJSON = new JSONObject();
        nodeJSON.accumulate("xPosition", node.getXPosition() + 100);
        nodeJSON.accumulate("yPosition", node.getYPosition());
        nodeJSON.accumulate("label", node.getNodeName());
        nodeJSON.accumulate("type", node.getNodeType());
        nodeJSON.accumulate("departmentId", node.getDepartmentId());
        nodeJSON.accumulate("level", node.getLevel());
        nodeJSON.accumulate("leafNo", node.getLeafNo());
        Person departmentManager = BLDepartment.getInstance().getDepartmentsManager(node.getDepartmentId());
        nodeJSON.accumulate("manager",
                (departmentManager != null
                        ? departmentManager.getFirstName() + " " + departmentManager.getLastName()
                        : ""));

        for (int i = 0; i < node.getChildrenNumber(); i++) {
            OrgTreeNode child = node.getChildren().get(i);
            nodeJSON.accumulate("children", getNode(child));
        }

        return nodeJSON;
    }
}