All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.flowable.engine.impl.delegate.JsonVariableAggregator Maven / Gradle / Ivy

There is a newer version: 7.0.1
Show newest version
/* 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.flowable.engine.impl.delegate;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.VariableAggregationDefinition;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.variable.VariableAggregator;
import org.flowable.engine.delegate.variable.VariableAggregatorContext;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.variable.api.persistence.entity.VariableInstance;
import org.flowable.variable.api.types.VariableType;
import org.flowable.variable.api.types.VariableTypes;
import org.flowable.variable.service.VariableService;
import org.flowable.variable.service.impl.types.BooleanType;
import org.flowable.variable.service.impl.types.ByteArrayType;
import org.flowable.variable.service.impl.types.DateType;
import org.flowable.variable.service.impl.types.DoubleType;
import org.flowable.variable.service.impl.types.InstantType;
import org.flowable.variable.service.impl.types.IntegerType;
import org.flowable.variable.service.impl.types.JodaDateTimeType;
import org.flowable.variable.service.impl.types.JodaDateType;
import org.flowable.variable.service.impl.types.JsonType;
import org.flowable.variable.service.impl.types.LocalDateTimeType;
import org.flowable.variable.service.impl.types.LocalDateType;
import org.flowable.variable.service.impl.types.LongStringType;
import org.flowable.variable.service.impl.types.LongType;
import org.flowable.variable.service.impl.types.NullType;
import org.flowable.variable.service.impl.types.ShortType;
import org.flowable.variable.service.impl.types.StringType;
import org.flowable.variable.service.impl.types.UUIDType;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * @author Filip Hrisafov
 */
public class JsonVariableAggregator implements VariableAggregator {

    protected final ProcessEngineConfigurationImpl processEngineConfiguration;

    public JsonVariableAggregator(ProcessEngineConfigurationImpl processEngineConfiguration) {
        this.processEngineConfiguration = processEngineConfiguration;
    }

    @Override
    public Object aggregateSingleVariable(DelegateExecution execution, VariableAggregatorContext context) {
        ObjectNode objectNode = processEngineConfiguration.getObjectMapper().createObjectNode();

        VariableService variableService = processEngineConfiguration.getVariableServiceConfiguration().getVariableService();
        VariableTypes variableTypes = processEngineConfiguration.getVariableServiceConfiguration().getVariableTypes();

        for (VariableAggregationDefinition.Variable definition : context.getDefinition().getDefinitions()) {
            String targetVarName = null;
            if (StringUtils.isNotEmpty(definition.getTargetExpression())) {
                Object value = processEngineConfiguration.getExpressionManager()
                        .createExpression(definition.getTargetExpression())
                        .getValue(execution);
                if (value != null) {
                    targetVarName = value.toString();
                }
            } else if (StringUtils.isNotEmpty(definition.getTarget())) {
                targetVarName = definition.getTarget();
            } else if (StringUtils.isNotEmpty(definition.getSource())) {
                targetVarName = definition.getSource();
            }

            if (targetVarName != null) {
                VariableInstance varInstance = null;
                if (StringUtils.isNotEmpty(definition.getSource())) {
                    varInstance = execution.getVariableInstance(definition.getSource());

                } else if (StringUtils.isNotEmpty(definition.getSourceExpression())) {
                    Object sourceValue = processEngineConfiguration.getExpressionManager()
                            .createExpression(definition.getSourceExpression())
                            .getValue(execution);
                    VariableType variableType = variableTypes.findVariableType(sourceValue);
                    // This is a fake variable instance so we can get the type of it
                    varInstance = variableService.createVariableInstance(targetVarName, variableType, sourceValue);
                }

                if (varInstance != null) {

                    String varInstanceTypeName = varInstance.getTypeName();

                    switch (varInstanceTypeName) {
                        case StringType.TYPE_NAME:
                        case LongStringType.TYPE_NAME:
                            objectNode.put(targetVarName, (String) varInstance.getValue());
                            break;
                        case JsonType.TYPE_NAME:
                            objectNode.set(targetVarName, (JsonNode) varInstance.getValue());
                            break;
                        case BooleanType.TYPE_NAME:
                            objectNode.put(targetVarName, (Boolean) varInstance.getValue());
                            break;
                        case ShortType.TYPE_NAME:
                            objectNode.put(targetVarName, (Short) varInstance.getValue());
                            break;
                        case IntegerType.TYPE_NAME:
                            objectNode.put(targetVarName, (Integer) varInstance.getValue());
                            break;
                        case LongType.TYPE_NAME:
                            objectNode.put(targetVarName, (Long) varInstance.getValue());
                            break;
                        case DoubleType.TYPE_NAME:
                            objectNode.put(targetVarName, (Double) varInstance.getValue());
                            break;
                        case DateType.TYPE_NAME:
                            objectNode.put(targetVarName, ((Date) varInstance.getValue()).toInstant().toString());
                            break;
                        case NullType.TYPE_NAME:
                            objectNode.putNull(targetVarName);
                            break;
                        case InstantType.TYPE_NAME:
                        case LocalDateType.TYPE_NAME:
                        case LocalDateTimeType.TYPE_NAME:
                        case JodaDateType.TYPE_NAME:
                        case JodaDateTimeType.TYPE_NAME:
                        case UUIDType.TYPE_NAME:
                            // For all these types it is OK to use toString as their string representation is what we want to have
                            objectNode.put(targetVarName, varInstance.getValue().toString());
                            break;
                        case ByteArrayType.TYPE_NAME:
                            objectNode.put(targetVarName, (byte[]) varInstance.getValue());
                            break;
                        default:
                            if (VariableAggregatorContext.OVERVIEW.equals(context.getState())) {
                                // We can only use the aggregated variable if we are in an overview state
                                Object value = varInstance.getValue();
                                if (value instanceof JsonNode) {
                                    objectNode.set(targetVarName, (JsonNode) value);
                                } else {
                                    throw new FlowableException("Cannot aggregate overview variable: " + varInstance);
                                }
                            } else {
                                throw new FlowableException("Cannot aggregate variable: " + varInstance);
                            }
                    }
                }

            }
        }

        return objectNode;
    }

    @Override
    public Object aggregateMultiVariables(DelegateExecution execution, List instances, VariableAggregatorContext context) {
        ObjectMapper objectMapper = processEngineConfiguration.getObjectMapper();
        ArrayNode arrayNode = objectMapper.createArrayNode();
        for (VariableInstance instance : instances) {
            arrayNode.add((JsonNode) instance.getValue());
        }

        return arrayNode;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy