| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.ofbiz.workflow; |
| |
| import java.io.IOException; |
| import java.sql.Timestamp; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.ofbiz.base.util.Debug; |
| import org.ofbiz.base.util.GeneralException; |
| import org.ofbiz.base.util.ObjectType; |
| import org.ofbiz.base.util.UtilGenerics; |
| import org.ofbiz.base.util.UtilMisc; |
| import org.ofbiz.entity.Delegator; |
| import org.ofbiz.entity.GenericEntityException; |
| import org.ofbiz.entity.GenericValue; |
| import org.ofbiz.entity.serialize.SerializeException; |
| import org.ofbiz.entity.serialize.XmlSerializer; |
| import org.ofbiz.service.DispatchContext; |
| import org.ofbiz.service.GenericServiceException; |
| import org.ofbiz.service.ModelService; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * Workflow Application Services - 'Services' and 'Workers' for interaction with Workflow Application API |
| */ |
| public class WfApplicationServices { |
| |
| // ------------------------------------------------------------------- |
| // Appication 'Service' Methods |
| // ------------------------------------------------------------------- |
| |
| public static final String module = WfApplicationServices.class.getName(); |
| |
| /** |
| * Activate an application by inserting expected arguments in |
| * the ApplicationSandbox table. |
| * |
| * Note: Assume that the activity (workEffort) has only one performer as |
| * defined in XPDL specification, this means that there is only one |
| * partyAssigment w/ CAL_ACEPTED state. |
| * @param ctx Service dispatch Context |
| * @param context Actual parameters |
| * @throws GenericServiceException |
| * @return Empty result |
| */ |
| public static Map<String, Object> activateApplication(DispatchContext ctx, Map<String, Object> context) { |
| final String workEffortId = (String) context.get("workEffortId"); |
| final Map<String, Object> result = new HashMap<String, Object>(); |
| |
| try { |
| final GenericValue weAssigment = getWorkEffortPartyAssigment(ctx.getDelegator(), workEffortId); |
| |
| final String partyId = (String) weAssigment.get("partyId"); |
| final String roleTypeId = (String) weAssigment.get("roleTypeId"); |
| final Timestamp fromDate = (Timestamp) weAssigment.get("fromDate"); |
| result.put("applicationId", insertAppSandbox(ctx.getDelegator(), workEffortId, partyId, |
| roleTypeId, fromDate, context)); |
| result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); |
| } catch (GenericServiceException we) { |
| we.printStackTrace(); |
| result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); |
| result.put(ModelService.ERROR_MESSAGE, we.getMessage()); |
| } |
| |
| return result; |
| } |
| |
| public static Map<String, Object> getApplicationContext(DispatchContext ctx, Map<String, Object> context) throws GenericServiceException { |
| final Delegator delegator = ctx.getDelegator(); |
| final Map<String, Object> result = new HashMap<String, Object>(); |
| try { |
| result.put("applicationContext", |
| getRunTimeContext(delegator, getRuntimeData(delegator, (String) context.get("applicationId")))); |
| result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_SUCCESS); |
| } catch (GenericServiceException we) { |
| we.printStackTrace(); |
| result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); |
| result.put(ModelService.ERROR_MESSAGE, we.getMessage()); |
| } |
| return result; |
| } |
| |
| public static Map<String, Object> completeApplication(DispatchContext ctx, Map<String, Object> context) throws GenericServiceException { |
| final Delegator delegator = ctx.getDelegator(); |
| final String applicationId = (String) context.get("applicationId"); |
| final Map<String, Object> result = new HashMap<String, Object>(); |
| |
| GenericValue application = getApplicationSandbox(delegator, applicationId); |
| GenericValue runTimeData = getRuntimeData(delegator, applicationId); |
| Map<String, Object> runTimeContext = getRunTimeContext(delegator, runTimeData); |
| Map<String, Object> contextSignature = new HashMap<String, Object>(); |
| Map<String, Object> resultSignature = new HashMap<String, Object>(); |
| Map<String, Object> resultContext = new HashMap<String, Object>(); |
| Map<String, Object> runContext = new HashMap<String, Object>(context); |
| |
| try { |
| // copy all OUT & INOUT formal parameters |
| getApplicationSignatures(delegator, application, contextSignature, resultSignature); |
| for (String name : resultSignature.keySet()) { |
| Object value = null; |
| if (runTimeContext.containsKey(name) |
| && contextSignature.containsKey(name) |
| && resultSignature.containsKey(name)) |
| value = runTimeContext.get(name); |
| if (UtilGenerics.checkMap(context.get("result")).containsKey(name)) { |
| value = UtilGenerics.checkMap(context.get("result")).get(name); |
| } |
| if (value != null) { |
| resultContext.put(name, |
| ObjectType.simpleTypeConvert(value, (String) resultSignature.get(name), null, null)); |
| } |
| } |
| runTimeContext.putAll(resultContext); |
| // fin de agregar |
| if (Debug.verboseOn()) { |
| Debug.logVerbose("Completing Application: " + applicationId, module); |
| Debug.logVerbose(" Result Signature: " + resultSignature.toString(), module); |
| Debug.logVerbose(" Result Values: " + resultContext.toString(), module); |
| |
| } |
| |
| setRunTimeContext(runTimeData, runTimeContext); |
| |
| runContext.remove("applicationId"); |
| |
| final String workEffortId = (String) runTimeContext.get("workEffortId"); |
| final Timestamp fromDate = (Timestamp) application.get("fromDate"); |
| final String partyId = (String) application.get("partyId"); |
| final String roleTypeId = (String) application.get("roleTypeId"); |
| |
| runContext.put("workEffortId", workEffortId); |
| runContext.put("fromDate", fromDate); |
| runContext.put("partyId", partyId); |
| runContext.put("roleTypeId", roleTypeId); |
| runContext.put("result", resultContext); |
| |
| result.putAll(ctx.getDispatcher().runSync("wfCompleteAssignment", runContext)); |
| } catch (GenericEntityException we) { |
| we.printStackTrace(); |
| result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); |
| result.put(ModelService.ERROR_MESSAGE, we.getMessage()); |
| } catch (GenericServiceException we) { |
| we.printStackTrace(); |
| result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); |
| result.put(ModelService.ERROR_MESSAGE, we.getMessage()); |
| } catch (GeneralException ge) { |
| ge.printStackTrace(); |
| result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR); |
| result.put(ModelService.ERROR_MESSAGE, ge.getMessage()); |
| } |
| return result; |
| } |
| |
| private static String insertAppSandbox(Delegator delegator, String workEffortId, String partyId, |
| String roleTypeId, Timestamp fromDate, Map<String, Object> context) throws GenericServiceException { |
| String dataId = null; |
| String applicationId = Long.toString((new Date().getTime())); |
| |
| try { |
| dataId = delegator.getNextSeqId("RuntimeData"); |
| GenericValue runtimeData = delegator.makeValue("RuntimeData", UtilMisc.toMap("runtimeDataId", dataId)); |
| runtimeData.set("runtimeInfo", XmlSerializer.serialize(context)); |
| delegator.create(runtimeData); |
| } catch (GenericEntityException ee) { |
| throw new GenericServiceException(ee.getMessage(), ee); |
| } catch (SerializeException se) { |
| throw new GenericServiceException(se.getMessage(), se); |
| } catch (IOException ioe) { |
| throw new GenericServiceException(ioe.getMessage(), ioe); |
| } |
| Map<String, Object> aFields = UtilMisc.toMap("applicationId", applicationId, "workEffortId", workEffortId, |
| "partyId", partyId, "roleTypeId", roleTypeId, "fromDate", fromDate, "runtimeDataId", dataId); |
| |
| GenericValue appV = null; |
| try { |
| appV = delegator.makeValue("ApplicationSandbox", aFields); |
| delegator.create(appV); |
| } catch (GenericEntityException e) { |
| throw new GenericServiceException(e.getMessage(), e); |
| } |
| return applicationId; |
| } |
| |
| private static GenericValue getApplicationSandbox(Delegator delegator, String applicationId) |
| throws GenericServiceException { |
| try { |
| GenericValue application = |
| delegator.findByPrimaryKey("ApplicationSandbox", UtilMisc.toMap("applicationId", applicationId)); |
| return application; |
| } catch (GenericEntityException ee) { |
| throw new GenericServiceException(ee.getMessage(), ee); |
| } |
| } |
| |
| private static Map<String, Object> getRunTimeContext(Delegator delegator, GenericValue runTimeData) |
| throws GenericServiceException { |
| try { |
| return UtilGenerics.checkMap(XmlSerializer.deserialize((String) runTimeData.get("runtimeInfo"), delegator)); |
| } catch (SerializeException se) { |
| throw new GenericServiceException(se.getMessage(), se); |
| } catch (ParserConfigurationException pe) { |
| throw new GenericServiceException(pe.getMessage(), pe); |
| } catch (SAXException se) { |
| throw new GenericServiceException(se.getMessage(), se); |
| } catch (IOException ioe) { |
| throw new GenericServiceException(ioe.getMessage(), ioe); |
| } |
| } |
| |
| private static void setRunTimeContext(GenericValue runTimeData, Map<String, Object> context) throws GenericServiceException { |
| try { |
| runTimeData.set("runtimeInfo", XmlSerializer.serialize(context)); |
| runTimeData.store(); |
| } catch (GenericEntityException ee) { |
| throw new GenericServiceException(ee.getMessage(), ee); |
| } catch (SerializeException se) { |
| throw new GenericServiceException(se.getMessage(), se); |
| } catch (IOException ioe) { |
| throw new GenericServiceException(ioe.getMessage(), ioe); |
| } |
| } |
| |
| private static GenericValue getRuntimeData(Delegator delegator, String applicationId) |
| throws GenericServiceException { |
| try { |
| GenericValue application = |
| delegator.findByPrimaryKey("ApplicationSandbox", UtilMisc.toMap("applicationId", applicationId)); |
| return application.getRelatedOne("RuntimeData"); |
| } catch (GenericEntityException ee) { |
| throw new GenericServiceException(ee.getMessage(), ee); |
| } |
| } |
| |
| private static void getApplicationSignatures(Delegator delegator, GenericValue application, |
| Map<String, Object> contextSignature, Map<String, Object> resultSignature) throws GenericEntityException { |
| Map<String, Object> expresions = null; |
| // look for the 1st application. |
| final GenericValue workEffort = |
| delegator.findByPrimaryKey("WorkEffort", UtilMisc.toMap("workEffortId", application.get("workEffortId"))); |
| String packageId = (String) workEffort.get("workflowPackageId"); |
| String packageVersion = (String) workEffort.get("workflowPackageVersion"); |
| String processId = (String) workEffort.get("workflowProcessId"); |
| String processVersion = (String) workEffort.get("workflowProcessVersion"); |
| String activityId = (String) workEffort.get("workflowActivityId"); |
| |
| expresions = new HashMap<String, Object>(); |
| expresions.putAll(UtilMisc.toMap("packageId", packageId)); |
| expresions.putAll(UtilMisc.toMap("packageVersion", packageVersion)); |
| expresions.putAll(UtilMisc.toMap("processId", processId)); |
| expresions.putAll(UtilMisc.toMap("processVersion", processVersion)); |
| expresions.putAll(UtilMisc.toMap("activityId", activityId)); |
| |
| final List<GenericValue> wfActivityTools = delegator.findByAnd("WorkflowActivityTool", expresions); |
| final GenericValue wfActivityTool = (GenericValue) wfActivityTools.toArray()[0]; |
| |
| packageId = (String) wfActivityTool.get("packageId"); |
| packageVersion = (String) wfActivityTool.get("packageVersion"); |
| processId = (String) wfActivityTool.get("processId"); |
| processVersion = (String) wfActivityTool.get("processVersion"); |
| final String applicationId = (String) wfActivityTool.get("toolId"); |
| |
| expresions = new HashMap<String, Object>(); |
| expresions.putAll(UtilMisc.toMap("packageId", packageId)); |
| expresions.putAll(UtilMisc.toMap("packageVersion", packageVersion)); |
| expresions.putAll(UtilMisc.toMap("processId", processId)); |
| expresions.putAll(UtilMisc.toMap("processVersion", processVersion)); |
| expresions.putAll(UtilMisc.toMap("applicationId", applicationId)); |
| |
| final List<GenericValue> params = delegator.findByAnd("WorkflowFormalParam", expresions); |
| |
| for (GenericValue param : params) { |
| String name = param.getString("formalParamId"); |
| String mode = param.getString("modeEnumId"); |
| String type = param.getString("dataTypeEnumId"); |
| if (mode.equals("WPM_IN") || mode.equals("WPM_INOUT")) |
| contextSignature.put(name, WfUtil.getJavaType(type)); |
| else if (mode.equals("WPM_OUT") || mode.equals("WPM_INOUT")) |
| resultSignature.put(name, WfUtil.getJavaType(type)); |
| } |
| } |
| |
| private static GenericValue getWorkEffortPartyAssigment(Delegator delegator, String workEffortId) |
| throws GenericServiceException { |
| Map<String, Object> expresions = new HashMap<String, Object>(); |
| expresions.putAll(UtilMisc.toMap("workEffortId", workEffortId)); |
| expresions.putAll(UtilMisc.toMap("statusId", "CAL_ACCEPTED")); |
| List<String> orderBy = UtilMisc.toList("-fromDate"); |
| |
| try { |
| final List<GenericValue> assigments = delegator.findByAnd("WorkEffortPartyAssignment", expresions, orderBy); |
| if (assigments.isEmpty()) { |
| Debug.logError("No accepted activities found for the workEffortId=" + workEffortId, module); |
| throw new GenericServiceException("Can not find WorkEffortPartyAssignment for the Workflow service. WorkEffortId=" + workEffortId); |
| } |
| if (assigments.size() != 1) |
| Debug.logWarning("More than one accepted activities found for the workEffortId=" + workEffortId, module); |
| return assigments.iterator().next(); |
| } catch (GenericEntityException ee) { |
| throw new GenericServiceException(ee.getMessage(), ee); |
| } |
| } |
| } |