1 25 package org.ofbiz.workflow; 26 27 import java.util.Date ; 28 import java.util.List ; 29 import java.util.Locale ; 30 import java.util.Map ; 31 32 import javax.transaction.InvalidTransactionException ; 33 import javax.transaction.SystemException ; 34 import javax.transaction.Transaction ; 35 import javax.transaction.TransactionManager ; 36 37 import org.ofbiz.base.util.Debug; 38 import org.ofbiz.base.util.StringUtil; 39 import org.ofbiz.base.util.UtilDateTime; 40 import org.ofbiz.base.util.UtilMisc; 41 import org.ofbiz.entity.GenericEntityException; 42 import org.ofbiz.entity.GenericValue; 43 import org.ofbiz.entity.transaction.GenericTransactionException; 44 import org.ofbiz.entity.transaction.TransactionFactory; 45 import org.ofbiz.entity.transaction.TransactionUtil; 46 import org.ofbiz.service.GenericRequester; 47 import org.ofbiz.service.GenericResultWaiter; 48 import org.ofbiz.service.GenericServiceException; 49 import org.ofbiz.service.ModelService; 50 import org.ofbiz.service.ServiceDispatcher; 51 import org.ofbiz.service.engine.AbstractEngine; 52 import org.ofbiz.service.job.AbstractJob; 53 import org.ofbiz.service.job.Job; 54 import org.ofbiz.service.job.JobManagerException; 55 56 63 public class WorkflowEngine extends AbstractEngine { 64 65 public static final String module = WorkflowEngine.class.getName(); 66 67 public WorkflowEngine(ServiceDispatcher dispatcher) { 68 super(dispatcher); 69 } 70 71 74 public Map runSync(String localName, ModelService modelService, Map context) throws GenericServiceException { 75 GenericResultWaiter waiter = new GenericResultWaiter(); 76 runAsync(localName, modelService, context, waiter, false); 77 return waiter.waitForResult(); 78 } 79 80 83 public void runSyncIgnore(String localName, ModelService modelService, Map context) throws GenericServiceException { 84 runAsync(localName, modelService, context, null, false); 85 } 86 87 90 public void runAsync(String localName, ModelService modelService, Map context, boolean persist) throws GenericServiceException { 91 runAsync(localName, modelService, context, null, persist); 92 } 93 94 97 public void runAsync(String localName, ModelService modelService, Map context, GenericRequester requester, boolean persist) throws GenericServiceException { 98 TransactionManager tm = TransactionFactory.getTransactionManager(); 100 if (tm == null) { 101 throw new GenericServiceException("Cannot get the transaction manager; cannot run persisted services."); 102 } 103 104 Transaction parentTrans = null; 105 boolean beganTransaction = false; 106 try { 107 try { 108 parentTrans = tm.suspend(); 109 beganTransaction = TransactionUtil.begin(); 110 } catch (SystemException se) { 112 Debug.logError(se, "Cannot suspend transaction: " + se.getMessage(), module); 113 } catch (GenericTransactionException e) { 114 Debug.logError(e, "Cannot begin nested transaction: " + e.getMessage(), module); 115 } 116 117 WfRequester req = null; 119 try { 120 req = WfFactory.getWfRequester(); 121 } catch (WfException e) { 122 try { 123 TransactionUtil.rollback(beganTransaction, "Error getting Workflow Requester", e); 124 } catch (GenericTransactionException gte) { 125 Debug.logError(gte, "Unable to rollback nested exception.", module); 126 } 127 throw new GenericServiceException(e.getMessage(), e); 128 } 129 130 String location = this.getLocation(modelService); 132 String invoke = modelService.invoke; 133 String packageId = this.getSplitPosition(location, 0); 134 String packageVersion = this.getSplitPosition(location, 1); 135 String processId = this.getSplitPosition(invoke, 0); 136 String processVersion = this.getSplitPosition(invoke, 1); 137 138 WfProcessMgr mgr = null; 140 try { 141 mgr = WfFactory.getWfProcessMgr(dispatcher.getDelegator(), packageId, packageVersion, processId, processVersion); 142 } catch (WfException e) { 143 String errMsg = "Process manager error"; 144 Debug.logError(e, errMsg, module); 145 try { 146 TransactionUtil.rollback(beganTransaction, errMsg, e); 147 } catch (GenericTransactionException gte) { 148 Debug.logError(gte, "Unable to rollback nested exception.", module); 149 } 150 throw new GenericServiceException(e.getMessage(), e); 151 } catch (Exception e) { 152 Debug.logError(e, "Un-handled process manager error", module); 153 throw new GenericServiceException(e.getMessage(), e); 154 } 155 156 WfProcess process = null; 158 try { 159 process = mgr.createProcess(req); 160 } catch (NotEnabled ne) { 161 try { 162 TransactionUtil.rollback(beganTransaction, "Error in create workflow process: Not Enabled", ne); 163 } catch (GenericTransactionException gte) { 164 Debug.logError(gte, "Unable to rollback nested exception.", module); 165 } 166 throw new GenericServiceException(ne.getMessage(), ne); 167 } catch (InvalidRequester ir) { 168 try { 169 TransactionUtil.rollback(beganTransaction, "Error in create workflow process: Invalid Requester", ir); 170 } catch (GenericTransactionException gte) { 171 Debug.logError(gte, "Unable to rollback nested exception.", module); 172 } 173 throw new GenericServiceException(ir.getMessage(), ir); 174 } catch (RequesterRequired rr) { 175 try { 176 TransactionUtil.rollback(beganTransaction, "Error in create workflow process: Requester Required", rr); 177 } catch (GenericTransactionException gte) { 178 Debug.logError(gte, "Unable to rollback nested exception.", module); 179 } 180 throw new GenericServiceException(rr.getMessage(), rr); 181 } catch (WfException wfe) { 182 try { 183 TransactionUtil.rollback(beganTransaction, "Error in create workflow process: general workflow error error", wfe); 184 } catch (GenericTransactionException gte) { 185 Debug.logError(gte, "Unable to rollback nested exception.", module); 186 } 187 throw new GenericServiceException(wfe.getMessage(), wfe); 188 } catch (Exception e) { 189 Debug.logError(e, "Un-handled process exception", module); 190 throw new GenericServiceException(e.getMessage(), e); 191 } 192 193 GenericValue userLogin = null; 195 if (context.containsKey("userLogin")) { 196 userLogin = (GenericValue) context.remove("userLogin"); 197 try { 198 Map fields = UtilMisc.toMap("partyId", userLogin.getString("partyId"), 199 "roleTypeId", "WF_OWNER", "workEffortId", process.runtimeKey(), 200 "fromDate", UtilDateTime.nowTimestamp()); 201 202 try { 203 GenericValue wepa = dispatcher.getDelegator().makeValue("WorkEffortPartyAssignment", fields); 204 dispatcher.getDelegator().create(wepa); 205 } catch (GenericEntityException e) { 206 String errMsg = "Cannot set ownership of workflow"; 207 try { 208 TransactionUtil.rollback(beganTransaction, errMsg, e); 209 } catch (GenericTransactionException gte) { 210 Debug.logError(gte, "Unable to rollback nested exception.", module); 211 } 212 throw new GenericServiceException(errMsg, e); 213 } 214 } catch (WfException we) { 215 String errMsg = "Cannot get the workflow process runtime key"; 216 try { 217 TransactionUtil.rollback(beganTransaction, errMsg, we); 218 } catch (GenericTransactionException gte) { 219 Debug.logError(gte, "Unable to rollback nested exception.", module); 220 } 221 throw new GenericServiceException(errMsg); 222 } 223 } 224 225 Locale locale = (Locale ) context.remove("locale"); 227 228 String startActivityId = (String ) context.remove("startWithActivityId"); 230 231 try { 233 req.registerProcess(process, context, requester); 234 if (userLogin != null) { 235 Map pContext = process.processContext(); 236 pContext.put("workflowOwnerId", userLogin.getString("userLoginId")); 237 process.setProcessContext(pContext); 238 } 239 } catch (WfException wfe) { 240 try { 241 TransactionUtil.rollback(beganTransaction, wfe.getMessage(), wfe); 242 } catch (GenericTransactionException gte) { 243 Debug.logError(gte, "Unable to rollback nested exception.", module); 244 } 245 throw new GenericServiceException(wfe.getMessage(), wfe); 246 } 247 248 if (locale != null) { 250 try { 251 Map pContext = process.processContext(); 252 pContext.put("initialLocale", locale); 253 process.setProcessContext(pContext); 254 } catch (WfException wfe) { 255 try { 256 TransactionUtil.rollback(beganTransaction, wfe.getMessage(), wfe); 257 } catch (GenericTransactionException gte) { 258 Debug.logError(gte, "Unable to rollback nested exception.", module); 259 } 260 throw new GenericServiceException(wfe.getMessage(), wfe); 261 } 262 } 263 264 try { 266 Job job = new WorkflowRunner(process, requester, startActivityId); 267 if (Debug.verboseOn()) Debug.logVerbose("Created WorkflowRunner: " + job, module); 268 dispatcher.getJobManager().runJob(job); 269 } catch (JobManagerException je) { 270 try { 271 TransactionUtil.rollback(beganTransaction, je.getMessage(), je); 272 } catch (GenericTransactionException gte) { 273 Debug.logError(gte, "Unable to rollback nested exception.", module); 274 } 275 throw new GenericServiceException(je.getMessage(), je); 276 } 277 278 try { 279 TransactionUtil.commit(beganTransaction); 280 } catch (GenericTransactionException e) { 281 Debug.logError(e, "Cannot commit nested transaction: " + e.getMessage(), module); 282 } 283 } finally { 284 if (parentTrans != null) { 286 try { 287 tm.resume(parentTrans); 288 } catch (InvalidTransactionException ite) { 290 throw new GenericServiceException("Cannot resume transaction", ite); 291 } catch (SystemException se) { 292 throw new GenericServiceException("Unexpected transaction error", se); 293 } 294 } 295 } 296 } 297 298 private String getSplitPosition(String splitString, int position) { 299 if (splitString.indexOf("::") == -1) { 300 if (position == 0) 301 return splitString; 302 if (position == 1) 303 return null; 304 } 305 List splitList = StringUtil.split(splitString, "::"); 306 return (String ) splitList.get(position); 307 } 308 } 309 310 311 class WorkflowRunner extends AbstractJob { 312 313 GenericRequester requester; 314 WfProcess process; 315 String startActivityId; 316 317 WorkflowRunner(WfProcess process, GenericRequester requester, String startActivityId) { 318 super(process.toString() + "." + System.currentTimeMillis(), process.toString()); 319 this.process = process; 320 this.requester = requester; 321 this.startActivityId = startActivityId; 322 runtime = new Date ().getTime(); 323 } 324 325 protected void finish() { 326 runtime = -1; 327 } 328 329 public void exec() { 330 try { 331 if (startActivityId != null) 332 process.start(startActivityId); 333 else 334 process.start(); 335 } catch (Exception e) { 336 Debug.logError(e, module); 337 if (requester != null) 338 requester.receiveResult(null); 339 } 340 finish(); 341 } 342 } 343 344 | Popular Tags |