blob: 3bb831b409ba590073ae5eda21a883f71583d356 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre Allard,
* Regent L'Archeveque,
* Sebastien Gemme - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.common.topology.ui.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.apogy.common.topology.AbstractNodeVisitor;
import org.eclipse.apogy.common.topology.GroupNode;
import org.eclipse.apogy.common.topology.Node;
import org.eclipse.apogy.common.topology.ui.Activator;
import org.eclipse.apogy.common.topology.ui.ApogyCommonTopologyUIFactory;
import org.eclipse.apogy.common.topology.ui.NodePresentation;
import org.eclipse.apogy.common.topology.ui.NodePresentationAdapter;
import org.eclipse.apogy.common.topology.ui.TopologyPresentationSet;
import org.eclipse.apogy.common.topology.ui.internal.MultiNodeListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TopologyPresentationRegistryCustomImpl extends TopologyPresentationRegistryImpl {
private static final Logger Logger = LoggerFactory.getLogger(TopologyPresentationRegistryImpl.class);
private MultiNodeListener multiNodeListener = null;
private final Map<Node, NodePresentation> nodeToNodePresentationMap = new HashMap<Node, NodePresentation>(100);
@Override
public TopologyPresentationSet createTopologyPresentationSet(Node topologyRoot) {
final TopologyPresentationSet topologyPresentationSet = ApogyCommonTopologyUIFactory.eINSTANCE
.createTopologyPresentationSet();
// Visit the topology spanned by the topologyRoot.
AbstractNodeVisitor visitor = new AbstractNodeVisitor() {
@Override
public void visit(Node node) {
// Check to see if the registry already contains a NodePresentation associated
// with node.
NodePresentation nodePresentation = getPresentationNode(node);
// If no NodePresentation has been found, attempts to create one.
if (nodePresentation == null) {
nodePresentation = createNodePresentation(node);
// If a NodePresentation was successfully created, add it to the list
if (nodePresentation != null) {
addNodePresentation(nodePresentation);
}
}
// If a NodePresentation was found or created.
if (nodePresentation != null) {
// Adds the NodePresenation to the TopologyPresentationSet.
topologyPresentationSet.getNodePresentationList().add(nodePresentation);
// Adds the TopologyPresentationSet to the nodePresentation.
nodePresentation.getTopologyPresentationSet().add(topologyPresentationSet);
}
}
};
topologyRoot.accept(visitor);
getTopologyPresentationSetList().add(topologyPresentationSet);
return topologyPresentationSet;
}
public void release(final TopologyPresentationSet topologyPresentationSet) {
if (topologyPresentationSet != null) {
for (Node node : topologyPresentationSet.getNodes()) {
NodePresentation nodePresentation = getPresentationNode(node);
if (nodePresentation != null) {
nodePresentation.getTopologyPresentationSet().remove(topologyPresentationSet);
// If the NodePresentation is no longer in use, release it.
if (nodePresentation.getTopologyPresentationSet().isEmpty()) {
// Remove the nodePresentation
removeNodePresentation(nodePresentation);
}
}
}
// Have the TopologyPresentationSet release all references to Node, Node
// Presentation and TopologyPresentationRegistry.
topologyPresentationSet.getNodePresentationList().clear();
topologyPresentationSet.setTopologyPresentationRegistry(null);
}
}
@Override
public NodePresentation getPresentationNode(Node node) {
return this.nodeToNodePresentationMap.get(node);
}
private NodePresentation createNodePresentation(Node node) {
Logger.debug("TopologyPresentationRegistryImpl.createNodePresentation(" + node + ")");
NodePresentation nodePresentation = null;
// Gets the NodePresentation Adapter associated with the topology node.
NodePresentationAdapter adapter = Activator.getDefault().getNodePresentationAdapterFactory()
.getAdapterFor(node);
if (adapter != null) {
// Attempts to create the NodePresentation associated with the node.
nodePresentation = adapter.getAdapter(node, null);
}
return nodePresentation;
}
private synchronized void addNodePresentation(NodePresentation nodePresentation) {
// Adds the NodePresentation to the list of NodePresentation.
getNodePresentationList().add(nodePresentation);
// Adds the Node and its NodePresentation to the map.
this.nodeToNodePresentationMap.put(nodePresentation.getNode(), nodePresentation);
// Registers a listener to the underlying Node.
getMultiNodeListener().registerNode(nodePresentation.getNode());
// Update the affected TopologyPresentationSet
if (nodePresentation.getNode().getParent() instanceof GroupNode) {
// Here we need to check the parent node to figure out who is affected.
GroupNode parent = (GroupNode) nodePresentation.getNode().getParent();
List<TopologyPresentationSet> affectedTopologyPresentationSet = getAffectedTopologyPresentationSet(parent);
// Update each TopologyPresentationSet affected.
for (TopologyPresentationSet topologyPresentationSet : affectedTopologyPresentationSet) {
try {
topologyPresentationSet.getNodePresentationList().add(nodePresentation);
} catch (Throwable t) {
Logger.error(t.getMessage(), t);
}
}
}
}
private synchronized void removeNodePresentation(NodePresentation nodePresentation) {
// Un-Registers a listener from the underlying Node.
getMultiNodeListener().unregisterNode(nodePresentation.getNode());
// Here we need to check the node itself to figure out who is affected.
List<TopologyPresentationSet> affectedTopologyPresentationSet = new ArrayList<TopologyPresentationSet>(
nodePresentation.getTopologyPresentationSet());
// Update each TopologyPresentationSet affected.
for (TopologyPresentationSet topologyPresentationSet : affectedTopologyPresentationSet) {
try {
topologyPresentationSet.getNodePresentationList().remove(nodePresentation);
} catch (Throwable t) {
Logger.error(t.getMessage(), t);
}
}
// Removes the Node and its NodePresentation from the map.
this.nodeToNodePresentationMap.remove(nodePresentation.getNode());
// Removes the NodePresentation from the list.
getNodePresentationList().remove(nodePresentation);
}
private synchronized void addNodeAndChildrens(Node topologyRoot) {
Logger.debug("TopologyPresentationRegistryImpl.addNodeAndChildrens(" + topologyRoot + ")");
// Visit the topology spanned by the topologyRoot.
AbstractNodeVisitor visitor = new AbstractNodeVisitor() {
@Override
public void visit(Node node) {
Logger.debug("/t CHILD " + node);
NodePresentation nodePresentation = getPresentationNode(node);
// NodePresentation not created yet, create one.
if (nodePresentation == null) {
nodePresentation = createNodePresentation(node);
if (nodePresentation != null) {
addNodePresentation(nodePresentation);
} else {
Logger.warn("No NodePresentation found for node <" + node + ">.");
}
}
}
};
topologyRoot.accept(visitor);
}
private synchronized void removeNodeAndChildrens(Node topologyRoot) {
// Visit the topology spanned by the topologyRoot.
AbstractNodeVisitor visitor = new AbstractNodeVisitor() {
@Override
public void visit(Node node) {
NodePresentation nodePresentation = getPresentationNode(node);
if (nodePresentation != null) {
removeNodePresentation(nodePresentation);
}
}
};
topologyRoot.accept(visitor);
}
private MultiNodeListener getMultiNodeListener() {
if (this.multiNodeListener == null) {
this.multiNodeListener = new MultiNodeListener() {
@Override
protected void nodeAdded(GroupNode parent, Node nodeAdded) {
addNodeAndChildrens(nodeAdded);
}
@Override
protected void nodesAdded(GroupNode parent, List<Node> nodesAdded) {
for (Node node : nodesAdded) {
addNodeAndChildrens(node);
}
}
@Override
protected void nodeRemoved(GroupNode parent, Node nodeRemoved) {
removeNodeAndChildrens(nodeRemoved);
}
@Override
protected void nodesRemoved(GroupNode parent, List<Node> nodesRemoved) {
for (Node node : nodesRemoved) {
removeNodeAndChildrens(node);
}
}
};
}
return this.multiNodeListener;
}
private List<TopologyPresentationSet> getAffectedTopologyPresentationSet(Node node) {
List<TopologyPresentationSet> topologyPresentationSetList = new ArrayList<TopologyPresentationSet>();
NodePresentation nodePresentation = getPresentationNode(node);
if (nodePresentation != null) {
topologyPresentationSetList.addAll(nodePresentation.getTopologyPresentationSet());
}
return topologyPresentationSetList;
}
} // TopologyPresentationRegistryImpl