2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.mso.bpmn.core;
23 import org.camunda.bpm.engine.delegate.DelegateExecution;
24 import org.camunda.bpm.engine.delegate.Expression;
25 import org.camunda.bpm.engine.delegate.JavaDelegate;
28 * Base class for service tasks.
30 public class BaseTask implements JavaDelegate {
33 * Get the value of a required field. This method throws
34 * MissingInjectedFieldException if the expression is null, and
35 * BadInjectedFieldException if the expression evaluates to a null
38 * @param expression the expression
39 * @param execution the execution
40 * @param fieldName the field name (for logging and exceptions)
41 * @return the field value
43 protected Object getField(Expression expression,
44 DelegateExecution execution, String fieldName) {
45 return getFieldImpl(expression, execution, fieldName, false);
49 * Gets the value of an optional field. There are three conditions
50 * in which this method returns null:
53 * <li> The expression itself is null (i.e. the field is missing
55 * <li>The expression evaluates to a null value.</li>
56 * <li>The expression references a single variable which has not
61 * Expression ${x} when x is null: return null<br>
62 * Expression ${x} when x is unset: return null<br>
63 * Expression ${x+y} when x and/or y are unset: exception<br>
65 * @param expression the expression
66 * @param execution the execution
67 * @param fieldName the field name (for logging and exceptions)
68 * @return the field value, possibly null
70 protected Object getOptionalField(Expression expression,
71 DelegateExecution execution, String fieldName) {
72 return getFieldImpl(expression, execution, fieldName, true);
76 * Get the value of a required output variable field. This method
77 * throws MissingInjectedFieldException if the expression is null, and
78 * BadInjectedFieldException if the expression produces a null or
79 * illegal variable name. Legal variable names contain only letters,
80 * numbers, and the underscore character ('_').
82 * @param expression the expression
83 * @param execution the execution
84 * @param fieldName the field name (for logging and exceptions)
85 * @return the output variable name
87 protected String getOutputField(Expression expression,
88 DelegateExecution execution, String fieldName) {
89 Object o = getFieldImpl(expression, execution, fieldName, false);
90 if (o instanceof String) {
91 String variable = (String) o;
92 if (!isLegalVariable(variable)) {
93 throw new BadInjectedFieldException(
94 fieldName, getTaskName(), "'" + variable
95 + "' is not a legal variable name");
99 throw new BadInjectedFieldException(
100 fieldName, getTaskName(), "expected a variable name string"
101 + ", got object of type " + o.getClass().getName());
106 * Get the value of an optional output variable field. This method
107 * throws BadInjectedFieldException if the expression produces an illegal
108 * variable name. Legal variable names contain only letters, numbers,
109 * and the underscore character ('_').
111 * @param expression the expression
112 * @param execution the execution
113 * @param fieldName the field name (for logging and exceptions)
114 * @return the output variable name, possibly null
116 protected String getOptionalOutputField(Expression expression,
117 DelegateExecution execution, String fieldName) {
118 Object o = getFieldImpl(expression, execution, fieldName, true);
119 if (o instanceof String) {
120 String variable = (String) o;
121 if (!isLegalVariable(variable)) {
122 throw new BadInjectedFieldException(
123 fieldName, getTaskName(), "'" + variable
124 + "' is not a legal variable name");
127 } else if (o == null) {
130 throw new BadInjectedFieldException(
131 fieldName, getTaskName(), "expected a variable name string"
132 + ", got object of type " + o.getClass().getName());
137 * Get the value of a required string field. This method throws
138 * MissingInjectedFieldException if the expression is null, and
139 * BadInjectedFieldException if the expression evaluates to a null
142 * Note: the result is coerced to a string value, if necessary.
144 * @param expression the expression
145 * @param execution the execution
146 * @param fieldName the field name (for logging and exceptions)
147 * @return the field value
149 protected String getStringField(Expression expression,
150 DelegateExecution execution, String fieldName) {
151 Object o = getFieldImpl(expression, execution, fieldName, false);
152 if (o instanceof String) {
155 throw new BadInjectedFieldException(
156 fieldName, getTaskName(), "cannot convert '" + o.toString()
162 * Gets the value of an optional string field. There are three conditions
163 * in which this method returns null:
166 * <li> The expression itself is null (i.e. the field is missing
168 * <li>The expression evaluates to a null value.</li>
169 * <li>The expression references a single variable which has not
174 * Expression ${x} when x is null: return null<br>
175 * Expression ${x} when x is unset: return null<br>
176 * Expression ${x+y} when x and/or y are unset: exception<br>
178 * Note: the result is coerced to a string value, if necessary.
180 * @param expression the expression
181 * @param execution the execution
182 * @param fieldName the field name (for logging and exceptions)
183 * @return the field value, possibly null
185 protected String getOptionalStringField(Expression expression,
186 DelegateExecution execution, String fieldName) {
187 Object o = getFieldImpl(expression, execution, fieldName, true);
188 if (o instanceof String) {
190 } else if (o == null) {
198 * Get the value of a required integer field. This method throws
199 * MissingInjectedFieldException if the expression is null, and
200 * BadInjectedFieldException if the expression evaluates to a null
201 * value or a value that cannot be coerced to an integer.
203 * @param expression the expression
204 * @param execution the execution
205 * @param fieldName the field name (for logging and exceptions)
206 * @return the field value
208 protected Integer getIntegerField(Expression expression,
209 DelegateExecution execution, String fieldName) {
210 Object o = getFieldImpl(expression, execution, fieldName, false);
211 if (o instanceof Integer) {
215 return Integer.parseInt(o.toString());
216 } catch (NumberFormatException e) {
217 throw new BadInjectedFieldException(
218 fieldName, getTaskName(), "cannot convert '" + o.toString()
225 * Gets the value of an optional integer field. There are three conditions
226 * in which this method returns null:
229 * <li> The expression itself is null (i.e. the field is missing
231 * <li>The expression evaluates to a null value.</li>
232 * <li>The expression references a single variable which has not
237 * Expression ${x} when x is null: return null<br>
238 * Expression ${x} when x is unset: return null<br>
239 * Expression ${x+y} when x and/or y are unset: exception<br>
241 * Note: the result is coerced to an integer value, if necessary. This
242 * method throws BadInjectedFieldException if the result cannot be coerced
245 * @param expression the expression
246 * @param execution the execution
247 * @param fieldName the field name (for logging and exceptions)
248 * @return the field value, possibly null
250 protected Integer getOptionalIntegerField(Expression expression,
251 DelegateExecution execution, String fieldName) {
252 Object o = getFieldImpl(expression, execution, fieldName, true);
253 if (o instanceof Integer) {
255 } else if (o == null) {
259 return Integer.parseInt(o.toString());
260 } catch (NumberFormatException e) {
261 throw new BadInjectedFieldException(
262 fieldName, getTaskName(), "cannot convert '" + o.toString()
269 * Gets the value of an optional long field. There are three conditions
270 * in which this method returns null:
273 * <li> The expression itself is null (i.e. the field is missing
275 * <li>The expression evaluates to a null value.</li>
276 * <li>The expression references a single variable which has not
281 * Expression ${x} when x is null: return null<br>
282 * Expression ${x} when x is unset: return null<br>
283 * Expression ${x+y} when x and/or y are unset: exception<br>
285 * Note: the result is coerced to a long value, if necessary. This
286 * method throws BadInjectedFieldException if the result cannot be coerced
289 * @param expression the expression
290 * @param execution the execution
291 * @param fieldName the field name (for logging and exceptions)
292 * @return the field value, possibly null
294 protected Long getOptionalLongField(Expression expression,
295 DelegateExecution execution, String fieldName) {
296 Object o = getFieldImpl(expression, execution, fieldName, true);
297 if (o instanceof Long) {
299 } else if (o == null) {
303 return Long.parseLong(o.toString());
304 } catch (NumberFormatException e) {
305 throw new BadInjectedFieldException(
306 fieldName, getTaskName(), "cannot convert '" + o.toString()
313 * Get the value of a required long field. This method throws
314 * MissingInjectedFieldException if the expression is null, and
315 * BadInjectedFieldException if the expression evaluates to a null
316 * value or a value that cannot be coerced to a long.
318 * @param expression the expression
319 * @param execution the execution
320 * @param fieldName the field name (for logging and exceptions)
321 * @return the field value
323 protected Long getLongField(Expression expression,
324 DelegateExecution execution, String fieldName) {
325 Object o = getFieldImpl(expression, execution, fieldName, false);
326 if (o instanceof Long) {
330 return Long.parseLong(o.toString());
331 } catch (NumberFormatException e) {
332 throw new BadInjectedFieldException(
333 fieldName, getTaskName(), "cannot convert '" + o.toString()
340 * Common implementation for field "getter" methods.
341 * @param expression the expression
342 * @param execution the execution
343 * @param fieldName the field name (for logging and exceptions)
344 * @param optional true if the field is optional
345 * @return the field value, possibly null
347 private Object getFieldImpl(Expression expression,
348 DelegateExecution execution, String fieldName, boolean optional) {
349 if (expression == null) {
351 throw new MissingInjectedFieldException(
352 fieldName, getTaskName());
360 value = expression.getValue(execution);
361 } catch (Exception e) {
363 throw new BadInjectedFieldException(
364 fieldName, getTaskName(), e.getClass().getSimpleName(), e);
367 // At this point, we have an exception that occurred while
368 // evaluating an expression for an optional field. A common
369 // problem is that the expression is a simple reference to a
370 // variable which has never been set, e.g. the expression is
371 // ${x}. The normal activiti behavior is to throw an exception,
372 // but we don't like that, so we have the following workaround,
373 // which parses the expression text to see if it is a "simple"
374 // variable reference, and if so, returns null. If the
375 // expression is anything other than a single variable
376 // reference, then an exception is thrown, as it would have
377 // been without this workaround.
379 // Get the expression text so we can parse it
380 String s = expression.getExpressionText();
382 // if (isDebugEnabled(execution)) {
383 // logDebug(execution, getTaskName() + " field '" + fieldName
384 // + "' expression evaluation failed: " + s);
387 int len = s.length();
391 while (i < len && Character.isWhitespace(s.charAt(i))) {
395 // Next character must be '$'
396 if (i == len || s.charAt(i++) != '$') {
397 throw new BadInjectedFieldException(
398 fieldName, getTaskName(), e.getClass().getSimpleName(), e);
402 while (i < len && Character.isWhitespace(s.charAt(i))) {
406 // Next character must be '{'
407 if (i == len || s.charAt(i++) != '{') {
408 throw new BadInjectedFieldException(
409 fieldName, getTaskName(), e.getClass().getSimpleName(), e);
413 while (i < len && Character.isWhitespace(s.charAt(i))) {
417 // Collect the variable name
418 StringBuilder variable = new StringBuilder();
419 while (i < len && isWordCharacter(s.charAt(i))) {
420 variable.append(s.charAt(i));
424 if (variable.length() == 0) {
425 throw new BadInjectedFieldException(
426 fieldName, getTaskName(), e.getClass().getSimpleName(), e);
430 while (i < len && Character.isWhitespace(s.charAt(i))) {
434 // Next character must be '}'
435 if (i == len || s.charAt(i++) != '}') {
436 throw new BadInjectedFieldException(
437 fieldName, getTaskName(), e.getClass().getSimpleName(), e);
441 while (i < len && Character.isWhitespace(s.charAt(i))) {
445 // Must be at end of string
447 throw new BadInjectedFieldException(
448 fieldName, getTaskName(), e.getClass().getSimpleName(), e);
451 // if (isDebugEnabled(execution)) {
452 // logDebug(execution, "Checking if variable '"
453 // + variable.toString() + "' exists");
456 // If the variable exists then the problem was
458 if (execution.hasVariable(variable.toString())) {
459 throw new BadInjectedFieldException(
460 fieldName, getTaskName(), e.getClass().getSimpleName(), e);
463 // The variable doesn't exist.
465 // if (isDebugEnabled(execution)) {
466 // logDebug(execution, "Variable '" + variable.toString()
467 // + "' does not exist [ok]");
473 if (value == null && !optional) {
474 throw new BadInjectedFieldException(
475 fieldName, getTaskName(), "required field has null value");
482 * Tests if a character is a "word" character.
483 * @param c the character
484 * @return true if the character is a "word" character.
486 private boolean isWordCharacter(char c) {
487 return (Character.isLetterOrDigit(c) || c == '_');
491 * Tests if the specified string is a legal flow variable name.
492 * @param name the string
493 * @return true if the string is a legal flow variable name
495 private boolean isLegalVariable(String name) {
500 int len = name.length();
506 char c = name.charAt(0);
508 if (!Character.isLetter(c) && c != '_') {
512 for (int i = 1; i < len; i++) {
514 if (!Character.isLetterOrDigit(c) && c != '_') {
523 * Returns the name of the task (normally the java class name).
524 * @return the name of the task
526 public String getTaskName() {
527 return getClass().getSimpleName();
531 public void execute(DelegateExecution execution) throws Exception { }