提交 a8c8d6ef 编写于 作者: E Erik Winlof 提交者: Joram Barrez
上级 b95a6384
......@@ -31,9 +31,11 @@ import org.activiti.engine.impl.util.IoUtil;
import org.activiti.engine.impl.util.ReflectUtil;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.test.Deployment;
import org.activiti.validation.validator.Problems;
/**
* @author Joram Barrez
* @author Erik Winlof
*/
public class BpmnDeploymentTest extends PluggableActivitiTestCase {
......@@ -71,12 +73,44 @@ public class BpmnDeploymentTest extends PluggableActivitiTestCase {
return new String(bytes);
}
public void FAILING_testViolateProcessDefinitionIdMaximumLength() {
public void testViolateBPMNIdMaximumLength() {
try {
repositoryService.createDeployment().addClasspathResource("org/activiti/engine/test/bpmn/deployment/processWithLongId.bpmn20.xml").deploy();
repositoryService.createDeployment()
.addClasspathResource("org/activiti/engine/test/bpmn/deployment/definitionWithLongTargetNamespace.bpmn20.xml")
.deploy();
fail();
} catch (ActivitiException e) {
assertTextPresent("id can be maximum 64 characters", e.getMessage());
assertTextPresent(Problems.BPMN_MODEL_TARGET_NAMESPACE_TOO_LONG, e.getMessage());
}
// Verify that nothing is deployed
assertEquals(0, repositoryService.createDeploymentQuery().count());
}
public void testViolateProcessDefinitionIdMaximumLength() {
try {
repositoryService.createDeployment()
.addClasspathResource("org/activiti/engine/test/bpmn/deployment/processWithLongId.bpmn20.xml")
.deploy();
fail();
} catch (ActivitiException e) {
assertTextPresent(Problems.PROCESS_DEFINITION_ID_TOO_LONG, e.getMessage());
}
// Verify that nothing is deployed
assertEquals(0, repositoryService.createDeploymentQuery().count());
}
public void testViolateProcessDefinitionNameAndDescriptionMaximumLength() {
try {
repositoryService.createDeployment()
.addClasspathResource("org/activiti/engine/test/bpmn/deployment/processWithLongNameAndDescription.bpmn20.xml")
.deploy();
fail();
} catch (ActivitiException e) {
assertTextPresent(Problems.PROCESS_DEFINITION_NAME_TOO_LONG, e.getMessage());
assertTextPresent(Problems.PROCESS_DEFINITION_DOCUMENTATION_TOO_LONG, e.getMessage());
}
// Verify that nothing is deployed
......
<?xml version="1.0" encoding="UTF-8"?>
<!-- 302 characters long targetNamespace is too long, only 255 characters are allowed in i.e. ACT_RE_PROCDEF.CATEGORY -->
<definitions id="ID123"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="ID100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
<process id="ABC">
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
\ No newline at end of file
......@@ -4,7 +4,8 @@
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="org.activiti.engine.test.bpmn.deployment">
<process id="abcdefghijklmnopqrstuvwxyz12345678901234567891234567890123456789">
<!-- 302 characters long id is too long, only 255 characters are allowed in ACT_RE_PROCDEF.KEY -->
<process id="ID100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
<startEvent id="start" />
......
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="org.activiti.engine.test.bpmn.deployment">
<!-- 302 characters long name is too long, only 255 characters are allowed in ACT_RE_PROCDEF.NAME -->
<process id="ID123" name="ID100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
<!-- Around 2700 characters long documentation is too long, only 2000 characters are allowed in ACT_RE_PROCDEF.DESCRIPTION -->
<documentation>
A little more than 900 characters
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
A little more than 900 characters
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
A little more than 900 characters
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
</documentation>
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
\ No newline at end of file
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.validation.validator;
/**
* @author Erik Winlof
*/
public class Constraints {
/**
* Max length database field ACT_RE_PROCDEF.CATEGORY
*/
public static final int BPMN_MODEL_TARGET_NAMESPACE_MAX_LENGTH = 255;
/**
* Max length database field ACT_RE_PROCDEF.KEY
*/
public static final int PROCESS_DEFINITION_ID_MAX_LENGTH = 255;
/**
* Max length database field ACT_RE_PROCDEF.NAME
*/
public static final int PROCESS_DEFINITION_NAME_MAX_LENGTH = 255;
/**
* Max length of database field ACT_RE_PROCDEF.DESCRIPTION
*/
public static final int PROCESS_DEFINITION_DOCUMENTATION_MAX_LENGTH = 2000;
}
......@@ -61,6 +61,14 @@ public interface Problems {
String EXCLUSIVE_GATEWAY_SEQ_FLOW_WITHOUT_CONDITIONS = "activiti-exclusive-gateway-seq-flow-without-conditions";
String EVENT_GATEWAY_ONLY_CONNECTED_TO_INTERMEDIATE_EVENTS = "activiti-event-gateway-only-connected-to-intermediate-events";
String BPMN_MODEL_TARGET_NAMESPACE_TOO_LONG = "activiti-bpmn-model-target-namespace-too-long";
String PROCESS_DEFINITION_ID_TOO_LONG = "activiti-process-definition-id-too-long";
String PROCESS_DEFINITION_NAME_TOO_LONG = "activiti-process-definition-name-too-long";
String PROCESS_DEFINITION_DOCUMENTATION_TOO_LONG = "activiti-process-definition-documentation-too-long";
String FLOW_ELEMENT_ID_TOO_LONG = "activiti-flow-element-id-too-long";
String SUBPROCESS_MULTIPLE_START_EVENTS = "activiti-subprocess-multiple-start-event";
String SUBPROCESS_START_EVENT_EVENT_DEFINITION_NOT_ALLOWED = "activiti-subprocess-start-event-event-definition-not-allowed";
......
......@@ -17,48 +17,74 @@ import java.util.List;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.validation.ValidationError;
import org.activiti.validation.validator.Constraints;
import org.activiti.validation.validator.Problems;
import org.activiti.validation.validator.ValidatorImpl;
/**
* @author jbarrez
* @author Erik Winlof
*/
public class BpmnModelValidator extends ValidatorImpl {
@Override
public void validate(BpmnModel bpmnModel, List<ValidationError> errors) {
// If all process definitions of this bpmnModel are not executable,
// raise an error
// If all process definitions of this bpmnModel are not executable, raise an error
boolean isAtLeastOneExecutable = validateAtLeastOneExecutable(bpmnModel, errors);
// If at least one process definition is executable, show a warning for
// each of the none-executables
// If at least one process definition is executable, show a warning for each of the none-executables
if (isAtLeastOneExecutable) {
for (Process process : bpmnModel.getProcesses()) {
if (!process.isExecutable()) {
addWarning(errors, Problems.PROCESS_DEFINITION_NOT_EXECUTABLE, process, process, "Process definition is not executable. Please verify that this is intentional.");
addWarning(errors, Problems.PROCESS_DEFINITION_NOT_EXECUTABLE, process, process,
"Process definition is not executable. Please verify that this is intentional.");
}
handleProcessConstraints(bpmnModel, process, errors);
}
}
handleBPMNModelConstraints(bpmnModel, errors);
}
/**
* Returns 'true' if at least one process definition in the {@link BpmnModel} is executable.
*/
private boolean validateAtLeastOneExecutable(BpmnModel bpmnModel, List<ValidationError> errors) {
int nrOfExecutableDefinitions = 0;
for (Process process : bpmnModel.getProcesses()) {
if (process.isExecutable()) {
nrOfExecutableDefinitions++;
}
protected void handleProcessConstraints(BpmnModel bpmnModel, Process process, List<ValidationError> errors) {
if (process.getId() != null && process.getId().length() > Constraints.PROCESS_DEFINITION_ID_MAX_LENGTH) {
addError(errors, Problems.PROCESS_DEFINITION_ID_TOO_LONG, process,
"The id of the process definition must not contain more than " + Constraints.PROCESS_DEFINITION_ID_MAX_LENGTH + " characters");
}
if (process.getName() != null && process.getName().length() > Constraints.PROCESS_DEFINITION_NAME_MAX_LENGTH) {
addError(errors, Problems.PROCESS_DEFINITION_NAME_TOO_LONG, process,
"The name of the process definition must not contain more than " + Constraints.PROCESS_DEFINITION_NAME_MAX_LENGTH + " characters");
}
if (process.getDocumentation() != null && process.getDocumentation().length() > Constraints.PROCESS_DEFINITION_DOCUMENTATION_MAX_LENGTH) {
addError(errors, Problems.PROCESS_DEFINITION_DOCUMENTATION_TOO_LONG, process,
"The documentation of the process definition must not contain more than " + Constraints.PROCESS_DEFINITION_DOCUMENTATION_MAX_LENGTH + " characters");
}
}
if (nrOfExecutableDefinitions == 0) {
addError(errors, Problems.ALL_PROCESS_DEFINITIONS_NOT_EXECUTABLE, "All process definition are set to be non-executable (property 'isExecutable' on process). This is not allowed.");
protected void handleBPMNModelConstraints(BpmnModel bpmnModel, List<ValidationError> errors) {
if (bpmnModel.getTargetNamespace() != null && bpmnModel.getTargetNamespace().length() > Constraints.BPMN_MODEL_TARGET_NAMESPACE_MAX_LENGTH) {
addError(errors, Problems.BPMN_MODEL_TARGET_NAMESPACE_TOO_LONG,
"The targetNamespace of the bpmn model must not contain more than " + Constraints.BPMN_MODEL_TARGET_NAMESPACE_MAX_LENGTH + " characters");
}
}
return nrOfExecutableDefinitions > 0;
/**
* Returns 'true' if at least one process definition in the {@link BpmnModel} is executable.
*/
protected boolean validateAtLeastOneExecutable(BpmnModel bpmnModel, List<ValidationError> errors) {
int nrOfExecutableDefinitions = 0;
for (Process process : bpmnModel.getProcesses()) {
if (process.isExecutable()) {
nrOfExecutableDefinitions++;
}
}
if (nrOfExecutableDefinitions == 0) {
addError(errors, Problems.ALL_PROCESS_DEFINITIONS_NOT_EXECUTABLE,
"All process definition are set to be non-executable (property 'isExecutable' on process). This is not allowed.");
}
return nrOfExecutableDefinitions > 0;
}
}
......@@ -26,25 +26,36 @@ import org.activiti.validation.validator.ProcessLevelValidator;
import org.apache.commons.lang3.StringUtils;
/**
* A validator for stuff that is shared accross all flow elements
* A validator for stuff that is shared across all flow elements
*
* @author jbarrez
* @author Erik Winlof
*/
public class FlowElementValidator extends ProcessLevelValidator {
@Override
protected void executeValidation(BpmnModel bpmnModel, Process process, List<ValidationError> errors) {
for (FlowElement flowElement : process.getFlowElements()) {
protected static final int ID_MAX_LENGTH = 255;
if (flowElement instanceof Activity) {
Activity activity = (Activity) flowElement;
handleMultiInstanceLoopCharacteristics(process, activity, errors);
handleDataAssociations(process, activity, errors);
}
}
@Override
protected void executeValidation(BpmnModel bpmnModel, Process process, List<ValidationError> errors) {
for (FlowElement flowElement : process.getFlowElements()) {
if (flowElement instanceof Activity) {
Activity activity = (Activity) flowElement;
handleConstraints(process, activity, errors);
handleMultiInstanceLoopCharacteristics(process, activity, errors);
handleDataAssociations(process, activity, errors);
}
}
}
}
protected void handleConstraints(Process process, Activity activity, List<ValidationError> errors) {
if (activity.getId() != null && activity.getId().length() > ID_MAX_LENGTH) {
addError(errors, Problems.FLOW_ELEMENT_ID_TOO_LONG, process, activity,
"The id of a flow element must not contain more than " + ID_MAX_LENGTH + " characters");
}
}
protected void handleMultiInstanceLoopCharacteristics(Process process, Activity activity, List<ValidationError> errors) {
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册