
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