/* Copyright 2008-2010 Gephi Authors : Mathieu Bastian <mathieu.bastian@gephi.org> Website : http://www.gephi.org This file is part of Gephi. Gephi 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. Gephi 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 Gephi. If not, see <http://www.gnu.org/licenses/>. */ package org.gephi.graph.dhns.core; import java.util.HashMap; import java.util.Map; import org.gephi.utils.collection.avl.ParamAVLIterator; import org.gephi.graph.api.Attributes; import org.gephi.graph.api.Graph; import org.gephi.graph.api.Node; import org.gephi.graph.dhns.edge.AbstractEdge; import org.gephi.graph.dhns.edge.EdgeDataImpl; import org.gephi.graph.dhns.node.AbstractNode; import org.gephi.graph.dhns.node.NodeDataImpl; import org.gephi.graph.dhns.node.iterators.TreeListIterator; /** * * @author Mathieu Bastian */ public class DuplicateManager { private final Dhns dhns; public DuplicateManager(Dhns dhns) { this.dhns = dhns; } public void duplicate(Dhns destination) { duplicate(destination, dhns.getGraphStructure().getMainView()); } public void duplicate(Dhns destination, GraphViewImpl view) { GraphFactoryImpl factory = destination.factory(); dhns.readLock(); destination.writeLock(); TreeStructure treeStructure = view.getStructure(); GraphStructure newGraphStructure = destination.getGraphStructure(); TreeStructure newStructure = newGraphStructure.getMainView().getStructure(); //Nodes for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) { AbstractNode node = itr.next(); AbstractNode nodeCopy = factory.newNode(); duplicateNodeData(node.getNodeData(), nodeCopy.getNodeData()); nodeCopy.setEnabled(node.isEnabled()); nodeCopy.setEnabledInDegree(node.getEnabledInDegree()); nodeCopy.setEnabledOutDegree(node.getEnabledOutDegree()); nodeCopy.setEnabledMutualDegree(node.getEnabledMutualDegree()); AbstractNode parentCopy = node.parent != null ? newStructure.getNodeAt(node.parent.getPre()) : null; newStructure.insertAsChild(nodeCopy, parentCopy); newGraphStructure.addToDictionnary(nodeCopy); } //Edges ParamAVLIterator<AbstractEdge> edgeIterator = new ParamAVLIterator<AbstractEdge>(); for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) { AbstractNode node = itr.next(); if (!node.getEdgesOutTree().isEmpty()) { for (edgeIterator.setNode(node.getEdgesOutTree()); edgeIterator.hasNext();) { AbstractEdge edge = edgeIterator.next(); AbstractEdge edgeCopy; AbstractNode sourceCopy = newStructure.getNodeAt(edge.getSource(view.getViewId()).getPre()); AbstractNode targetCopy = newStructure.getNodeAt(edge.getTarget(view.getViewId()).getPre()); if (edge.isMixed()) { edgeCopy = factory.newEdge(edge.getEdgeData().getId(), sourceCopy, targetCopy, edge.getWeight(), edge.isDirected()); if (edge.isDirected()) { destination.touchDirected(); } else { destination.touchUndirected(); } } else { edgeCopy = factory.newEdge(sourceCopy, targetCopy); edgeCopy.setWeight(edge.getWeight()); destination.touchDirected(); } duplicateEdgeData(edge.getEdgeData(), edgeCopy.getEdgeData()); sourceCopy.getEdgesOutTree().add(edgeCopy); targetCopy.getEdgesInTree().add(edgeCopy); newGraphStructure.addToDictionnary(edgeCopy); } } } newGraphStructure.getMainView().setNodesEnabled(view.getNodesEnabled()); newGraphStructure.getMainView().setEdgesCountTotal(view.getEdgesCountTotal()); newGraphStructure.getMainView().setEdgesCountEnabled(view.getEdgesCountEnabled()); newGraphStructure.getMainView().setMutualEdgesTotal(view.getMutualEdgesTotal()); newGraphStructure.getMainView().setMutualEdgesEnabled(view.getMutualEdgesEnabled()); //Metaedges newGraphStructure.getMainView().getStructureModifier().getEdgeProcessor().computeMetaEdges(); destination.writeUnlock(); dhns.readUnlock(); } public void duplicateNodes(Dhns destination, Node[] nodes) { Map<AbstractNode, AbstractNode> nodeMap = new HashMap<AbstractNode, AbstractNode>(); GraphFactoryImpl factory = destination.factory(); Graph destGraph = null; if (dhns.isDirected()) { destGraph = destination.getDirectedGraph(); } else if (dhns.isUndirected()) { destGraph = destination.getUndirectedGraph(); } else { destGraph = destination.getMixedGraph(); } dhns.readLock(); destination.writeLock(); //Nodes for (Node sourceNode : nodes) { AbstractNode absSourceNode = (AbstractNode) sourceNode; AbstractNode nodeCopy = factory.newNode(sourceNode.getNodeData().getId()); destGraph.addNode(nodeCopy); duplicateNodeData((NodeDataImpl) sourceNode.getNodeData(), (NodeDataImpl) nodeCopy.getNodeData()); nodeMap.put(absSourceNode, nodeCopy); } //Edges ParamAVLIterator<AbstractEdge> edgeIterator = new ParamAVLIterator<AbstractEdge>(); for (Node sourceNode : nodes) { AbstractNode absSourceNode = (AbstractNode) sourceNode; AbstractNode nodeCopy = nodeMap.get(absSourceNode); int sourceView = absSourceNode.getViewId(); if (!absSourceNode.getEdgesOutTree().isEmpty()) { for (edgeIterator.setNode(absSourceNode.getEdgesOutTree()); edgeIterator.hasNext();) { AbstractEdge edge = edgeIterator.next(); AbstractNode originalTargetNode = edge.getTarget(sourceView); AbstractNode copyTargetNode = nodeMap.get(originalTargetNode); if (copyTargetNode != null) { AbstractEdge edgeCopy = factory.newEdge(edge.getEdgeData().getId(), nodeCopy, copyTargetNode, edge.getWeight(), edge.isDirected()); destGraph.addEdge(edgeCopy); duplicateEdgeData(edge.getEdgeData(), edgeCopy.getEdgeData()); } } } if (!absSourceNode.getMetaEdgesOutTree().isEmpty()) { for (edgeIterator.setNode(absSourceNode.getMetaEdgesOutTree()); edgeIterator.hasNext();) { AbstractEdge edge = edgeIterator.next(); AbstractNode originalTargetNode = edge.getTarget(sourceView); AbstractNode copyTargetNode = nodeMap.get(originalTargetNode); if (copyTargetNode != null) { AbstractEdge edgeCopy = factory.newEdge(edge.getEdgeData().getId(), nodeCopy, copyTargetNode, edge.getWeight(), edge.isDirected()); destGraph.addEdge(edgeCopy); duplicateEdgeData(edge.getEdgeData(), edgeCopy.getEdgeData()); } } } } destination.writeUnlock(); dhns.readUnlock(); } private void duplicateNodeData(NodeDataImpl source, NodeDataImpl dest) { dest.setX(source.x()); dest.setY(source.y()); dest.setZ(source.z()); dest.setR(source.r()); dest.setG(source.g()); dest.setB(source.b()); dest.setAlpha(source.alpha()); dest.setSize(source.getSize()); dest.getTextData().setColor(source.getTextData().getR(), source.getTextData().getG(), source.getTextData().getB(), source.getTextData().getAlpha()); dest.getTextData().setSize(source.getTextData().getSize()); dest.getTextData().setVisible(source.getTextData().isVisible()); //Attributes Attributes sourceAttributes = source.getAttributes(); for (int i = 0; i < sourceAttributes.countValues(); i++) { dest.getAttributes().setValue(i, sourceAttributes.getValue(i)); } } private void duplicateEdgeData(EdgeDataImpl source, EdgeDataImpl dest) { dest.setR(source.r()); dest.setG(source.g()); dest.setB(source.b()); dest.setAlpha(source.alpha()); dest.getTextData().setColor(source.getTextData().getR(), source.getTextData().getG(), source.getTextData().getB(), source.getTextData().getAlpha()); dest.getTextData().setSize(source.getTextData().getSize()); dest.getTextData().setVisible(source.getTextData().isVisible()); //Attributes Attributes sourceAttributes = source.getAttributes(); for (int i = 0; i < sourceAttributes.countValues(); i++) { dest.getAttributes().setValue(i, sourceAttributes.getValue(i)); } } }