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

org.ow2.bonita.persistence.xml.XMLHistory Maven / Gradle / Ivy

/**
 * Copyright (C) 2007  Bull S. A. S.
 * Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
 * 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.persistence.xml;

import com.thoughtworks.xstream.XStream;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.ow2.bonita.facade.def.majorElement.ActivityDefinition;
import org.ow2.bonita.facade.def.majorElement.PackageDefinition;
import org.ow2.bonita.facade.def.majorElement.PackageFullDefinition;
import org.ow2.bonita.facade.def.majorElement.ProcessDefinition;
import org.ow2.bonita.facade.def.majorElement.ProcessFullDefinition;
import org.ow2.bonita.facade.def.majorElement.impl.PackageFullDefinitionImpl;
import org.ow2.bonita.facade.runtime.ActivityBody;
import org.ow2.bonita.facade.runtime.ActivityFullInstance;
import org.ow2.bonita.facade.runtime.ActivityState;
import org.ow2.bonita.facade.runtime.ProcessFullInstance;
import org.ow2.bonita.facade.runtime.TaskInstance;
import org.ow2.bonita.facade.runtime.impl.ProcessFullInstanceImpl;
import org.ow2.bonita.facade.uuid.ActivityDefinitionUUID;
import org.ow2.bonita.facade.uuid.ActivityInstanceUUID;
import org.ow2.bonita.facade.uuid.PackageDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessInstanceUUID;
import org.ow2.bonita.facade.uuid.TaskUUID;
import org.ow2.bonita.persistence.QuerierUtil;
import org.ow2.bonita.services.Archivable;
import org.ow2.bonita.services.Archiver;
import org.ow2.bonita.services.Querier;
import org.ow2.bonita.util.BonitaRuntimeException;
import org.ow2.bonita.util.Misc;

/**
 *
 *
 * @author Pierre Vigneras
 * @date Feb 29, 2008
 */
public class XMLHistory implements Archiver, Querier {

  private static final String XML_EXTENSION = ".xml";
  private static final String INSTANCE_FILENAME_PREFIX = "instance-";
  private static final String PACKAGE_FILENAME_PREFIX = "package-";

  private static final String DEFINITION_FOLDER = "definitions";
  private static final String RUNTIME_FOLDER = "runtime";
  private static final Logger LOG = Logger.getLogger(XMLHistory.class.getName());

  private static final Object CONSTRUCTOR_MUTEX = new Object();
  
  private void logWrite(final Archivable archivable, final File file) {
    if (LOG.isLoggable(Level.FINE)) {
      LOG.fine("Writing: " + archivable + " to file: " + file);
    }
    Writer writer = null;
    try {
      writer = new FileWriter(file);
      writer.append(xstream.toXML(archivable));
      writer.flush();
    } catch (IOException e) {
      throw new BonitaRuntimeException(e);
    } finally {
      Misc.close(writer);
    }
  }

  private Object logRead(final Class< ? extends Archivable> clazz, final File file) {
    if (LOG.isLoggable(Level.FINE)) {
      LOG.fine("Fetching class: " + clazz.getName() + " from file: " + file);
    }
    Reader reader = null;
    try {
      reader = new FileReader(file);
      return xstream.fromXML(reader);
    } catch (IOException e) {
      throw new BonitaRuntimeException(e);
    } finally {
      Misc.close(reader);
    }
  }

  private final File base;
  private final XStream xstream;

  public XMLHistory() {
    this(new File(Misc.TMP_DIR, "Bonita"));
  }

  public XMLHistory(final String path) {
    this(new File(path));
  }

  public XMLHistory(final File path) {
    this.base = new File(path, "history");
    if (LOG.isLoggable(Level.CONFIG)) {
      LOG.config("Configuring history: " + XMLHistory.class.getName() + " with base: " + base);
    }
    // if history directory does not exist, create it in mutual exclusion
    // all is done in synchronized blocks, because double-checked locking pattern is broken
    synchronized (CONSTRUCTOR_MUTEX) {
      if (this.base.exists()) {
        if (!this.base.isDirectory() || !this.base.canRead() || !this.base.canWrite()) {
          throw new BonitaRuntimeException("Given history base: " + path + " should be a readable and writable directory!");
        }
      } else if (!this.base.mkdirs()) {
        throw new BonitaRuntimeException("Can't create base: " + path);
      }  
    }
    this.xstream = new XStream();
  }

  /*
   * PROCESS INSTANCE
   */

  public void archive(ProcessFullInstance processInst) {
    ProcessFullInstance newInstance = new ProcessFullInstanceImpl(processInst);
    //newInstance.end();
    final File file = getFile(processInst.getProcessDefinitionUUID(),
        processInst.getProcessInstanceUUID(), INSTANCE_FILENAME_PREFIX);
    checkDuplicate(newInstance, file);
    checkWritable(file);
    logWrite(newInstance, file);
  }

  public void remove(ProcessFullInstance processInst) {
    final File file = getFile(processInst.getProcessDefinitionUUID(),
        processInst.getProcessInstanceUUID(), INSTANCE_FILENAME_PREFIX);
    deleteFile(file);
  }

  // points to: base/RUNTIME_FOLDER/processDefinitionUUID/INSTANCE_FILENAME_PREFIX+processUUID.xml
  private File getFile(final ProcessDefinitionUUID processUUID, final ProcessInstanceUUID instanceUUID, final String prefix) {
    Misc.checkArgsNotNull(processUUID, instanceUUID);
    final File runtimeFolderBase = new File(base, RUNTIME_FOLDER);
    File processFolder = new File(runtimeFolderBase, processUUID.toString());
    final File instanceFile = new File(processFolder, prefix + instanceUUID.toString() + XML_EXTENSION);
    return instanceFile;
  }

  public ProcessFullInstance getProcessInstance(ProcessInstanceUUID instanceUUID) {
    Misc.checkArgsNotNull(instanceUUID);
    final File runtimeFolder = new File(base, RUNTIME_FOLDER);
    final File[] processFolders = runtimeFolder.listFiles();
    if (processFolders == null) {
      return null;
    }
    for (File processFolder : processFolders) {
      File[] instanceFiles = processFolder.listFiles();
      if (instanceFiles != null) {
        for (File instanceFile : instanceFiles) {
          if (instanceFile.getName().equals(INSTANCE_FILENAME_PREFIX + instanceUUID.toString() + ".xml")) {
            return (ProcessFullInstance) logRead(ProcessFullInstance.class, instanceFile);
          }
        }
      }
    }
    return null;
  }

  public Set getProcessInstances() {
    return getAllInstances();
  }

  public Set getProcessInstances(ProcessDefinitionUUID processUUID) {
    Misc.checkArgsNotNull(processUUID);
    final Set result = new HashSet();
    final File runtimeFolder = new File(base, RUNTIME_FOLDER);
    File processFolder = new File(runtimeFolder, processUUID.toString());
    if (processFolder.exists()) {
      File[] instanceFiles = processFolder.listFiles();
      if (instanceFiles != null) {
        for (File instanceFile : instanceFiles) {
          result.add((ProcessFullInstance) logRead(ProcessFullInstance.class, instanceFile));
        }
      }
    }
    return result;
  }

  @SuppressWarnings("unchecked")
  public ActivityFullInstance< TaskInstance > getTaskInstance(TaskUUID taskUUID) {
    Misc.checkArgsNotNull(taskUUID);
    Set instances = getAllInstances();
    if (instances != null) {
      for (ProcessFullInstance instance : instances) {
        Set> activities = getActivityInstances(instance.getProcessInstanceUUID());
        if (activities != null) {
          for (ActivityFullInstance< ? > activity : activities) {
            ActivityBody body = activity.getBody();
            if (body != null && body instanceof TaskInstance && body.getUUID().equals(taskUUID)) {
              return (ActivityFullInstance) activity;
            }
          }
        }
      }
    }
    return null;
  }

  private Set getAllInstances() {
    Set instances = new HashSet();
    final File runtimeFolder = new File(base, RUNTIME_FOLDER);
    final File[] processFolders = runtimeFolder.listFiles();
    if (processFolders == null) {
      return null;
    }
    for (File processFolder : processFolders) {
      for (File instanceFile : processFolder.listFiles()) {
        instances.add((ProcessFullInstance) logRead(ProcessFullInstance.class, instanceFile));
      }
    }
    return instances;
  }

  public File getBasePath() {
    return base;
  }


  private void checkWritable(final File file) {
    final File parent = file.getParentFile();
    if (!parent.exists() && !parent.mkdirs()) {
      // This test can fail because:
      // - mkdir failed because of security exception, or disk full ...
      // in this case an exception should be thrown
      // - the directory has been created after calling exists() test and before mkdir() has been called.
      // in this situation, there is no failure.
      // To solve this, we can add locks in this method,
      // or we can just check again that parent does not exist.
      // We choose the last solution.
      // TODO: see if the first call to exists() can be removed
      if (!parent.exists()) {
        throw new BonitaRuntimeException("Can't create path: " + parent);
      }
    }
  }

  private void checkDuplicate(final Archivable archivable, final File file) {
    if (file.exists()) {
      throw new IllegalArgumentException(" Can't archive: " + archivable
          + " --- A record with processDefinitionUUID: "
          + archivable + " has already been archived in file: " + file);
    }
  }

  public void clear() {
    if (LOG.isLoggable(Level.CONFIG)) {
      LOG.config("Clearing history: " + this + ". Deleting recursively directory: " + base);
    }
    Misc.deleteDir(getBasePath());
  }

  /*
   * DEFINITION
   */

  public void archive(PackageFullDefinition packageDef) {
    packageDef = new PackageFullDefinitionImpl(packageDef);
    //packageDef.end();
    final File file = getFile(packageDef.getUUID());
    checkWritable(file);
    logWrite(packageDef, file);
  }

  public void remove(PackageFullDefinition packageDef) {
    final File file = getFile(packageDef.getUUID());
    deleteFile(file);
  }

  private void deleteFile(File f) {
    boolean deleted = false;
    int retry = 5;
    while (!deleted && retry > 0)  {
      deleted = f.delete();
      retry--;
    }
    if (!deleted) {
      throw new RuntimeException("Impossible to delete file : " + f + " from " + this.getClass());
    }
  }
  //points to: base/DEFINITION_FOLDER/PACKAGE_FILENAME_PREFIX+packageUUID.xml
  private File getFile(PackageDefinitionUUID packageUUID) {
    final File definitionFolder = new File(base, DEFINITION_FOLDER);
    final File packageFile = new File(definitionFolder, PACKAGE_FILENAME_PREFIX + packageUUID + XML_EXTENSION);
    return packageFile;
  }

  public Set getPackages() {
    final Set result = new HashSet();
    final File definitionFolder = new File(base, DEFINITION_FOLDER);
    final File[] packageFiles = definitionFolder.listFiles();
    if (packageFiles == null) {
      return result;
    }
    for (File packageFile : packageFiles) {
      result.add((PackageFullDefinition) logRead(PackageFullDefinition.class, packageFile));
    }
    return result;
  }

  public PackageFullDefinition getPackage(PackageDefinitionUUID packageUUID) {

    Misc.checkArgsNotNull(packageUUID);
    File file = getFile(packageUUID);
    if (!file.exists()) {
      return null;
    }
    return (PackageFullDefinition) logRead(PackageFullDefinition.class, file);
  }

  public ActivityFullInstance getActivityInstance(
      ActivityInstanceUUID activityInstanceUUID) {

    Misc.checkArgsNotNull(activityInstanceUUID);
    Set instances = getAllInstances();
    if (instances != null) {
      for (ProcessFullInstance instance : instances) {
        Set> activities = instance.getActivities();
        if (activities != null) {
          for (ActivityFullInstance activity : activities) {
            if (activity.getUUID().equals(activityInstanceUUID)) {
              return activity;
            }
          }
        }
      }
    }
    return null;
  }

  public Set> getUserInstanceTasks(
      String userId, ProcessInstanceUUID instanceUUID, ActivityState taskState) {
    Misc.checkArgsNotNull(instanceUUID, taskState);
    ProcessFullInstance instance = getProcessInstance(instanceUUID);
    Set> result = new HashSet>();

    if (instance == null) {
      return result;
    }

    result.addAll(QuerierUtil.getUserTasks(instance.getActivities(), userId, taskState));

    return result;
  }

  

  public Set> getUserTasks(String userId, ActivityState taskState) {
    Set> result = new HashSet>();
    Set instances = getAllInstances();
    if (instances != null) {
      for (ProcessFullInstance instance : instances)   {
        Set> activities = instance.getActivities();
        if (activities != null) {
          Set> taskActivities = QuerierUtil.getUserTasks(activities, userId, taskState);
          if (taskActivities != null) {
            result.addAll(taskActivities);
          }
        }
      }
    }
    return result;
  }

  public ActivityFullInstance getActivityInstance(ProcessInstanceUUID instanceUUID,
      String activityId, String iterationId, String activityInstanceId) {
    Misc.checkArgsNotNull(instanceUUID, activityId, iterationId, activityInstanceId);
    ProcessFullInstance instance = getProcessInstance(instanceUUID);
    if (instance == null) {
      return null;
    }
    return instance.getActivity(activityId, iterationId, activityInstanceId);
  }

  public Set> getActivityInstances(ProcessInstanceUUID instanceUUID) {
    Misc.checkArgsNotNull(instanceUUID);
    ProcessFullInstance instance = getProcessInstance(instanceUUID);
    if (instance == null) {
      return new HashSet>();
    }
    Set> result = instance.getActivities();
    if (result == null) {
      return new HashSet>();
    }
    return result;
  }

  @SuppressWarnings("unchecked")
  public Set> getTaskInstances(ProcessInstanceUUID instanceUUID) {
    Misc.checkArgsNotNull(instanceUUID);
    final Set> result = new HashSet>();

    Set> activities = getActivityInstances(instanceUUID);
    if (activities != null) {
      for (ActivityFullInstance< ? > activity : activities) {
        ActivityBody body = activity.getBody();
        if (body != null && body instanceof TaskInstance) {
          result.add((ActivityFullInstance) activity);
        }
      }
    }
    return result;
  }

  public Set getPackages(String packageId) {
    Misc.checkArgsNotNull(packageId);
    Set packages = getPackages();
    Set result = new HashSet();
    if (packages != null) {
      for (PackageFullDefinition package1 : packages) {
        if (package1.getPackageId().equals(packageId)) {
          result.add(package1);
        }
      }
    }
    return result;
  }

  public ProcessFullDefinition getPackageProcess(
      PackageDefinitionUUID packageDefinitionUUID, String processId) {

    Misc.checkArgsNotNull(packageDefinitionUUID, processId);
    PackageFullDefinition packageDef = getPackage(packageDefinitionUUID);
    if (packageDef != null) {
      Set processes = packageDef.getProcesses();
      for (ProcessFullDefinition process : processes) {
        if (process.getProcessId().equals(processId)) {
          return process;
        }
      }
    }
    return null;
  }


  public Set getPackages(PackageDefinition.PackageState packageState) {
    Misc.checkArgsNotNull(packageState);
    Set packages = getPackages();
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    Set result = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      if (PackageDefinition.PackageState.DEPLOYED.equals(packageState) && package1.getUndeployedBy() == null) {
        result.add(package1);
      } else if (PackageDefinition.PackageState.UNDEPLOYED.equals(packageState)) {
        result.add(package1);
      }
    }
    return result;
  }

  public Set getPackages(String packageId, PackageDefinition.PackageState packageState) {
    Set packages = getPackages(packageId);
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    Set result = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      if (PackageDefinition.PackageState.DEPLOYED.equals(packageState) && package1.getUndeployedBy() == null) {
        result.add(package1);
      } else if (PackageDefinition.PackageState.UNDEPLOYED.equals(packageState)) {
        result.add(package1);
      }
    }
    return result;
  }

  public PackageFullDefinition getLastDeployedPackage(String packageId, PackageDefinition.PackageState packageState) {
    Set packages = getPackages(packageId, packageState);
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    PackageFullDefinition last = null;
    for (PackageFullDefinition package1 : packages) {
      if (last == null || package1.getDeployedDate().after(last.getDeployedDate())) {
        last = package1;
      }
    }
    return last;
  }

  public Set getPackageProcesses(PackageDefinitionUUID packageId) {
    PackageFullDefinition package1 = getPackage(packageId);
    if (package1 == null) {
      return null;
    }
    return package1.getProcesses();
  }

  public Set getProcesses() {
    Set packages = getPackages();
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    Set result = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      Set processes = package1.getProcesses();
      if (processes != null && !processes.isEmpty()) {
        result.addAll(processes);
      }
    }
    return result;
  }

  public Set getPackageProcesses(String packageId, String processId) {
    Set packages = getPackages(packageId);
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    Set result = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      Set processes = package1.getProcesses();
      if (processes != null && !processes.isEmpty()) {
        for (ProcessFullDefinition process : processes) {
          if (process.getProcessId().equals(processId)) {
            result.add(process);
          }
        }
      }
    }
    return result;
  }
  
  public Set getProcesses(String processId) {
    Set packages = getPackages();
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    Set result = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      Set processes = package1.getProcesses();
      if (processes != null && !processes.isEmpty()) {
        for (ProcessFullDefinition process : processes) {
          if (process.getProcessId().equals(processId)) {
            result.add(process);
          }
        }
      }
    }
    return result;
  }

  public Set getProcesses(String processId, String version) {
    Set packages = getPackages();
    if (packages == null || packages.isEmpty()) {
      return new HashSet();
    }
    Set returnProcesses = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      Set processes = package1.getProcesses();
      if (processes != null && !processes.isEmpty()) {
        for (ProcessFullDefinition process : processes) {
          if (process.getProcessId().equals(processId) && process.getVersion().equals(version)) {
            returnProcesses.add(process);
          }
        }
      }
    }
    return returnProcesses;
  }

  public Set getProcesses(ProcessDefinition.ProcessState processState) {
    Set packages = getPackages();
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    Set result = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      boolean match = false;
      if (ProcessDefinition.ProcessState.DEPLOYED.equals(processState) && package1.getUndeployedBy() == null) {
        match = true;
      } else if (ProcessDefinition.ProcessState.UNDEPLOYED.equals(processState)) {
        match = true;
      }
      if (match) {
        Set processes = package1.getProcesses();
        if (processes != null && !processes.isEmpty()) {
          result.addAll(processes);
        }
      }
    }
    return result;
  }

  public Set getProcesses(String processId, ProcessDefinition.ProcessState processState) {
    Set packages = getPackages();
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    Set result = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      boolean match = false;
      if (ProcessDefinition.ProcessState.DEPLOYED.equals(processState) && package1.getUndeployedBy() == null) {
        match = true;
      } else if (ProcessDefinition.ProcessState.UNDEPLOYED.equals(processState)) {
        match = true;
      }
      if (match) {
        Set processes = package1.getProcesses();
        for (ProcessFullDefinition process : processes) {
          if (process.getProcessId().equals(processId)) {
            result.add(process);
          }
        }
      }
    }
    return result;
  }
  
  public Set getProcesses(
    String packageId, String processId, ProcessDefinition.ProcessState processState) {
    Set packages = getPackages(packageId);
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    Set result = new HashSet();
    for (PackageFullDefinition package1 : packages) {
      boolean match = false;
      if (ProcessDefinition.ProcessState.DEPLOYED.equals(processState) && package1.getUndeployedBy() == null) {
        match = true;
      } else if (ProcessDefinition.ProcessState.UNDEPLOYED.equals(processState)) {
        match = true;
      }
      if (match) {
        Set processes = package1.getProcesses();
        for (ProcessFullDefinition process : processes) {
          if (process.getProcessId().equals(processId)) {
            result.add(process);
          }
        }
      }
    }
    return result;
  }

  public ProcessFullDefinition getProcess(ProcessDefinitionUUID processUUID) {
    Set packages = getPackages();
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    for (PackageFullDefinition package1 : packages) {
      Set processes = package1.getProcesses();
      if (processes != null && !processes.isEmpty()) {
        for (ProcessFullDefinition process : processes) {
          if (process.getUUID().equals(processUUID)) {
            return process;
          }
        }
      }
    }
    return null;
  }
  public ProcessFullDefinition getProcess(String packageId, String processId, String version) {
    Set packages = getPackages(packageId);
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    for (PackageFullDefinition package1 : packages) {
      Set processes = package1.getProcesses();
      if (processes != null && !processes.isEmpty()) {
        for (ProcessFullDefinition process : processes) {
          if (process.getProcessId().equals(processId) && process.getVersion().equals(version)) {
            return process;
          }
        }
      }
    }
    return null;
  }

  public PackageFullDefinition getPackage(String packageId, String version) {
    Misc.checkArgsNotNull(packageId);
    Set packages = getPackages();
    if (packages != null) {
      for (PackageFullDefinition package1 : packages) {
        if (package1.getPackageId().equals(packageId) && package1.getVersion().equals(version)) {
          return package1;
        }
      }
    }
    return null;
  }

  public ProcessFullDefinition getLastDeployedProcess(
    String packageId, String processId, ProcessDefinition.ProcessState processState) {
    PackageDefinition.PackageState packageState = PackageDefinition.PackageState.DEPLOYED;
    if (processState.equals(ProcessDefinition.ProcessState.UNDEPLOYED)) {
      packageState = PackageDefinition.PackageState.UNDEPLOYED;
    }
    Set packages = getPackages(packageId, packageState);
    if (packages == null || packages.isEmpty()) {
      return null;
    }
    PackageFullDefinition lastPackage = null;
    ProcessFullDefinition lastProcess = null;
    for (PackageFullDefinition package1 : packages) {
      if (lastPackage == null) {
        lastPackage = package1;
      }
      Set processes = package1.getProcesses();
      if (processes != null && !processes.isEmpty()) {
        for (ProcessFullDefinition process : processes) {
          if (process.getProcessId().equals(processId)) {
            if (lastProcess == null || package1.getDeployedDate().after(lastPackage.getDeployedDate())) {
              lastPackage = package1;
              lastProcess = process;
            }
          }
        }
      }
    }
    return lastProcess;
  }

  public Set getDependentPackages(PackageDefinitionUUID packageUUID) {
    Set result = new HashSet();
    Set deployedPackages = getPackages(PackageDefinition.PackageState.DEPLOYED);
    for (PackageFullDefinition package1 : deployedPackages) {
      if (!package1.getPackageDefinitionUUID().equals(packageUUID)) {
        if (package1.getPackageDependencies() != null && package1.getPackageDependencies().contains(packageUUID)) {
          result.add(package1);
        }
      }
    }
    return result;
  }

  public ActivityDefinition getActivity(ActivityDefinitionUUID activityDefinitionUUID) {
    Set processes = getProcesses();
    if (processes != null) {
      for (ProcessFullDefinition process : processes) {
        Set activities = process.getActivities();
        if (activities != null) {
          for (ActivityDefinition activity : activities) {
            if (activity.getUUID().equals(activityDefinitionUUID)) {
              return activity;
            }
          }
        }
      }
    }
    return null;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy