summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bpmn/MSOCoreBPMN/pom.xml6
-rw-r--r--bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/BaseTask.java922
-rw-r--r--bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/internal/VariableNameExtractor.java67
-rw-r--r--bpmn/MSOCoreBPMN/src/test/java/org/openecomp/mso/bpmn/core/internal/VariableNameExtractorTest.java86
4 files changed, 581 insertions, 500 deletions
diff --git a/bpmn/MSOCoreBPMN/pom.xml b/bpmn/MSOCoreBPMN/pom.xml
index b3eddeda41..6884c1e33b 100644
--- a/bpmn/MSOCoreBPMN/pom.xml
+++ b/bpmn/MSOCoreBPMN/pom.xml
@@ -167,5 +167,11 @@
<artifactId>status-control</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>3.8.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/BaseTask.java b/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/BaseTask.java
index e9da2355e4..77e418d4c3 100644
--- a/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/BaseTask.java
+++ b/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/BaseTask.java
@@ -23,510 +23,432 @@ package org.openecomp.mso.bpmn.core;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.Expression;
import org.camunda.bpm.engine.delegate.JavaDelegate;
+import org.openecomp.mso.bpmn.core.internal.VariableNameExtractor;
/**
* Base class for service tasks.
*/
public class BaseTask implements JavaDelegate {
- /**
- * Get the value of a required field. This method throws
- * MissingInjectedFieldException if the expression is null, and
- * BadInjectedFieldException if the expression evaluates to a null
- * value.
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the field value
- */
- protected Object getField(Expression expression,
- DelegateExecution execution, String fieldName) {
- return getFieldImpl(expression, execution, fieldName, false);
- }
-
- /**
- * Gets the value of an optional field. There are three conditions
- * in which this method returns null:
- * <p>
- * <ol>
- * <li> The expression itself is null (i.e. the field is missing
- * altogether.</li>
- * <li>The expression evaluates to a null value.</li>
- * <li>The expression references a single variable which has not
- * been set.</li>
- * </ol>
- * <p>
- * Examples:<br>
- * Expression ${x} when x is null: return null<br>
- * Expression ${x} when x is unset: return null<br>
- * Expression ${x+y} when x and/or y are unset: exception<br>
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the field value, possibly null
- */
- protected Object getOptionalField(Expression expression,
- DelegateExecution execution, String fieldName) {
- return getFieldImpl(expression, execution, fieldName, true);
- }
-
- /**
- * Get the value of a required output variable field. This method
- * throws MissingInjectedFieldException if the expression is null, and
- * BadInjectedFieldException if the expression produces a null or
- * illegal variable name. Legal variable names contain only letters,
- * numbers, and the underscore character ('_').
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the output variable name
- */
- protected String getOutputField(Expression expression,
- DelegateExecution execution, String fieldName) {
- Object o = getFieldImpl(expression, execution, fieldName, false);
- if (o instanceof String) {
- String variable = (String) o;
- if (!isLegalVariable(variable)) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "'" + variable
- + "' is not a legal variable name");
- }
- return variable;
- } else {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "expected a variable name string"
- + ", got object of type " + o.getClass().getName());
- }
- }
-
- /**
- * Get the value of an optional output variable field. This method
- * throws BadInjectedFieldException if the expression produces an illegal
- * variable name. Legal variable names contain only letters, numbers,
- * and the underscore character ('_').
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the output variable name, possibly null
- */
- protected String getOptionalOutputField(Expression expression,
- DelegateExecution execution, String fieldName) {
- Object o = getFieldImpl(expression, execution, fieldName, true);
- if (o instanceof String) {
- String variable = (String) o;
- if (!isLegalVariable(variable)) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "'" + variable
- + "' is not a legal variable name");
- }
- return variable;
- } else if (o == null) {
- return null;
- } else {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "expected a variable name string"
- + ", got object of type " + o.getClass().getName());
- }
- }
-
- /**
- * Get the value of a required string field. This method throws
- * MissingInjectedFieldException if the expression is null, and
- * BadInjectedFieldException if the expression evaluates to a null
- * value.
- * <p>
- * Note: the result is coerced to a string value, if necessary.
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the field value
- */
- protected String getStringField(Expression expression,
- DelegateExecution execution, String fieldName) {
- Object o = getFieldImpl(expression, execution, fieldName, false);
- if (o instanceof String) {
- return (String) o;
- } else {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "cannot convert '" + o.toString()
- + "' to Integer");
- }
- }
-
- /**
- * Gets the value of an optional string field. There are three conditions
- * in which this method returns null:
- * <p>
- * <ol>
- * <li> The expression itself is null (i.e. the field is missing
- * altogether.</li>
- * <li>The expression evaluates to a null value.</li>
- * <li>The expression references a single variable which has not
- * been set.</li>
- * </ol>
- * <p>
- * Examples:<br>
- * Expression ${x} when x is null: return null<br>
- * Expression ${x} when x is unset: return null<br>
- * Expression ${x+y} when x and/or y are unset: exception<br>
- * <p>
- * Note: the result is coerced to a string value, if necessary.
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the field value, possibly null
- */
- protected String getOptionalStringField(Expression expression,
- DelegateExecution execution, String fieldName) {
- Object o = getFieldImpl(expression, execution, fieldName, true);
- if (o instanceof String) {
- return (String) o;
- } else if (o == null) {
- return null;
- } else {
- return o.toString();
- }
- }
-
- /**
- * Get the value of a required integer field. This method throws
- * MissingInjectedFieldException if the expression is null, and
- * BadInjectedFieldException if the expression evaluates to a null
- * value or a value that cannot be coerced to an integer.
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the field value
- */
- protected Integer getIntegerField(Expression expression,
- DelegateExecution execution, String fieldName) {
- Object o = getFieldImpl(expression, execution, fieldName, false);
- if (o instanceof Integer) {
- return (Integer) o;
- } else {
- try {
- return Integer.parseInt(o.toString());
- } catch (NumberFormatException e) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "cannot convert '" + o.toString()
- + "' to Integer");
- }
- }
- }
-
- /**
- * Gets the value of an optional integer field. There are three conditions
- * in which this method returns null:
- * <p>
- * <ol>
- * <li> The expression itself is null (i.e. the field is missing
- * altogether.</li>
- * <li>The expression evaluates to a null value.</li>
- * <li>The expression references a single variable which has not
- * been set.</li>
- * </ol>
- * <p>
- * Examples:<br>
- * Expression ${x} when x is null: return null<br>
- * Expression ${x} when x is unset: return null<br>
- * Expression ${x+y} when x and/or y are unset: exception<br>
- * <p>
- * Note: the result is coerced to an integer value, if necessary. This
- * method throws BadInjectedFieldException if the result cannot be coerced
- * to an integer.
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the field value, possibly null
- */
- protected Integer getOptionalIntegerField(Expression expression,
- DelegateExecution execution, String fieldName) {
- Object o = getFieldImpl(expression, execution, fieldName, true);
- if (o instanceof Integer) {
- return (Integer) o;
- } else if (o == null) {
- return null;
- } else {
- try {
- return Integer.parseInt(o.toString());
- } catch (NumberFormatException e) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "cannot convert '" + o.toString()
- + "' to Integer");
- }
- }
- }
-
- /**
- * Gets the value of an optional long field. There are three conditions
- * in which this method returns null:
- * <p>
- * <ol>
- * <li> The expression itself is null (i.e. the field is missing
- * altogether.</li>
- * <li>The expression evaluates to a null value.</li>
- * <li>The expression references a single variable which has not
- * been set.</li>
- * </ol>
- * <p>
- * Examples:<br>
- * Expression ${x} when x is null: return null<br>
- * Expression ${x} when x is unset: return null<br>
- * Expression ${x+y} when x and/or y are unset: exception<br>
- * <p>
- * Note: the result is coerced to a long value, if necessary. This
- * method throws BadInjectedFieldException if the result cannot be coerced
- * to a long.
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the field value, possibly null
- */
- protected Long getOptionalLongField(Expression expression,
- DelegateExecution execution, String fieldName) {
- Object o = getFieldImpl(expression, execution, fieldName, true);
- if (o instanceof Long) {
- return (Long) o;
- } else if (o == null) {
- return null;
- } else {
- try {
- return Long.parseLong(o.toString());
- } catch (NumberFormatException e) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "cannot convert '" + o.toString()
- + "' to Long");
- }
- }
- }
-
- /**
- * Get the value of a required long field. This method throws
- * MissingInjectedFieldException if the expression is null, and
- * BadInjectedFieldException if the expression evaluates to a null
- * value or a value that cannot be coerced to a long.
- *
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @return the field value
- */
- protected Long getLongField(Expression expression,
- DelegateExecution execution, String fieldName) {
- Object o = getFieldImpl(expression, execution, fieldName, false);
- if (o instanceof Long) {
- return (Long) o;
- } else {
- try {
- return Long.parseLong(o.toString());
- } catch (NumberFormatException e) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "cannot convert '" + o.toString()
- + "' to Long");
- }
- }
- }
-
- /**
- * Common implementation for field "getter" methods.
- * @param expression the expression
- * @param execution the execution
- * @param fieldName the field name (for logging and exceptions)
- * @param optional true if the field is optional
- * @return the field value, possibly null
- */
- private Object getFieldImpl(Expression expression,
- DelegateExecution execution, String fieldName, boolean optional) {
- if (expression == null) {
- if (!optional) {
- throw new MissingInjectedFieldException(
- fieldName, getTaskName());
- }
- return null;
- }
-
- Object value;
-
- try {
- value = expression.getValue(execution);
- } catch (Exception e) {
- if (!optional) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), e.getClass().getSimpleName(), e);
- }
-
- // At this point, we have an exception that occurred while
- // evaluating an expression for an optional field. A common
- // problem is that the expression is a simple reference to a
- // variable which has never been set, e.g. the expression is
- // ${x}. The normal activiti behavior is to throw an exception,
- // but we don't like that, so we have the following workaround,
- // which parses the expression text to see if it is a "simple"
- // variable reference, and if so, returns null. If the
- // expression is anything other than a single variable
- // reference, then an exception is thrown, as it would have
- // been without this workaround.
-
- // Get the expression text so we can parse it
- String s = expression.getExpressionText();
-
-// if (isDebugEnabled(execution)) {
-// logDebug(execution, getTaskName() + " field '" + fieldName
-// + "' expression evaluation failed: " + s);
-// }
-
- int len = s.length();
- int i = 0;
-
- // Skip whitespace
- while (i < len && Character.isWhitespace(s.charAt(i))) {
- i++;
- }
-
- // Next character must be '$'
- if (i == len || s.charAt(i++) != '$') {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), e.getClass().getSimpleName(), e);
- }
-
- // Skip whitespace
- while (i < len && Character.isWhitespace(s.charAt(i))) {
- i++;
- }
-
- // Next character must be '{'
- if (i == len || s.charAt(i++) != '{') {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), e.getClass().getSimpleName(), e);
- }
-
- // Skip whitespace
- while (i < len && Character.isWhitespace(s.charAt(i))) {
- i++;
- }
-
- // Collect the variable name
- StringBuilder variable = new StringBuilder();
- while (i < len && isWordCharacter(s.charAt(i))) {
- variable.append(s.charAt(i));
- i++;
- }
-
- if (variable.length() == 0) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), e.getClass().getSimpleName(), e);
- }
-
- // Skip whitespace
- while (i < len && Character.isWhitespace(s.charAt(i))) {
- i++;
- }
-
- // Next character must be '}'
- if (i == len || s.charAt(i++) != '}') {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), e.getClass().getSimpleName(), e);
- }
-
- // Skip whitespace
- while (i < len && Character.isWhitespace(s.charAt(i))) {
- i++;
- }
-
- // Must be at end of string
- if (i != len) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), e.getClass().getSimpleName(), e);
- }
-
-// if (isDebugEnabled(execution)) {
-// logDebug(execution, "Checking if variable '"
-// + variable.toString() + "' exists");
-// }
-
- // If the variable exists then the problem was
- // something else...
- if (execution.hasVariable(variable.toString())) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), e.getClass().getSimpleName(), e);
- }
-
- // The variable doesn't exist.
-
-// if (isDebugEnabled(execution)) {
-// logDebug(execution, "Variable '" + variable.toString()
-// + "' does not exist [ok]");
-// }
-
- value = null;
- }
-
- if (value == null && !optional) {
- throw new BadInjectedFieldException(
- fieldName, getTaskName(), "required field has null value");
- }
-
- return value;
- }
-
- /**
- * Tests if a character is a "word" character.
- * @param c the character
- * @return true if the character is a "word" character.
- */
- private boolean isWordCharacter(char c) {
- return (Character.isLetterOrDigit(c) || c == '_');
- }
-
- /**
- * Tests if the specified string is a legal flow variable name.
- * @param name the string
- * @return true if the string is a legal flow variable name
- */
- private boolean isLegalVariable(String name) {
- if (name == null) {
- return false;
- }
-
- int len = name.length();
-
- if (len == 0) {
- return false;
- }
-
- char c = name.charAt(0);
-
- if (!Character.isLetter(c) && c != '_') {
- return false;
- }
-
- for (int i = 1; i < len; i++) {
- c = name.charAt(i);
- if (!Character.isLetterOrDigit(c) && c != '_') {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Returns the name of the task (normally the java class name).
- * @return the name of the task
- */
- public String getTaskName() {
- return getClass().getSimpleName();
- }
-
- @Override
- public void execute(DelegateExecution execution) throws Exception { }
+ /**
+ * Get the value of a required field. This method throws
+ * MissingInjectedFieldException if the expression is null, and
+ * BadInjectedFieldException if the expression evaluates to a null
+ * value.
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the field value
+ */
+ protected Object getField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ return getFieldImpl(expression, execution, fieldName, false);
+ }
+
+ /**
+ * Gets the value of an optional field. There are three conditions
+ * in which this method returns null:
+ * <p>
+ * <ol>
+ * <li> The expression itself is null (i.e. the field is missing
+ * altogether.</li>
+ * <li>The expression evaluates to a null value.</li>
+ * <li>The expression references a single variable which has not
+ * been set.</li>
+ * </ol>
+ * <p>
+ * Examples:<br>
+ * Expression ${x} when x is null: return null<br>
+ * Expression ${x} when x is unset: return null<br>
+ * Expression ${x+y} when x and/or y are unset: exception<br>
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the field value, possibly null
+ */
+ protected Object getOptionalField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ return getFieldImpl(expression, execution, fieldName, true);
+ }
+
+ /**
+ * Get the value of a required output variable field. This method
+ * throws MissingInjectedFieldException if the expression is null, and
+ * BadInjectedFieldException if the expression produces a null or
+ * illegal variable name. Legal variable names contain only letters,
+ * numbers, and the underscore character ('_').
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the output variable name
+ */
+ protected String getOutputField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ Object o = getFieldImpl(expression, execution, fieldName, false);
+ if (o instanceof String) {
+ String variable = (String) o;
+ if (!isLegalVariable(variable)) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "'" + variable
+ + "' is not a legal variable name");
+ }
+ return variable;
+ } else {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "expected a variable name string"
+ + ", got object of type " + o.getClass().getName());
+ }
+ }
+
+ /**
+ * Get the value of an optional output variable field. This method
+ * throws BadInjectedFieldException if the expression produces an illegal
+ * variable name. Legal variable names contain only letters, numbers,
+ * and the underscore character ('_').
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the output variable name, possibly null
+ */
+ protected String getOptionalOutputField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ Object o = getFieldImpl(expression, execution, fieldName, true);
+ if (o instanceof String) {
+ String variable = (String) o;
+ if (!isLegalVariable(variable)) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "'" + variable
+ + "' is not a legal variable name");
+ }
+ return variable;
+ } else if (o == null) {
+ return null;
+ } else {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "expected a variable name string"
+ + ", got object of type " + o.getClass().getName());
+ }
+ }
+
+ /**
+ * Get the value of a required string field. This method throws
+ * MissingInjectedFieldException if the expression is null, and
+ * BadInjectedFieldException if the expression evaluates to a null
+ * value.
+ * <p>
+ * Note: the result is coerced to a string value, if necessary.
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the field value
+ */
+ protected String getStringField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ Object o = getFieldImpl(expression, execution, fieldName, false);
+ if (o instanceof String) {
+ return (String) o;
+ } else {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "cannot convert '" + o.toString()
+ + "' to Integer");
+ }
+ }
+
+ /**
+ * Gets the value of an optional string field. There are three conditions
+ * in which this method returns null:
+ * <p>
+ * <ol>
+ * <li> The expression itself is null (i.e. the field is missing
+ * altogether.</li>
+ * <li>The expression evaluates to a null value.</li>
+ * <li>The expression references a single variable which has not
+ * been set.</li>
+ * </ol>
+ * <p>
+ * Examples:<br>
+ * Expression ${x} when x is null: return null<br>
+ * Expression ${x} when x is unset: return null<br>
+ * Expression ${x+y} when x and/or y are unset: exception<br>
+ * <p>
+ * Note: the result is coerced to a string value, if necessary.
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the field value, possibly null
+ */
+ protected String getOptionalStringField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ Object o = getFieldImpl(expression, execution, fieldName, true);
+ if (o instanceof String) {
+ return (String) o;
+ } else if (o == null) {
+ return null;
+ } else {
+ return o.toString();
+ }
+ }
+
+ /**
+ * Get the value of a required integer field. This method throws
+ * MissingInjectedFieldException if the expression is null, and
+ * BadInjectedFieldException if the expression evaluates to a null
+ * value or a value that cannot be coerced to an integer.
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the field value
+ */
+ protected Integer getIntegerField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ Object o = getFieldImpl(expression, execution, fieldName, false);
+ if (o instanceof Integer) {
+ return (Integer) o;
+ } else {
+ try {
+ return Integer.parseInt(o.toString());
+ } catch (NumberFormatException e) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "cannot convert '" + o.toString()
+ + "' to Integer");
+ }
+ }
+ }
+
+ /**
+ * Gets the value of an optional integer field. There are three conditions
+ * in which this method returns null:
+ * <p>
+ * <ol>
+ * <li> The expression itself is null (i.e. the field is missing
+ * altogether.</li>
+ * <li>The expression evaluates to a null value.</li>
+ * <li>The expression references a single variable which has not
+ * been set.</li>
+ * </ol>
+ * <p>
+ * Examples:<br>
+ * Expression ${x} when x is null: return null<br>
+ * Expression ${x} when x is unset: return null<br>
+ * Expression ${x+y} when x and/or y are unset: exception<br>
+ * <p>
+ * Note: the result is coerced to an integer value, if necessary. This
+ * method throws BadInjectedFieldException if the result cannot be coerced
+ * to an integer.
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the field value, possibly null
+ */
+ protected Integer getOptionalIntegerField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ Object o = getFieldImpl(expression, execution, fieldName, true);
+ if (o instanceof Integer) {
+ return (Integer) o;
+ } else if (o == null) {
+ return null;
+ } else {
+ try {
+ return Integer.parseInt(o.toString());
+ } catch (NumberFormatException e) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "cannot convert '" + o.toString()
+ + "' to Integer");
+ }
+ }
+ }
+
+ /**
+ * Gets the value of an optional long field. There are three conditions
+ * in which this method returns null:
+ * <p>
+ * <ol>
+ * <li> The expression itself is null (i.e. the field is missing
+ * altogether.</li>
+ * <li>The expression evaluates to a null value.</li>
+ * <li>The expression references a single variable which has not
+ * been set.</li>
+ * </ol>
+ * <p>
+ * Examples:<br>
+ * Expression ${x} when x is null: return null<br>
+ * Expression ${x} when x is unset: return null<br>
+ * Expression ${x+y} when x and/or y are unset: exception<br>
+ * <p>
+ * Note: the result is coerced to a long value, if necessary. This
+ * method throws BadInjectedFieldException if the result cannot be coerced
+ * to a long.
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the field value, possibly null
+ */
+ protected Long getOptionalLongField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ Object o = getFieldImpl(expression, execution, fieldName, true);
+ if (o instanceof Long) {
+ return (Long) o;
+ } else if (o == null) {
+ return null;
+ } else {
+ try {
+ return Long.parseLong(o.toString());
+ } catch (NumberFormatException e) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "cannot convert '" + o.toString()
+ + "' to Long");
+ }
+ }
+ }
+
+ /**
+ * Get the value of a required long field. This method throws
+ * MissingInjectedFieldException if the expression is null, and
+ * BadInjectedFieldException if the expression evaluates to a null
+ * value or a value that cannot be coerced to a long.
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @return the field value
+ */
+ protected Long getLongField(Expression expression,
+ DelegateExecution execution, String fieldName) {
+ Object o = getFieldImpl(expression, execution, fieldName, false);
+ if (o instanceof Long) {
+ return (Long) o;
+ } else {
+ try {
+ return Long.parseLong(o.toString());
+ } catch (NumberFormatException e) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "cannot convert '" + o.toString()
+ + "' to Long");
+ }
+ }
+ }
+
+ /**
+ * Common implementation for field "getter" methods.
+ *
+ * @param expression the expression
+ * @param execution the execution
+ * @param fieldName the field name (for logging and exceptions)
+ * @param optional true if the field is optional
+ * @return the field value, possibly null
+ */
+ private Object getFieldImpl(Expression expression,
+ DelegateExecution execution, String fieldName, boolean optional) {
+ if (expression == null) {
+ if (!optional) {
+ throw new MissingInjectedFieldException(
+ fieldName, getTaskName());
+ }
+ return null;
+ }
+
+ Object value = null;
+
+ try {
+ value = expression.getValue(execution);
+ } catch (Exception e) {
+ if (!optional) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), e.getClass().getSimpleName(), e);
+ }
+
+ // At this point, we have an exception that occurred while
+ // evaluating an expression for an optional field. A common
+ // problem is that the expression is a simple reference to a
+ // variable which has never been set, e.g. the expression is
+ // ${x}. The normal activiti behavior is to throw an exception,
+ // but we don't like that, so we have the following workaround,
+ // which parses the expression text to see if it is a "simple"
+ // variable reference, and if so, returns null. If the
+ // expression is anything other than a single variable
+ // reference, then an exception is thrown, as it would have
+ // been without this workaround.
+
+ // Get the expression text so we can parse it
+ String s = expression.getExpressionText();
+ new VariableNameExtractor(s).extract().ifPresent(name -> {
+ if (execution.hasVariable(name)) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), e.getClass().getSimpleName(), e);
+ }
+ });
+ }
+
+ if (value == null && !optional) {
+ throw new BadInjectedFieldException(
+ fieldName, getTaskName(), "required field has null value");
+ }
+
+ return value;
+ }
+
+ /**
+ * Tests if a character is a "word" character.
+ *
+ * @param c the character
+ * @return true if the character is a "word" character.
+ */
+ private static boolean isWordCharacter(char c) {
+ return (Character.isLetterOrDigit(c) || c == '_');
+ }
+
+ /**
+ * Tests if the specified string is a legal flow variable name.
+ *
+ * @param name the string
+ * @return true if the string is a legal flow variable name
+ */
+ private boolean isLegalVariable(String name) {
+ if (name == null) {
+ return false;
+ }
+
+ int len = name.length();
+
+ if (len == 0) {
+ return false;
+ }
+
+ char c = name.charAt(0);
+
+ if (!Character.isLetter(c) && c != '_') {
+ return false;
+ }
+
+ for (int i = 1; i < len; i++) {
+ c = name.charAt(i);
+ if (!Character.isLetterOrDigit(c) && c != '_') {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the name of the task (normally the java class name).
+ *
+ * @return the name of the task
+ */
+ public String getTaskName() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void execute(DelegateExecution execution) throws Exception {
+ }
}
diff --git a/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/internal/VariableNameExtractor.java b/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/internal/VariableNameExtractor.java
new file mode 100644
index 0000000000..e1aaba74da
--- /dev/null
+++ b/bpmn/MSOCoreBPMN/src/main/java/org/openecomp/mso/bpmn/core/internal/VariableNameExtractor.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.mso.bpmn.core.internal;
+
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Extracts variable name from expression if entire expression is just
+ * one variable, for example "${x}".
+ *
+ * Ignores all whitespaces, except inside variable name.
+ *
+ * Examples:
+ * "${x}", extracted variable name is "x"
+ * " ${\t weird_NAME }", extracted variable name is "weird_NAME"
+ * "${incorrect name}", no extracted name
+ * "${two}+${two}", no extracted name
+ */
+public class VariableNameExtractor {
+
+ private static final Pattern VARIABLE_NAME_PATTERN = Pattern
+ .compile("^\\s*\\$\\s*\\{\\s*([a-zA-Z0-9_]+)\\s*\\}\\s*$");
+
+ private final String expression;
+
+
+ /**
+ * Creates new VariableNameExtractor
+ * @param expression expression to be parsed
+ */
+ public VariableNameExtractor(String expression) {
+ this.expression = expression;
+ }
+
+ /**
+ * Extracts variable name from expression given in constructor
+ * @return Optional of variable name, empty if expression wasn't single variable
+ */
+ public Optional<String> extract() {
+ Matcher matcher = VARIABLE_NAME_PATTERN.matcher(expression);
+ if (!matcher.matches()) {
+ return Optional.empty();
+ }
+ return Optional.of(matcher.group(1));
+ }
+
+}
diff --git a/bpmn/MSOCoreBPMN/src/test/java/org/openecomp/mso/bpmn/core/internal/VariableNameExtractorTest.java b/bpmn/MSOCoreBPMN/src/test/java/org/openecomp/mso/bpmn/core/internal/VariableNameExtractorTest.java
new file mode 100644
index 0000000000..57f479f7cb
--- /dev/null
+++ b/bpmn/MSOCoreBPMN/src/test/java/org/openecomp/mso/bpmn/core/internal/VariableNameExtractorTest.java
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.mso.bpmn.core.internal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Optional;
+import org.junit.Test;
+
+public class VariableNameExtractorTest {
+
+ @Test
+ public void shouldExtractVariableName() throws Exception {
+ // given
+ String name = "A_different_NAME123";
+ String variable = "${A_different_NAME123}";
+ VariableNameExtractor extractor = new VariableNameExtractor(variable);
+ // when
+ Optional<String> extracted = extractor.extract();
+ // then
+ assertThat(extracted).isPresent().contains(name);
+ }
+
+ @Test
+ public void shouldExtractVariableNameFromWhitespaces() throws Exception {
+ // given
+ String name = "name";
+ String variable = " \n\t$ \n\t{ \n\tname \n\t} \n\t";
+ VariableNameExtractor extractor = new VariableNameExtractor(variable);
+ // when
+ Optional<String> extracted = extractor.extract();
+ // then
+ assertThat(extracted).isPresent().contains(name);
+ }
+
+ @Test
+ public void shouldReturnEmptyIfThereIsMoreThanVariable() throws Exception {
+ // given
+ String variable = "a ${test}";
+ VariableNameExtractor extractor = new VariableNameExtractor(variable);
+ // when
+ Optional<String> extracted = extractor.extract();
+ // then
+ assertThat(extracted).isNotPresent();
+ }
+
+ @Test
+ public void shouldReturnEmptyIfVariableNameIsIncorrect() throws Exception {
+ // given
+ String variable = "${name with space}";
+ VariableNameExtractor extractor = new VariableNameExtractor(variable);
+ // when
+ Optional<String> extracted = extractor.extract();
+ // then
+ assertThat(extracted).isNotPresent();
+ }
+
+ @Test
+ public void shouldReturnEmptyIfTwoVariablesPresent() throws Exception {
+ // given
+ String variable = "${var1} ${var2}";
+ VariableNameExtractor extractor = new VariableNameExtractor(variable);
+ // when
+ Optional<String> extracted = extractor.extract();
+ // then
+ assertThat(extracted).isNotPresent();
+ }
+} \ No newline at end of file