/* * Lokomo OneCMDB - An Open Source Software for Configuration * Management of Datacenter Resources * * Copyright (C) 2006 Lokomo Systems AB * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * Lokomo Systems AB can be contacted via e-mail: info@lokomo.com or via * paper mail: Lokomo Systems AB, Sv�rdv�gen 27, SE-182 33 * Danderyd, Sweden. * */ package org.onecmdb.core.utils.graph.result; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import org.onecmdb.core.utils.bean.CiBean; import org.onecmdb.core.utils.bean.ValueBean; import org.onecmdb.core.utils.graph.query.constraint.RelationConstraint; import org.onecmdb.core.utils.wsdl.RFCBean; /** * <code>Graph</code> is the result from a graph query. * The graph is organized so the nodes and edges are group * by the templates that are derived from. * */ public class Graph extends NamedItem { private static final long serialVersionUID = 1L; private transient HashMap<String, HashMap<String, Template>> edgeSources = new HashMap<String, HashMap<String, Template>>(); private transient HashMap<String, HashMap<String, Template>> edgeTargets = new HashMap<String, HashMap<String, Template>>(); private transient HashMap<String, CiBean> nodeMap = new HashMap<String, CiBean>(); private transient HashMap<String, CiBean> edgeMap = new HashMap<String, CiBean>(); private transient HashMap<String, String> templateIdMap = new HashMap<String, String>(); private transient HashMap<Long, List<RFCBean>> rfcMap = new HashMap<Long, List<RFCBean>>(); private List<Template> nodes = new ArrayList<Template>(); private List<Template> edges = new ArrayList<Template>(); private boolean mapBuild = false; public void addNodes(Template t) { this.nodes.add(t); } public void addEdges(Template t) { this.edges.add(t); } public List<Template> getNodes() { return(this.nodes); } public List<Template> getEdges() { return(this.edges); } public void setNodes(List<Template> templates) { this.nodes = templates; } public void setEdges(List<Template> edges) { this.edges = edges; } public Template fetchNode(String id) { for (Template t : this.nodes) { if (t.getId().equals(id)) { return(t); } } return(null); } public Template fetchEdge(String id) { for (Template t : this.edges) { if (t.getId().equals(id)) { return(t); } } return(null); } public CiBean findOffspringAlias(String alias) { return(this.nodeMap.get(alias)); } public CiBean findEdgeBean(String alias) { return(this.edgeMap.get(alias)); } public Collection<CiBean> fetchAllNodeOffsprings() { return(this.nodeMap.values()); } public void buildMap() { for (Template template : this.nodes) { templateIdMap.put(template.getAlias(), template.getId()); for (CiBean offspring : template.getOffsprings()) { nodeMap.put(offspring.getAlias(), offspring); templateIdMap.put(offspring.getAlias(), template.getId()); } for (RFCBean rfc : template.getRFC()) { // Build rfcs map. Long id = rfc.getTargetCIId(); if (id != null) { List<RFCBean> beans = rfcMap.get(id); if (beans == null) { beans = new ArrayList<RFCBean>(); rfcMap.put(id, beans); } beans.add(rfc); } } } for (Template edge : this.edges) { HashMap<String, Template> targetMap = new HashMap<String, Template>(); HashMap<String, Template> sourceMap = new HashMap<String, Template>(); for (CiBean edgeBean : edge.getOffsprings()) { edgeMap.put(edgeBean.getAlias(), edgeBean); String sAlias = getValue(edgeBean, "source"); String tAlias = getValue(edgeBean, "target"); CiBean target = nodeMap.get(tAlias); CiBean source = nodeMap.get(sAlias); if (target == null || source == null) { continue; } Template sources = targetMap.get(target.getAlias()); if (sources == null) { sources = new Template(); sources.setId(templateIdMap.get(source.getAlias())); sources.setTemplate(fetchNode(sources.getId()).getTemplate()); targetMap.put(target.getAlias(), sources); } sources.addOffspring(source); Template targets = sourceMap.get(source.getAlias()); if (targets == null) { targets = new Template(); targets.setId(templateIdMap.get(target.getAlias())); targets.setTemplate(fetchNode(targets.getId()).getTemplate()); sourceMap.put(source.getAlias(), targets); } targets.addOffspring(target); } edgeSources.put(edge.getId(), sourceMap); edgeTargets.put(edge.getId(), targetMap); } mapBuild = true; } private String getValue(CiBean b, String alias) { ValueBean vBean = b.fetchAttributeValueBean(alias,0); if (vBean == null) { return(null); } return(vBean.getValue()); } /** * The direction indicates if the input bean is a source or a target.<br> * The values are defined as follow * <pre> * RelationConstraint.SOURCE * RelationConstraint.TARGET * </pre> * @param bean * @param direction * @param refId * @return */ public Template fetchReference(CiBean bean, int direction, String refId) { if (bean == null) { return(new Template()); } if (!mapBuild) { buildMap(); } HashMap<String, Template> map = null; if (direction == RelationConstraint.SOURCE) { map = edgeSources.get(refId); } else { map = edgeTargets.get(refId); } if (map == null) { return(new Template()); } Template t = map.get(bean.getAlias()); if (t == null) { t = new Template(); } return(t); } public List<RFCBean> fetchRFCs(CiBean bean) { List<RFCBean> beans = rfcMap.get(bean.getId()); if (beans == null) { return(Collections.EMPTY_LIST); } return(beans); } public String toString() { StringBuffer b = new StringBuffer(); b.append("Graph:\n"); for (Template t : getNodes()) { b.append("\tNode<" + t.getId() + ">{" + "offsprings=" + t.getOffsprings().size() + ", rfcs=" + t.getRFC().size() + ", txs=" + t.getTransactions().size() + "} totalCount=" + t.getTotalCount() + "\n"); } for (Template t : getEdges()) { b.append("\tEdge<" + t.getId() + ">{" + "offsprings=" + t.getOffsprings().size() + ", rfcs=" + t.getRFC().size() + ", txs=" + t.getTransactions().size() + "} totalCount=" + t.getTotalCount() + "\n"); } return(b.toString()); } }