/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jbpm.pvm.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.jbpm.pvm.CompositeElement;
import org.jbpm.pvm.Node;
import org.jbpm.pvm.VariableDefinition;
/**
* @author Tom Baeyens
*/
public class CompositeElementImpl extends ObservableElementImpl implements CompositeElement {
private static final long serialVersionUID = 1L;
protected List<NodeImpl> nodes;
protected boolean hasVariableDefinitions;
protected List<VariableDefinitionImpl> variableDefinitions;
transient protected Map<String, NodeImpl> nodesMap;
// nested nodes /////////////////////////////////////////////////////////////
/**
* creates a nested node. Also the nested node's parent pointer will be set
* appropriatly.
*/
public Node createNode() {
return createNode(null);
}
/**
* creates a nested node with the given name. Also the nested node's parent pointer will be set
* appropriatly.
* @param nodeName may be null.
*/
public NodeImpl createNode(String nodeName) {
NodeImpl node = new NodeImpl();
node.setName(nodeName);
addNode(node);
return node;
}
public Node addNode(NodeImpl node) {
node.setProcessDefinition(processDefinition);
if (nodes==null) {
nodes = new ArrayList<NodeImpl>();
}
if (! nodes.contains(node)) {
nodes.add(node);
}
nodesMap = null;
return node;
}
/** removes the given node from the nested activities.
* Also the node's parent will be nulled.
* This method will do nothing if the node is null or if
* the node is not in the list of nested activities.
* If the node is actually removed from the list of
* activities, the node's source will be nulled.
* In case this is the node that was in the
* activitiesMap and another node exists with the same
* name, that node (the first) will be put in the
* activitiesMap as a replacement for the removed node.
*/
public boolean removeNode(NodeImpl node) {
if ( (node!=null)
&& (nodes!=null)
) {
boolean isRemoved = nodes.remove(node);
if (isRemoved) {
node.setParentNode(null);
if (nodes.isEmpty()) {
nodes = null;
}
nodesMap = null;
}
return isRemoved;
}
return false;
}
/** the first nested node with the given name or null of no
* such node exists.
*/
public NodeImpl getNode(String nodeName) {
return (getNodesMap()!=null ? nodesMap.get(nodeName) : null);
}
/** is this node present ? */
public boolean hasNode(String nodeName) {
return ((getNodesMap()!=null) && (nodesMap.containsKey(nodeName)));
}
public Node findNode(String nodeName) {
if (nodes!=null) {
for(NodeImpl n : nodes) {
Node node = n.findNode(nodeName);
if (node!=null) {
return node;
}
}
}
return null;
}
/** the list of nested activities.
* Beware: the actual member is returned. No copy is made.
*/
public List<Node> getNodes() {
return (List) nodes;
}
/** the nested activities, keyed by node name. If a node with
* the same name occurs mutltiple times, the first in the list
* is included in the map.
* Activities with a null value for their name are not included
* in the map.
* Beware: the actual member is returned. No copy is made.
*/
public Map<String, Node> getNodesMap() {
if(nodesMap == null){
this.nodesMap = NodeImpl.getNodesMap(nodes);
}
return (Map) nodesMap;
}
/** indicates if this processDefinition has nodes. */
public boolean hasNodes() {
return ((nodes!=null) && (!nodes.isEmpty()));
}
// variable definitions /////////////////////////////////////////////////////
public List<VariableDefinition> getVariableDefinitions() {
return (List) variableDefinitions;
}
public void setVariableDefinitions(List<VariableDefinitionImpl> variableDefinitions) {
this.variableDefinitions = variableDefinitions;
}
}