提交 cac7df97 编写于 作者: F fheremans

Added output of artifacts + finished form-properties exporting

上级 1a89621e
......@@ -19,6 +19,10 @@
<groupId>org.activiti</groupId>
<artifactId>activiti-simple-workflow</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
......
......@@ -42,6 +42,14 @@ public class FormFieldControl
})
private List<FormFieldControlParameter> controlParameters = new ArrayList<FormFieldControlParameter>();
public FormFieldControl() {
}
public FormFieldControl(String template) {
this.template = template;
}
public String getTemplate()
{
return template;
......
......@@ -29,14 +29,22 @@ import javax.xml.bind.annotation.XmlValue;
@XmlAccessorType(XmlAccessType.FIELD)
public class FormFieldControlParameter
{
@XmlAttribute(name="name")
private String name;
@XmlValue
private String configuration;
public FormFieldControlParameter() {
}
public FormFieldControlParameter(String name, String configuration) {
this.name = name;
this.configuration = configuration;
}
public String getName()
public String getName()
{
return name;
}
......
......@@ -45,13 +45,19 @@ public interface AlfrescoConversionConstants {
/**
* Default start form key
*/
String DEFAULT_START_FORM_TYPE = "bpm:startTask";
String DEFAULT_START_FORM_TYPE = "bpm:activitiStartTask";
/**
* Base type for all task models
*/
String DEFAULT_BASE_FORM_TYPE = "bpm:workflowTask";
String PROPERTY_WORKFLOW_DESCRIPTION = "bpm:workflowDescription";
String PROPERTY_WORKFLOW_DUE_DATE = "bpm:workflowDueDate";
String PROPERTY_WORKFLOW_PRIORITY = "bpm:workflowPriority";
String PROPERTY_SEND_EMAIL_NOTIFICATIONS = "bpm:sendEMailNotifications";
String PROPERTY_PACKAGEITEMS = "packageitems";
String PROPERTY_TYPE_TEXT = "d:text";
String PROPERTY_TYPE_DATE = "d:date";
String PROPERTY_TYPE_DOUBLE = "d:double";
......@@ -77,6 +83,22 @@ public interface AlfrescoConversionConstants {
String FORM_DATE_PARAM_SHOW_TIME = "showTime";
String FORM_DATE_PARAM_SUBMIT_TIME = "submitTime";
String FORM_NUMBER_TEMPLATE = "/org/alfresco/components/form/controls/number.ftl";
String FORM_PRIORITY_TEMPLATE = "/org/alfresco/components/form/controls/workflow/priority.ftl";
String FORM_EMAIL_NOTIFICATION_TEMPLATE = "/org/alfresco/components/form/controls/workflow/email-notification.ftl";
String FORM_SET_GENERAL = "";
String FORM_SET_INFO = "info";
String FORM_SET_ASSIGNEE = "assignee";
String FORM_SET_ITEMS = "items";
String FORM_SET_OTHER = "other";
String FORM_SET_GENERAL_LABEL = "workflow.set.general";
String FORM_SET_ASSIGNEE_LABEL = "workflow.set.assignee";
String FORM_SET_ITEMS_LABEL = "workflow.set.items";
String FORM_SET_OTHER_LABEL = "workflow.set.other";
String FORM_WORKFLOW_DESCRIPTION_LABEL = "workflow.field.message";
String FORM_WORKFLOW_DUE_DATE_LABEL = "workflow.field.due";
String FORM_WORKFLOW_PRIORITY_LABEL = "workflow.field.priority";
String FORM_GROUP_LAYOUT_1_COLUMN = "one-column";
String FORM_GROUP_LAYOUT_2_COLUMNS = "two-column";
......
......@@ -14,6 +14,7 @@ package org.activiti.workflow.simple.alfresco.conversion;
import java.text.MessageFormat;
import org.activiti.bpmn.model.UserTask;
import org.activiti.workflow.simple.alfresco.configmodel.Configuration;
import org.activiti.workflow.simple.alfresco.configmodel.Form;
import org.activiti.workflow.simple.alfresco.configmodel.Module;
......@@ -51,12 +52,21 @@ public class AlfrescoHumanStepDefinitionConverter extends HumanStepDefinitionCon
@Override
public void convertStepDefinition(StepDefinition stepDefinition, WorkflowDefinitionConversion conversion) {
// Let superclass handle BPMN-specific conversion
super.convertStepDefinition(stepDefinition, conversion);
// Clear form-properties in the BPMN file, as we use custom form-mapping in Alfresco
String userTaskId = conversion.getLastActivityId();
UserTask userTask = (UserTask) conversion.getProcess().getFlowElement(userTaskId);
userTask.getFormProperties().clear();
HumanStepDefinition humanStep = (HumanStepDefinition) stepDefinition;
validate(humanStep);
// Create the content model for the task
M2Type type = new M2Type();
M2Model model = AlfrescoConversionUtil.getContentModel(conversion);
model.getTypes().add(type);
M2Namespace modelNamespace = model.getNamespaces().get(0);
type.setName(AlfrescoConversionUtil.getQualifiedName(modelNamespace.getPrefix(),
humanStep.getId()));
......
......@@ -12,8 +12,22 @@
*/
package org.activiti.workflow.simple.alfresco.conversion;
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.workflow.simple.alfresco.configmodel.Module;
import org.activiti.workflow.simple.alfresco.conversion.exception.AlfrescoSimpleWorkflowException;
import org.activiti.workflow.simple.alfresco.model.M2Model;
import org.activiti.workflow.simple.converter.WorkflowDefinitionConversion;
import org.activiti.workflow.simple.converter.WorkflowDefinitionConversionFactory;
import org.activiti.workflow.simple.definition.HumanStepDefinition;
import org.apache.commons.io.IOUtils;
/**
* {@link WorkflowDefinitionConversionFactory} which has additional listeners which
......@@ -25,15 +39,72 @@ import org.activiti.workflow.simple.definition.HumanStepDefinition;
public class AlfrescoWorkflowDefinitionConversionFactory extends WorkflowDefinitionConversionFactory {
private static final long serialVersionUID = 1L;
protected BpmnXMLConverter bpmnConverter;
protected JAXBContext contentModelContext;
protected JAXBContext moduleContext;
public AlfrescoWorkflowDefinitionConversionFactory() {
super();
// Initialize writers for artifacts
bpmnConverter = new BpmnXMLConverter();
try {
contentModelContext = JAXBContext.newInstance(M2Model.class);
} catch (JAXBException jaxbe) {
throw new AlfrescoSimpleWorkflowException(
"Error while building JAXB-context for exporting content-model", jaxbe);
}
try {
moduleContext = JAXBContext.newInstance(Module.class);
} catch (JAXBException jaxbe) {
throw new AlfrescoSimpleWorkflowException(
"Error while building JAXB-context for exporting share-module", jaxbe);
}
// Add additional listeners for Alfresco-specific listeners
workflowDefinitionConversionListeners.add(new InitializeAlfrescoModelsConversionListener());
defaultWorkflowDefinitionConversionListeners.add(new InitializeAlfrescoModelsConversionListener());
// Custom step converters
defaultStepConverters.put(HumanStepDefinition.class, new AlfrescoHumanStepDefinitionConverter());
}
/**
* Write the BPMN-model in the given conversion to the given stream.
*/
public void writeBpmnModel(OutputStream out, WorkflowDefinitionConversion conversion) throws IOException {
BpmnModel model = conversion.getBpmnModel();
byte[] xmlContent = bpmnConverter.convertToXML(model, "UTF-8");
IOUtils.write(xmlContent, out);
}
/**
* Write the Share module XML in the given conversion to the given stream.
*/
public void writeModule(OutputStream out, WorkflowDefinitionConversion conversion) throws IOException {
Module module = AlfrescoConversionUtil.getModule(conversion);
try {
Marshaller marshaller = moduleContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(module, out);
} catch (JAXBException jaxbe) {
throw new IOException(jaxbe);
}
}
/**
* Write the content model XML in the given conversion to the given stream.
*/
public void writeContentModel(OutputStream out, WorkflowDefinitionConversion conversion) throws IOException {
M2Model model = AlfrescoConversionUtil.getContentModel(conversion);
try {
Marshaller marshaller = contentModelContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(model, out);
} catch (JAXBException jaxbe) {
throw new IOException(jaxbe);
}
}
}
......@@ -18,6 +18,10 @@ import java.util.UUID;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.workflow.simple.alfresco.configmodel.Configuration;
import org.activiti.workflow.simple.alfresco.configmodel.Form;
import org.activiti.workflow.simple.alfresco.configmodel.FormField;
import org.activiti.workflow.simple.alfresco.configmodel.FormFieldControl;
import org.activiti.workflow.simple.alfresco.configmodel.FormFieldControlParameter;
import org.activiti.workflow.simple.alfresco.configmodel.Module;
import org.activiti.workflow.simple.alfresco.model.M2Model;
import org.activiti.workflow.simple.alfresco.model.M2Namespace;
......@@ -31,13 +35,18 @@ import org.activiti.workflow.simple.converter.listener.WorkflowDefinitionConvers
* @author Frederik Heremans
* @author Joram Barrez
*/
public class InitializeAlfrescoModelsConversionListener implements WorkflowDefinitionConversionListener {
public class InitializeAlfrescoModelsConversionListener implements WorkflowDefinitionConversionListener, AlfrescoConversionConstants {
private static final long serialVersionUID = 1L;
@Override
public void beforeStepsConversion(WorkflowDefinitionConversion conversion) {
String processId = generateUniqueProcessId(conversion);
String processId = null;
if(conversion.getWorkflowDefinition().getId() != null) {
processId = AlfrescoConversionUtil.getValidIdString(conversion.getWorkflowDefinition().getId());
} else {
processId = generateUniqueProcessId(conversion);
}
addContentModel(conversion, processId);
addModule(conversion, processId);
}
......@@ -48,7 +57,14 @@ public class InitializeAlfrescoModelsConversionListener implements WorkflowDefin
if(flowElement instanceof StartEvent) {
StartEvent startEvent = (StartEvent) flowElement;
if(startEvent.getFormKey() == null) {
startEvent.setFormKey(AlfrescoConversionConstants.DEFAULT_START_FORM_TYPE);
startEvent.setFormKey(DEFAULT_START_FORM_TYPE);
// Also add form-config to the share-module for workflow detail screen, based on the default form
Module module = AlfrescoConversionUtil.getModule(conversion);
Configuration detailsForm = module.addConfiguration(EVALUATOR_STRING_COMPARE,
MessageFormat.format(EVALUATOR_CONDITION_ACTIVITI, conversion.getProcess().getId()));
populateDefaultDetailFormConfig(detailsForm);
}
}
}
......@@ -56,7 +72,7 @@ public class InitializeAlfrescoModelsConversionListener implements WorkflowDefin
protected String generateUniqueProcessId(WorkflowDefinitionConversion conversion) {
String processId = AlfrescoConversionUtil.getValidIdString(
AlfrescoConversionConstants.PROCESS_ID_PREFIX + UUID.randomUUID().toString());
PROCESS_ID_PREFIX + UUID.randomUUID().toString());
conversion.getProcess().setId(processId);
return processId;
}
......@@ -67,16 +83,16 @@ public class InitializeAlfrescoModelsConversionListener implements WorkflowDefin
// Set general model properties
M2Model model = new M2Model();
model.setName(AlfrescoConversionUtil.getQualifiedName(processId,
AlfrescoConversionConstants.CONTENT_MODEL_UNQUALIFIED_NAME));
CONTENT_MODEL_UNQUALIFIED_NAME));
M2Namespace namespace = AlfrescoConversionUtil.createNamespace(processId);
model.getNamespaces().add(namespace);
// Import required alfresco models
model.getImports().add(AlfrescoConversionConstants.DICTIONARY_NAMESPACE);
model.getImports().add(AlfrescoConversionConstants.CONTENT_NAMESPACE);
model.getImports().add(AlfrescoConversionConstants.BPM_NAMESPACE);
model.getImports().add(DICTIONARY_NAMESPACE);
model.getImports().add(CONTENT_NAMESPACE);
model.getImports().add(BPM_NAMESPACE);
// Store model in the conversion artifacts to be accessed later
AlfrescoConversionUtil.storeContentModel(model, conversion);
......@@ -86,7 +102,55 @@ public class InitializeAlfrescoModelsConversionListener implements WorkflowDefin
protected void addModule(WorkflowDefinitionConversion conversion, String processId) {
// Create form-configuration
Module module = new Module();
module.setId(MessageFormat.format(AlfrescoConversionConstants.MODULE_ID, processId));
module.setId(MessageFormat.format(MODULE_ID, processId));
AlfrescoConversionUtil.storeModule(module, conversion);
}
protected void populateDefaultDetailFormConfig(Configuration configuration) {
Form form = configuration.createForm();
// Add visibility of fields
form.getFormFieldVisibility().addShowFieldElement(PROPERTY_WORKFLOW_DESCRIPTION);
form.getFormFieldVisibility().addShowFieldElement(PROPERTY_WORKFLOW_DUE_DATE);
form.getFormFieldVisibility().addShowFieldElement(PROPERTY_WORKFLOW_PRIORITY);
form.getFormFieldVisibility().addShowFieldElement(PROPERTY_PACKAGEITEMS);
form.getFormFieldVisibility().addShowFieldElement(PROPERTY_SEND_EMAIL_NOTIFICATIONS);
// Add all sets to the appearance
form.getFormAppearance().addFormSet(FORM_SET_GENERAL, FORM_SET_APPEARANCE_TITLE, FORM_SET_GENERAL_LABEL, null);
form.getFormAppearance().addFormSet(FORM_SET_INFO, null, null, FORM_SET_TEMPLATE_2_COLUMN);
form.getFormAppearance().addFormSet(FORM_SET_ASSIGNEE, FORM_SET_APPEARANCE_TITLE, FORM_SET_ASSIGNEE_LABEL, null);
form.getFormAppearance().addFormSet(FORM_SET_ITEMS, FORM_SET_APPEARANCE_TITLE, FORM_SET_ITEMS_LABEL, null);
form.getFormAppearance().addFormSet(FORM_SET_OTHER, FORM_SET_APPEARANCE_TITLE, FORM_SET_OTHER_LABEL, null);
// Finally, add the individual fields
FormField descriptionField = new FormField();
descriptionField.setId(PROPERTY_WORKFLOW_DESCRIPTION);
descriptionField.setControl(new FormFieldControl(FORM_MULTILINE_TEXT_TEMPLATE));
descriptionField.setLabelId(FORM_WORKFLOW_DESCRIPTION_LABEL);
form.getFormAppearance().addFormAppearanceElement(descriptionField);
FormField dueDateField = new FormField();
dueDateField.setId(PROPERTY_WORKFLOW_DUE_DATE);
dueDateField.setSet(FORM_SET_INFO);
dueDateField.setLabelId(FORM_WORKFLOW_DUE_DATE_LABEL);
dueDateField.setControl(new FormFieldControl(FORM_DATE_TEMPLATE));
dueDateField.getControl().getControlParameters().add(new FormFieldControlParameter(FORM_DATE_PARAM_SHOW_TIME, Boolean.FALSE.toString()));
dueDateField.getControl().getControlParameters().add(new FormFieldControlParameter(FORM_DATE_PARAM_SUBMIT_TIME, Boolean.FALSE.toString()));
form.getFormAppearance().addFormAppearanceElement(dueDateField);
FormField priorityField = new FormField();
priorityField.setSet(FORM_SET_INFO);
priorityField.setLabelId(FORM_WORKFLOW_PRIORITY_LABEL);
priorityField.setId(PROPERTY_WORKFLOW_PRIORITY);
priorityField.setControl(new FormFieldControl(FORM_PRIORITY_TEMPLATE));
form.getFormAppearance().addFormAppearanceElement(priorityField);
form.getFormAppearance().addFormField(PROPERTY_PACKAGEITEMS, null, FORM_SET_ITEMS);
FormField emailNotificationsField = new FormField();
emailNotificationsField.setId(PROPERTY_SEND_EMAIL_NOTIFICATIONS);
emailNotificationsField.setControl(new FormFieldControl(FORM_EMAIL_NOTIFICATION_TEMPLATE));
form.getFormAppearance().addFormAppearanceElement(emailNotificationsField);
}
}
......@@ -41,6 +41,7 @@ public class AlfrescoDatePropertyConverter implements AlfrescoFormPropertyConver
M2Property property = new M2Property();
property.setMandatory(new M2Mandatory(dateDefinition.isMandatory()));
property.setName(propertyName);
contentType.getProperties().add(property);
if(dateDefinition.isShowTime()) {
property.setPropertyType(AlfrescoConversionConstants.PROPERTY_TYPE_DATETIME);
......
......@@ -37,10 +37,15 @@ public class AlfrescoFormCreator {
public AlfrescoFormCreator() {
propertyConverters = new HashMap<Class<? extends FormPropertyDefinition>, AlfrescoFormPropertyConverter>();
registerConverter(new AlfrescoTextPropertyConverter());
registerConverter(new AlfrescoDatePropertyConverter());
registerConverter(new AlfrescoNumberPropertyConverter());
registerConverter(new AlfrescoListPropertyConverter());
}
public void createForm(M2Type contentType, Form formConfig, FormDefinition formDefinition, WorkflowDefinitionConversion conversion) {
if(formDefinition.getFormGroups() != null) {
if(formDefinition != null && formDefinition.getFormGroups() != null) {
for(FormPropertyGroup group : formDefinition.getFormGroups()) {
// Create a group in the form-config
......@@ -78,5 +83,9 @@ public class AlfrescoFormCreator {
} else {
return null;
}
}
protected void registerConverter(AlfrescoFormPropertyConverter converter) {
propertyConverters.put(converter.getConvertedClass(), converter);
}
}
......@@ -50,6 +50,7 @@ public class AlfrescoListPropertyConverter implements AlfrescoFormPropertyConver
property.setMandatory(new M2Mandatory(dateDefinition.isMandatory()));
property.setName(propertyName);
property.setPropertyType(AlfrescoConversionConstants.PROPERTY_TYPE_TEXT);
contentType.getProperties().add(property);
// Create constraint for the values
if(dateDefinition.getEntries() != null && dateDefinition.getEntries().size() > 0) {
......@@ -59,7 +60,7 @@ public class AlfrescoListPropertyConverter implements AlfrescoFormPropertyConver
List<String> values = new ArrayList<String>(dateDefinition.getEntries().size());
for(ListPropertyEntry entry : dateDefinition.getEntries()) {
// TODO: i18n file using labels
// TODO: i18n file using labels in properties-file, a part of deployment?
values.add(entry.getValue());
}
valueConstraint.getParameters().add(new M2NamedValue(AlfrescoConversionConstants.CONTENT_MODEL_CONSTRAINT_TYPE_LIST, null, values));
......
......@@ -58,5 +58,7 @@ public class AlfrescoNumberPropertyConverter implements AlfrescoFormPropertyConv
control.setTemplate(AlfrescoConversionConstants.FORM_NUMBER_TEMPLATE);
formField.setControl(control);
}
contentType.getProperties().add(property);
}
}
......@@ -42,6 +42,7 @@ public class AlfrescoTextPropertyConverter implements AlfrescoFormPropertyConver
property.setMandatory(new M2Mandatory(textDefinition.isMandatory()));
property.setName(propertyName);
property.setPropertyType(AlfrescoConversionConstants.PROPERTY_TYPE_TEXT);
contentType.getProperties().add(property);
// Add form configuration
form.getFormFieldVisibility().addShowFieldElement(propertyName);
......@@ -58,5 +59,6 @@ public class AlfrescoTextPropertyConverter implements AlfrescoFormPropertyConver
control.setTemplate(AlfrescoConversionConstants.FORM_MULTILINE_TEXT_TEMPLATE);
formField.setControl(control);
}
}
}
......@@ -25,6 +25,10 @@ public class M2Mandatory {
@XmlValue
private boolean mandatory = false;
public M2Mandatory() {
}
public M2Mandatory(boolean mandatory) {
this.mandatory = mandatory;
}
......
......@@ -25,6 +25,10 @@ public class M2Namespace {
@XmlAttribute
private String prefix;
public M2Namespace() {
}
public M2Namespace(String uri, String prefix) {
this.uri = uri;
this.prefix = prefix;
......
/* 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.workflow.simple.alfresco.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.workflow.simple.alfresco.configmodel.Configuration;
import org.activiti.workflow.simple.alfresco.configmodel.Module;
import org.activiti.workflow.simple.alfresco.conversion.AlfrescoConversionConstants;
import org.activiti.workflow.simple.alfresco.conversion.AlfrescoConversionUtil;
import org.activiti.workflow.simple.alfresco.conversion.AlfrescoWorkflowDefinitionConversionFactory;
import org.activiti.workflow.simple.alfresco.model.M2Model;
import org.activiti.workflow.simple.alfresco.model.M2Property;
import org.activiti.workflow.simple.alfresco.model.M2Type;
import org.activiti.workflow.simple.converter.WorkflowDefinitionConversion;
import org.activiti.workflow.simple.definition.HumanStepDefinition;
import org.activiti.workflow.simple.definition.WorkflowDefinition;
import org.activiti.workflow.simple.definition.form.FormDefinition;
import org.activiti.workflow.simple.definition.form.FormPropertyGroup;
import org.activiti.workflow.simple.definition.form.TextPropertyDefinition;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class WorkflowDefinitionConversionTest {
protected AlfrescoWorkflowDefinitionConversionFactory conversionFactory;
@Before
public void init() {
conversionFactory = new AlfrescoWorkflowDefinitionConversionFactory();
}
/**
* Check if all required artifacts are created when converting an empty workflow-definition.
*/
@Test
public void testEmptyWorkflowDefinitionConversion() {
WorkflowDefinition definition = new WorkflowDefinition();
definition.setDescription("This is the description");
definition.setId("workflowdefinition");
definition.setName("My workflow definition");
WorkflowDefinitionConversion conversion = conversionFactory.createWorkflowDefinitionConversion(definition);
conversion.convert();
BpmnModel bpmnModel = conversion.getBpmnModel();
assertNotNull(bpmnModel);
Process process = bpmnModel.getMainProcess();
assertNotNull(process);
assertEquals("This is the description", process.getDocumentation());
assertEquals("My workflow definition", process.getName());
assertEquals("workflowdefinition", process.getId());
// Default start-task key should be used, as no custom startform-config is present
boolean startTaskFound = false;
for(FlowElement element : process.getFlowElements()) {
if(element instanceof StartEvent) {
assertEquals("bpm:activitiStartTask", ((StartEvent) element).getFormKey());
startTaskFound = true;
}
}
assertTrue(startTaskFound);
// Check presence of content-model
M2Model contentModel = AlfrescoConversionUtil.getContentModel(conversion);
assertNotNull(contentModel);
// Check presence of form-config and default workflow-details
Module module = AlfrescoConversionUtil.getModule(conversion);
assertNotNull(module);
assertEquals(1L, module.getConfigurations().size());
Configuration config = module.getConfigurations().get(0);
assertEquals(1L, config.getForms().size());
assertEquals("activiti$workflowdefinition", config.getCondition());
assertEquals(AlfrescoConversionConstants.EVALUATOR_STRING_COMPARE, config.getEvaluator());
}
/**
* Check if all required artifacts are created when converting an empty workflow-definition.
*/
@Test
public void testGeneratedWorkflowDefinitionId() {
WorkflowDefinition definition = new WorkflowDefinition();
WorkflowDefinitionConversion conversion = conversionFactory.createWorkflowDefinitionConversion(definition);
conversion.convert();
BpmnModel bpmnModel = conversion.getBpmnModel();
assertNotNull(bpmnModel);
Process process = bpmnModel.getMainProcess();
assertNotNull(process);
String generatedProcessId = process.getId();
assertNotNull(generatedProcessId);
}
/**
* Check artifact export.
*/
@Test
public void testExportArtifacts() throws Exception {
WorkflowDefinition definition = new WorkflowDefinition();
HumanStepDefinition humanStep = new HumanStepDefinition();
humanStep.setAssignee("fred");
humanStep.setId("step 1");
FormDefinition form = new FormDefinition();
form.setFormKey("wf:activitiAdhoc");
humanStep.setForm(form);
definition.addStep(humanStep);
WorkflowDefinitionConversion conversion = conversionFactory.createWorkflowDefinitionConversion(definition);
conversion.convert();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
conversionFactory.writeBpmnModel(stream, conversion);
byte[] byteArray = stream.toByteArray();
assertTrue(byteArray.length > 0);
stream = new ByteArrayOutputStream();
conversionFactory.writeContentModel(stream, conversion);
byteArray = stream.toByteArray();
assertTrue(byteArray.length > 0);
stream = new ByteArrayOutputStream();
conversionFactory.writeModule(stream, conversion);
byteArray = stream.toByteArray();
assertTrue(byteArray.length > 0);
}
/**
* Test basic form-fields (text, number, date, list, ...)
*/
@Test
public void testHumanStepBasicFormField() throws Exception {
// TODO: finish test once all types are present
WorkflowDefinition definition = new WorkflowDefinition();
definition.setId("process");
HumanStepDefinition humanStep = new HumanStepDefinition();
humanStep.setId("step1");
FormDefinition form = new FormDefinition();
humanStep.setForm(form);
FormPropertyGroup group = new FormPropertyGroup();
group.setId("group");
group.setTitle("My group");
humanStep.getForm().addFormPropertyGroup(group);
// Add simple text
TextPropertyDefinition textProperty = new TextPropertyDefinition();
textProperty.setName("text");
textProperty.setMandatory(true);
group.addFormProperty(textProperty);
definition.addStep(humanStep);
WorkflowDefinitionConversion conversion = conversionFactory.createWorkflowDefinitionConversion(definition);
conversion.convert();
// Check content-model
M2Model model = AlfrescoConversionUtil.getContentModel(conversion);
assertNotNull(model);
M2Type type = model.getTypes().get(0);
assertNotNull(type);
// Simple text
M2Property property = getPropertyFromType("text", type);
assertEquals("d:text", property.getPropertyType());
assertEquals(Boolean.TRUE, property.getMandatory().isMandatory());
}
protected M2Property getPropertyFromType(String shortName, M2Type type) {
for(M2Property prop : type.getProperties()) {
if(prop.getName().endsWith(shortName)) {
return prop;
}
}
Assert.fail("No property found for the given name: " + shortName);
return null;
}
}
......@@ -73,7 +73,16 @@ public class DefaultWorkflowDefinitionConversionListener implements WorkflowDefi
* (eg. amongst differnt tenants)
*/
protected String generateProcessId(WorkflowDefinition workflowDefinition) {
return workflowDefinition.getName().replace(" ", "_");
String processId = null;
if(workflowDefinition.getId() != null) {
processId = workflowDefinition.getId();
} else {
// Revert to using the name of the process
if(workflowDefinition.getName() != null) {
processId = workflowDefinition.getName().replace(" ", "_");
}
}
return processId;
}
public void afterStepsConversion(WorkflowDefinitionConversion conversion) {
......
......@@ -85,6 +85,10 @@ public class HumanStepDefinitionConverter extends BaseStepDefinitionConverter<Hu
// Form properties
userTask.setFormProperties(convertProperties(formDefinition));
if(formDefinition.getFormKey() != null) {
userTask.setFormKey(formDefinition.getFormKey());
}
}
return userTask;
......
......@@ -56,7 +56,6 @@ public class WorkflowDefinition extends AbstractStepDefinitionContainer<Workflow
private static final long serialVersionUID = 1L;
protected String id;
protected String key;
protected String name;
protected String description;
......
......@@ -28,95 +28,20 @@
importPackage(java.util);
importPackage(org.activiti.explorer.reporting);
var reportData = new ReportData();
var month = execution.getVariable("month");
var employee = execution.getVariable("employee");
// Fetch first and last day
var firstDay, lastDay;
var minMaxResult = ReportingUtil.executeSelectSqlQuery("SELECT MIN(END_TIME_), MAX(END_TIME_) FROM ACT_HI_TASKINST where END_TIME_ is not null and month(END_TIME_) = " + (month + 1) + " and ASSIGNEE_ = '" + employee + "'");
var hasResults = minMaxResult.next();
if (hasResults) {
var minDate = minMaxResult.getTimestamp(1);
var maxDate = minMaxResult.getTimestamp(2);
if (minDate != null && maxDate != null) {
var cal = Calendar.getInstance();
cal.setTime(minDate);
firstDay = cal.get(Calendar.DAY_OF_MONTH);
cal.setTime(maxDate);
lastDay = cal.get(Calendar.DAY_OF_MONTH);
}
}
var counts = new Array();
if (firstDay != null && lastDay != null && firstDay != lastDay) {
for (var i=firstDay; i<=lastDay; i++) {
counts[i] = 0;
}
var result = ReportingUtil.executeSelectSqlQuery("SELECT END_TIME_ FROM ACT_HI_TASKINST where END_TIME_ is not null and month(END_TIME_) = " + (month + 1) + " and ASSIGNEE_ = '" + employee + "'");
while (result.next()) { // process results one row at a time
var timestamp = result.getTimestamp(1);
var cal = Calendar.getInstance();
cal.setTime(timestamp);
var day = cal.get(Calendar.DAY_OF_MONTH);
var previousCount = counts[day];
counts[day] = counts[day] + 1;
}
var dataset = reportData.newDataset();
dataset.type = "lineChart";
dataset.description = "Daily productivity overview for " + employee;
dataset.xaxis = "Day of month";
dataset.yaxis = "Number of completed tasks";
for (var i=firstDay; i<=lastDay; i++) {
dataset.add(i + "", counts[i]);
}
} else if (firstDay != null && lastDay != null && firstDay == lastDay) {
for (var i=0; i<=24; i++) {
counts[i] = 0;
}
// Fetch counts for hours
var result = ReportingUtil.executeSelectSqlQuery("SELECT END_TIME_ FROM ACT_HI_TASKINST where END_TIME_ is not null and month(END_TIME_) = " + (month + 1) + " and ASSIGNEE_ = '" + employee + "'");
while (result.next()) { // process results one row at a time
var timestamp = result.getTimestamp(1);
var cal = Calendar.getInstance();
cal.setTime(timestamp);
var hour = cal.get(Calendar.HOUR_OF_DAY);
var previousCount = counts[hour];
counts[hour] = counts[hour] + 1;
}
var dataset = reportData.newDataset();
dataset.type = "lineChart";
dataset.description = "Hourly productivity overview for " + employee;
dataset.xaxis = "Hour of day";
dataset.yaxis = "Number of completed tasks";
for (var i=0; i<=24; i++) {
dataset.add(i + "", counts[i]);
}
}
execution.setVariable("reportData", reportData.toBytes());
var reportData = {
"title": "My Report",
"datasets": [
{
"type" : "lineChart",
"description" : "My first chart",
"xaxis" : "Category",
"yaxis" : "Total sales",
"data" :
{ "2010" : 50, "2011" : 33, "2012" : 17, "2013" : 87 }
}
]
};
execution.setVariable("reportData", new java.lang.String(JSON.stringify(reportData)).getBytes("UTF-8"));
]]></script>
</scriptTask>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册