All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.bonita.deployment.IterationDetectionNoException Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2011-2012 BonitaSoft S.A.
 * BonitaSoft, 31 rue Gustave Eiffel - 38000 Grenoble
 * This library 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
 * version 2.1 of the License.
 * This library 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
 * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA  02110-1301, USA.
 **/
package org.ow2.bonita.deployment;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.ow2.bonita.facade.def.element.impl.IterationDescriptor;
import org.ow2.bonita.iteration.IterationNode;
import org.ow2.bonita.iteration.IterationNode.SplitType;
import org.ow2.bonita.iteration.IterationProcess;
import org.ow2.bonita.iteration.IterationTransition;

/**
 * @author Nicolas Chabanoles
 * @author Matthieu Chaffotte
 * 
 */
public class IterationDetectionNoException {

  private static final Logger LOG = Logger.getLogger(IterationDetection.class.getName());

  public static final String LINE_SEPARATOR = System.getProperty("line.separator");

  protected IterationDetectionNoException() {
    super();
  }

  /*
   * Implements a deep first search to list all the paths in the process.
* DFS (graph G, node s) { Mark(s); For each node n : Neighbour(s) do if * !marked(n) then DFS(G,n); End-if end } */ public static SortedSet findIterations(final IterationProcess inProcess) { final SortedMap allProcessNodes = inProcess.getNodes(); final SortedSet allPorcessNodesSorted = new TreeSet(allProcessNodes.values()); // store path during recursive search final List path = new ArrayList(allProcessNodes.size()); // store visited nodes final SortedSet visitedNodes = new TreeSet(); final SortedSet iterationDescriptors = new TreeSet(); for (final IterationNode sourceNode : allPorcessNodesSorted) { final SortedSet incomingTransitions = new TreeSet( sourceNode.getIncomingTransitions()); final SortedSet temporaryIterationDescriptors = new TreeSet(); for (final IterationTransition transition : incomingTransitions) { // List all paths form sourceNode to sourceNode, i.e. find all cycles. // We need to take care not to looping forever, that is why we need to // remember already visited nodes. listCycles(inProcess, sourceNode, transition.getSource(), path, visitedNodes, temporaryIterationDescriptors); iterationDescriptors.addAll(temporaryIterationDescriptors); } } return iterationDescriptors; } private static void listCycles(final IterationProcess inProcess, final IterationNode sourceNode, final IterationNode targetNode, final List path, final SortedSet visitedNodes, final SortedSet iterationDescriptors) { // Add node into the path. path.add(sourceNode); // SourceNode == targetNode --> stop recursive search if (sourceNode.getName().equals(targetNode.getName())) { final IterationDescriptor descriptor = buildIterationDescriptor(path); iterationDescriptors.add(descriptor); path.remove(sourceNode); return; } visitedNodes.add(sourceNode); // mark node // search recursively... final SortedSet outgoingTransitions = new TreeSet( sourceNode.getOutgoingTransitions()); for (final IterationTransition transition : outgoingTransitions) { if (!visitedNodes.contains(transition.getDestination())) { // do not follow transitions that points to a visited node to avoid // looping infinitely. listCycles(inProcess, transition.getDestination(), targetNode, path, visitedNodes, iterationDescriptors); } } visitedNodes.remove(sourceNode); // un-mark node path.remove(sourceNode); } /* * Build an iteration descriptor based on nodes in path. Entry nodes: nodes * that have an incoming transition from a node that do not belong to the * cycle. Exit nodes: nodes that have an outgoing transition to a node that do * not belong to the cycle. Other nodes: nodes that have an incoming * transition from a node that do not belong to the cycle. */ private static IterationDescriptor buildIterationDescriptor(final List path) { final List nodesInPath = getNodeNames(path); final SortedSet entryNodes = new TreeSet(); final SortedSet exitNodes = new TreeSet(); final SortedSet otherNodes = new TreeSet(); for (final IterationNode node : path) { final Set incomingTransitions = node.getIncomingTransitions(); final Set outgoingTransitions = node.getOutgoingTransitions(); final String nodeName = node.getName(); for (final IterationTransition transition : incomingTransitions) { if (!path.contains(transition.getSource())) { entryNodes.add(nodeName); } } for (final IterationTransition transition : outgoingTransitions) { if (!path.contains(transition.getDestination())) { exitNodes.add(nodeName); final SplitType splitType = node.getSplitType(); // Only allow XOR split for exit nodes if (!SplitType.XOR.equals(splitType) && LOG.isLoggable(Level.WARNING)) { final StringBuilder builder = new StringBuilder("Potential issue in iteration : "); builder.append(nodeName).append(" is an exit node for cycle ").append(nodesInPath).append('.') .append(LINE_SEPARATOR); builder.append("Split type of this node is ").append(splitType).append(" but only XOR is supported.") .append(LINE_SEPARATOR); builder .append("An exception will be thrown at runtime if more than one transition is enabled at the same time."); LOG.warning(builder.toString()); } } } if (!entryNodes.contains(nodeName) && !exitNodes.contains(nodeName)) { otherNodes.add(nodeName); } } return new IterationDescriptor(otherNodes, entryNodes, exitNodes); } private static List getNodeNames(final List path) { final List nodeNames = new ArrayList(); for (final IterationNode iterationNode : path) { nodeNames.add(iterationNode.getName()); } return nodeNames; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy