This document describes how to build an organizational structure tree using Java EE and PrimeFaces for display in a cloud computing environment without data warehousing. It provides code for:
1) Creating a database table to store the organizational structure
2) Developing a JEE entity class and EJB to represent and access the data
3) Building a managed bean that constructs the tree model from the EJB data
4) Displaying the tree on a web page using PrimeFaces
The tree can then be used to organize and display reporting and other hierarchical data from different private cloud systems without needing data warehousing. Future publications will cover integrating trees from different private clouds.
1 of 16
Download to read offline
More Related Content
Cloud computing BI publication 1
1. BY JOBE BACWADI
1. Executive summary
Data Warehousing and BI? Very easy for the company, very easy for the bank, very easy for everyone but not for the government! Sound strange but true, right?
We cannot develop the government BI using data warehousing, just dream on if you think so. The solution is cloud computing. With cloud computing we are saying every
government agency has data services which can be shared via SOAP or RESTful. For an agency to be cloud computing ready they must provide SOAP/RESTful services for their
systems. No data warehousing required! We call this private cloud because only those services relevant for the outside world are published. Cloud computing does not mean
someone must host your data and applications (so beware of sharks out there who want to make money out of you talking about cloud computing).
I will divide the publications into three and I am assuring you by the third one you will be able to design cloud computing BI.
a) Publication 1 will be about how to build a reporting tree using JEE and prime faces. There is no BI if there is not organisation structure, if there is no accounting
structure, if there is no project structure, etc. These are all trees in programming. This code you can copy past and it will work.
b) Publication 2 will be about how to build a tree from different trees hosted in different locations. It¨s like we say we have a national government tree which should show
report on Education department tree, which is located in a different location, and so on. This publication will also deal with performance issues (the main reason why we
build data warehousing), but now without data warehousing.
c) Publication 3 will be about how to build cloud BI without data warehousing.
2. BY JOBE BACWADI
2. Building a Tree using JEE and Prime Faces
Let¨s use organisation structure example.
2.1 Building the Database
Below is an example with the org structure table build using MySQL. The parent_code column is the foreign key to code. So this is a tree.
3. BY JOBE BACWADI
2.2 Building an EJB
Netbeans tool is free and generate these things automatically. Why buy expensive tools then? Use Netbeans to generate OrgStructure entity class from database. Use the wizard
and stop the headache. The EJB should be as follows:
package gai.ejb.entities.org;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* @author jobe bacwadi
*/
@Entity
@Table(name = "org_structure")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "OrgStructure.findParentCodeIsNull", query = "SELECT o FROM OrgStructure o WHERE o.parentCode is null"),
@NamedQuery(name = "OrgStructure.findByLevelParentCode", query = "SELECT o FROM OrgStructure o WHERE o.level = :level and o.parentCode.code = :parentCode"),
@NamedQuery(name = "OrgStructure.findAllName", query = "SELECT o FROM OrgStructure o order by o.name"),
@NamedQuery(name = "OrgStructure.findByParentCode", query = "SELECT o FROM OrgStructure o WHERE o.parentCode.code = :parentCode"),
4. BY JOBE BACWADI
@NamedQuery(name = "OrgStructure.findByParentName", query = "SELECT o FROM OrgStructure o WHERE o.parentCode.name = :name"),
@NamedQuery(name = "OrgStructure.findAll", query = "SELECT o FROM OrgStructure o"),
@NamedQuery(name = "OrgStructure.findById", query = "SELECT o FROM OrgStructure o WHERE o.id = :id"),
@NamedQuery(name = "OrgStructure.findByCode", query = "SELECT o FROM OrgStructure o WHERE o.code = :code"),
@NamedQuery(name = "OrgStructure.findByName", query = "SELECT o FROM OrgStructure o WHERE o.name = :name"),
@NamedQuery(name = "OrgStructure.findByDescription", query = "SELECT o FROM OrgStructure o WHERE o.description = :description"),
@NamedQuery(name = "OrgStructure.findByLevel", query = "SELECT o FROM OrgStructure o WHERE o.level = :level"),
@NamedQuery(name = "OrgStructure.findByOldCode", query = "SELECT o FROM OrgStructure o WHERE o.oldCode = :oldCode"),
@NamedQuery(name = "OrgStructure.findByTypeCode", query = "SELECT o FROM OrgStructure o WHERE o.typeCode = :typeCode")})
public class OrgStructure implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 45)
@Column(name = "code")
private String code;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 100)
@Column(name = "name")
private String name;
@Size(max = 512)
@Column(name = "description")
private String description;
@Column(name = "level")
private Integer level;
@Size(max = 45)
@Column(name = "old_code")
private String oldCode;
@Size(max = 45)
@Column(name = "type_code")
private String typeCode;
@JoinColumn(name = "security_code", referencedColumnName = "code")
6. BY JOBE BACWADI
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public String getOldCode() {
return oldCode;
}
public void setOldCode(String oldCode) {
this.oldCode = oldCode;
}
public String getTypeCode() {
return typeCode;
}
public void setTypeCode(String typeCode) {
this.typeCode = typeCode;
}
public SecCode getSecurityCode() {
7. BY JOBE BACWADI
return securityCode;
}
public void setSecurityCode(SecCode securityCode) {
this.securityCode = securityCode;
}
@XmlTransient
public Collection<OrgStructure> getOrgStructureCollection() {
return orgStructureCollection;
}
public void setOrgStructureCollection(Collection<OrgStructure> orgStructureCollection) {
this.orgStructureCollection = orgStructureCollection;
}
public OrgStructure getParentCode() {
return parentCode;
}
public void setParentCode(OrgStructure parentCode) {
this.parentCode = parentCode;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof OrgStructure)) {
return false;
}
OrgStructure other = (OrgStructure) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
8. BY JOBE BACWADI
return false;
}
return true;
}
@Override
public String toString() {
return "gai.org.entities.OrgStructure[ id=" + id + " ]";
}
}
2.3 Build Org Structure Service
The entity bean above is just the model displaying where to get information from database. Now we need to build the service that will get this information for us. I called it
OrgStructureService.
package gai.ejb.services.internal.org;
import gai.ejb.entities.org.OrgStructure;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
/**
*
* @author Jobe Bacwadi
*/
13. BY JOBE BACWADI
return null;
}
return list;
}
}
2.4 Build the Tree
Now we have the database table (Section 2.1), the JEE model representing the table (Section 2.2) and the service (Section 2.3) using the model to get us information from the
table. Now we need to build a ManagedBean that will build a tree for us. I called it TreeOrgView, because it is a view.
package gai.view.org;
/**
*
* @author Jobe Bacwadi
*/
import gai.ejb.services.internal.org.OrgStructureService;
import gai.ejb.entities.org.OrgStructure;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean(name = "treeOrgView")
@ViewScoped
public class TreeOrgView implements Serializable {
14. BY JOBE BACWADI
private TreeNode root;
private List<TreeNode> nodes = new ArrayList<>();
private boolean validTree;
@EJB
private OrgStructureService orgBean;
@PostConstruct
public void init() {
Map<String, Integer> nodeIndex = new HashMap<>();
List<OrgStructure> rootList = orgBean.getOrgParents();
if (rootList == null) {
validTree = false;
} else {
validTree = true;
root = new DefaultTreeNode("Root", null);
for (OrgStructure org : rootList) {
List<OrgStructure> level1List = orgBean.getOrgSiblings(1, org.getCode());
if (level1List != null) {
TreeNode node = new DefaultTreeNode(org.getName(), root);
nodes.add(node);
nodeIndex.put(org.getCode(), nodes.indexOf(node));
for (OrgStructure levelOrg : level1List) {
TreeNode levelNode = new DefaultTreeNode(levelOrg.getName(), node);
nodes.add(levelNode);
nodeIndex.put(levelOrg.getCode(), nodes.indexOf(levelNode));
}
}
}
for (int i = 1; i < orgBean.getMaxLevel(); i++) {
int level = i;
int nextLevel = level + 1;
List<OrgStructure> parentList = orgBean.getOrgSiblings(level);
for (OrgStructure org : parentList) {
List<OrgStructure> siblingList = orgBean.getOrgSiblings(nextLevel, org.getCode());
if (siblingList != null) {
15. BY JOBE BACWADI
for (OrgStructure levelOrg : siblingList) {
TreeNode levelNode = new DefaultTreeNode(levelOrg.getName(), nodes.get(nodeIndex.get(org.getCode())));
nodes.add(levelNode);
nodeIndex.put(levelOrg.getCode(), nodes.indexOf(levelNode));
}
}
}
}
}
}
public TreeNode getRoot() {
return root;
}
public boolean isValidTree() {
return validTree;
}
}
2.5 Display the Tree on the Web Page
Now we have the tree and we need to display it. The best option is Prime Faces Ajax.
<c:if test="#{treeOrgView.validTree}" >
<h:form>
<p:tree value="#{treeOrgView.root}" var="node" dynamic="true">
<p:treeNode>
<p:commandLink value="#{node}" actionListener="#" update="@all" >
</p:commandLink>
</p:treeNode>
</p:tree>
</h:form>
16. BY JOBE BACWADI
</c:if>
2.6 That¨s It!
Now you can run the program and you have a tree.
Now wait for the next publication that deals with how to call tree with information and reports from different private clouds!