diff --git a/source/java/org/alfresco/repo/workflow/activiti/AlfrescoProcessEngineConfiguration.java b/source/java/org/alfresco/repo/workflow/activiti/AlfrescoProcessEngineConfiguration.java
index f492456f28..36691fca68 100644
--- a/source/java/org/alfresco/repo/workflow/activiti/AlfrescoProcessEngineConfiguration.java
+++ b/source/java/org/alfresco/repo/workflow/activiti/AlfrescoProcessEngineConfiguration.java
@@ -29,6 +29,7 @@ import org.activiti.engine.impl.variable.SerializableType;
import org.activiti.engine.impl.variable.VariableType;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
+import org.alfresco.repo.workflow.activiti.variable.CustomStringVariableType;
import org.alfresco.service.cmr.repository.NodeService;
/**
@@ -61,6 +62,11 @@ public class AlfrescoProcessEngineConfiguration extends SpringProcessEngineConfi
variableTypes.addType(type, serializableIndex);
}
}
+
+ // WOR-171: Replace string type by custom one to handle large text-values
+ int stringIndex = variableTypes.getTypeIndex("string");
+ variableTypes.removeType(variableTypes.getVariableType("string"));
+ variableTypes.addType(new CustomStringVariableType(), stringIndex);
}
@Override
diff --git a/source/java/org/alfresco/repo/workflow/activiti/variable/CustomStringVariableType.java b/source/java/org/alfresco/repo/workflow/activiti/variable/CustomStringVariableType.java
new file mode 100644
index 0000000000..4b25155992
--- /dev/null
+++ b/source/java/org/alfresco/repo/workflow/activiti/variable/CustomStringVariableType.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2005-2011 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco 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 Alfresco. If not, see .
+ */
+package org.alfresco.repo.workflow.activiti.variable;
+
+import org.activiti.engine.impl.persistence.entity.ByteArrayEntity;
+import org.activiti.engine.impl.variable.StringType;
+import org.activiti.engine.impl.variable.ValueFields;
+
+/**
+ * Custom implementation of the Activiti {@link StringType}, which allows string-values
+ * to be larger than the database-restriction of the TEXT_ column, by using binary storage in case
+ * the string value exceeds the size.
+ *
+ * @author Frederik Heremans
+ * @since 4.2
+ */
+public class CustomStringVariableType extends StringType {
+ protected static final int MAX_TEXT_LENGTH = 4000;
+
+ @Override
+ public void setValue(Object value, ValueFields valueFields)
+ {
+ if(value != null && ((String) value).length() > MAX_TEXT_LENGTH)
+ {
+ ByteArrayEntity byteArray = valueFields.getByteArrayValue();
+ byte[] bytes = ((String) value).getBytes();
+ if (byteArray==null)
+ {
+ valueFields.setByteArrayValue(bytes);
+ }
+ else
+ {
+ // Reuse the existing byte-array entity on an update instead of creating a new one each time
+ byteArray.setBytes(bytes);
+ }
+ }
+ else {
+ // Make sure NO byte-array is present anymore in case this variable exceeded the
+ // length before this update, but is shorter now
+ valueFields.setByteArrayValue(null);
+
+ // Revert to storing regular string
+ super.setValue(value, valueFields);
+ }
+ }
+
+ @Override
+ public Object getValue(ValueFields valueFields)
+ {
+ // In case the string is stored as a byte-array, create a string from the stored bytes
+ // using platform encoding and return this instead of the text-value
+ if(valueFields.getByteArrayValueId() != null && valueFields.getByteArrayValue() != null) {
+ return new String(valueFields.getByteArrayValue().getBytes());
+ }
+ return super.getValue(valueFields);
+ }
+}
diff --git a/source/test-java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java b/source/test-java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java
index 23d8ae0bcf..582ac8bd25 100644
--- a/source/test-java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java
+++ b/source/test-java/org/alfresco/repo/workflow/activiti/ActivitiWorkflowServiceIntegrationTest.java
@@ -250,6 +250,46 @@ public class ActivitiWorkflowServiceIntegrationTest extends AbstractWorkflowServ
assertEquals("This is the description", tasks.get(0).getDescription());
}
+ /**
+ * Test to validate fix for WOR-107
+ */
+ public void testLongTextValues() throws Exception
+ {
+ String veryLongTextValue = getLongString(10000);
+ // start pooled review and approve workflow
+ WorkflowDefinition workflowDef = deployDefinition(getAdhocDefinitionPath());
+ assertNotNull(workflowDef);
+
+ // Create workflow parameters
+ Map params = new HashMap();
+ Serializable wfPackage = workflowService.createPackage(null);
+ params.put(WorkflowModel.ASSOC_PACKAGE, wfPackage);
+ Date dueDate = new Date();
+ params.put(WorkflowModel.PROP_WORKFLOW_DUE_DATE, dueDate);
+ params.put(WorkflowModel.PROP_WORKFLOW_PRIORITY, 1);
+ params.put(WorkflowModel.PROP_COMMENT, veryLongTextValue);
+
+ NodeRef assignee = personManager.get(USER2);
+ params.put(WorkflowModel.ASSOC_ASSIGNEE, assignee);
+
+ // No exception should be thrown when using *very* long String variables (in this case, 10000)
+ WorkflowPath path = workflowService.startWorkflow(workflowDef.getId(), params);
+ assertNotNull(path);
+
+ WorkflowTask startTask = workflowService.getStartTask(path.getInstance().getId());
+ assertNotNull(startTask);
+
+ assertEquals(veryLongTextValue, startTask.getProperties().get(WorkflowModel.PROP_COMMENT));
+ }
+
+ protected String getLongString(int numberOfCharacters) {
+ StringBuffer stringBuffer = new StringBuffer();
+ for(int i=0; i