/*
|
* 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.internal.repository;
|
|
import java.io.ByteArrayInputStream;
|
import java.io.InputStream;
|
import java.util.List;
|
import java.util.Map;
|
|
import org.jbpm.api.ProcessDefinition;
|
import org.jbpm.api.ProcessDefinitionQuery;
|
import org.jbpm.internal.log.Log;
|
import org.jbpm.pvm.internal.env.EnvironmentImpl;
|
import org.jbpm.pvm.internal.migration.InstanceMigrator;
|
import org.jbpm.pvm.internal.migration.MigrationDescriptor;
|
import org.jbpm.pvm.internal.model.ProcessDefinitionImpl;
|
import org.jbpm.pvm.internal.session.RepositorySession;
|
import org.jbpm.pvm.internal.xml.Parse;
|
import org.jbpm.pvm.internal.xml.Parser;
|
|
|
/**
|
* @author Tom Baeyens
|
*/
|
public class ProcessDeployer implements Deployer {
|
|
private static final Log log = Log.getLog(ProcessDeployer.class.getName());
|
|
protected String extension;
|
protected Parser parser;
|
|
public ProcessDeployer(String extension, Parser parser) {
|
this.extension = extension;
|
this.parser = parser;
|
}
|
|
@SuppressWarnings("unchecked")
|
public void deploy(DeploymentImpl deployment) {
|
|
for (String resourceName: deployment.getResourceNames()) {
|
|
if (resourceName.endsWith(extension)) {
|
byte[] bytes = deployment.getBytes(resourceName);
|
InputStream inputStream = new ByteArrayInputStream(bytes);
|
Parse parse = parser.createParse();
|
parse.contextMapPut(Parse.CONTEXT_KEY_DEPLOYMENT, deployment);
|
parse.setProblems(deployment.getProblems());
|
parse.setInputStream(inputStream);
|
parse.execute();
|
List<ProcessDefinitionImpl> processDefinitions = (List<ProcessDefinitionImpl>) parse.getDocumentObject();
|
if (processDefinitions!=null) {
|
for (ProcessDefinitionImpl processDefinition : processDefinitions) {
|
if ((processDefinition != null) && (processDefinition.getName() != null)) {
|
String processDefinitionName = processDefinition.getName();
|
|
processDefinition.setSuspended(deployment.isSuspended());
|
|
String imageResourceName = resourceName.substring(0, resourceName.lastIndexOf(extension)) + ".png";
|
if (deployment.getResourceNames().contains(imageResourceName)) {
|
processDefinition.setImageResourceName(imageResourceName);
|
}
|
|
processDefinition.setDeploymentDbid(deployment.getDbid());
|
|
if (deployment.hasObjectProperties(processDefinitionName)) {
|
String key = deployment.getProcessDefinitionKey(processDefinitionName);
|
String id = deployment.getProcessDefinitionId(processDefinitionName);
|
Long version = deployment.getProcessDefinitionVersion(processDefinitionName);
|
processDefinition.setId(id);
|
processDefinition.setKey(key);
|
processDefinition.setVersion(version.intValue());
|
|
} else {
|
checkKey(processDefinition, deployment);
|
checkVersion(processDefinition, deployment);
|
checkId(processDefinition, deployment);
|
|
deployment.setProcessDefinitionId(processDefinitionName, processDefinition.getId());
|
deployment.setProcessDefinitionKey(processDefinitionName, processDefinition.getKey());
|
deployment.setProcessDefinitionVersion(processDefinitionName, new Long(processDefinition.getVersion()));
|
|
//execute migration
|
Map<ProcessDefinition, MigrationDescriptor> migrations = (Map<ProcessDefinition, MigrationDescriptor>)parse.contextMapGet(Parse.CONTEXT_KEY_MIGRATIONS);
|
if (migrations != null) {
|
MigrationDescriptor migrationDescriptor = migrations.get(processDefinition);
|
if (migrationDescriptor != null) {
|
InstanceMigrator.migrateAll(processDefinition, migrationDescriptor);
|
}
|
}
|
|
}
|
|
deployment.addObject(processDefinitionName, processDefinition);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
protected void checkKey(ProcessDefinitionImpl processDefinition, DeploymentImpl deployment) {
|
String processDefinitionName = processDefinition.getName();
|
String processDefinitionKey = processDefinition.getKey();
|
|
// if no key was specified in the jpdl process file
|
if (processDefinitionKey==null) {
|
// derive the key from the name
|
// replace any non-word character with an underscore
|
processDefinitionKey = processDefinitionName.replaceAll("\\W", "_");
|
processDefinition.setKey(processDefinitionKey);
|
}
|
|
RepositorySession repositorySession = EnvironmentImpl.getFromCurrent(RepositorySession.class);
|
|
List<ProcessDefinition> existingProcesses = repositorySession.createProcessDefinitionQuery()
|
.processDefinitionName(processDefinitionName)
|
.list();
|
|
for (ProcessDefinition existingProcess: existingProcesses) {
|
if (!processDefinitionKey.equals(existingProcess.getKey())) {
|
deployment.addProblem("invalid key '"+processDefinitionKey+"' in process "+processDefinition.getName()+". Existing process has name '"+processDefinitionName+"' and key '"+processDefinitionKey+"'");
|
}
|
}
|
|
existingProcesses = repositorySession.createProcessDefinitionQuery()
|
.processDefinitionKey(processDefinitionKey)
|
.list();
|
|
for (ProcessDefinition existingProcess: existingProcesses) {
|
if (!processDefinitionName.equals(existingProcess.getName())) {
|
deployment.addProblem("invalid name '"+processDefinitionName+"' in process "+processDefinition.getName()+". Existing process has name '"+processDefinitionName+"' and key '"+processDefinitionKey+"'");
|
}
|
}
|
}
|
|
protected void checkId(ProcessDefinitionImpl processDefinition, DeploymentImpl deployment) {
|
String id = processDefinition.getId();
|
if (id==null) {
|
id = processDefinition.getKey()+"-"+processDefinition.getVersion();
|
if (log.isTraceEnabled()) log.trace("created id '"+id+"' for "+processDefinition);
|
processDefinition.setId(id);
|
}
|
|
RepositorySession repositorySession = EnvironmentImpl.getFromCurrent(RepositorySession.class);
|
ProcessDefinition existingProcessDefinition = repositorySession.createProcessDefinitionQuery()
|
.processDefinitionId(id)
|
.uniqueResult();
|
if (existingProcessDefinition != null) {
|
deployment.addProblem("process '" + id + "' already exists");
|
}
|
}
|
|
protected void checkVersion(ProcessDefinitionImpl processDefinition, DeploymentImpl deployment) {
|
int version = processDefinition.getVersion();
|
String key = processDefinition.getKey();
|
if (version==ProcessDefinitionImpl.UNASSIGNED_VERSION) {
|
RepositorySession repositorySession = EnvironmentImpl.getFromCurrent(RepositorySession.class);
|
|
ProcessDefinition latestDeployedVersion = repositorySession
|
.createProcessDefinitionQuery()
|
.processDefinitionKey(key)
|
.orderDesc(ProcessDefinitionQuery.PROPERTY_VERSION)
|
.page(0, 1)
|
.uniqueResult();
|
|
if (latestDeployedVersion!=null) {
|
version = latestDeployedVersion.getVersion() + 1;
|
} else {
|
version = 1;
|
}
|
if (log.isTraceEnabled()) log.trace("assigning version "+version+" to process definition "+key);
|
processDefinition.setVersion(version);
|
}
|
}
|
|
public void updateResource(DeploymentImpl deployment, String resourceName, byte[] bytes) {
|
deployment.addResourceFromInputStream(resourceName, new ByteArrayInputStream(bytes));
|
}
|
}
|