001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.bpmscript;
018:
019: import java.sql.Timestamp;
020: import java.util.List;
021: import java.util.Map;
022: import java.util.concurrent.ConcurrentHashMap;
023: import java.util.concurrent.atomic.AtomicInteger;
024:
025: public class LockingProcessInstanceManager implements
026: IProcessInstanceManager {
027:
028: private final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
029: .getLog(LockingProcessInstanceManager.class);
030:
031: private IProcessInstanceManager processInstanceManager;
032:
033: private static Map<String, AtomicInteger> locks = new ConcurrentHashMap<String, AtomicInteger>();
034:
035: public LockingProcessInstanceManager(
036: IProcessInstanceManager processInstanceManager) {
037: this .processInstanceManager = processInstanceManager;
038: }
039:
040: public LockingProcessInstanceManager() {
041:
042: }
043:
044: public ExecutorResult doWithProcessInstance(
045: final String processInstanceId,
046: final IProcessInstanceCallback callback) throws Throwable {
047: AtomicInteger lock = null;
048: synchronized (locks) {
049: lock = locks.get(processInstanceId);
050: if (lock == null) {
051: lock = new AtomicInteger(1);
052: locks.put(processInstanceId, lock);
053: } else {
054: lock.set(lock.get() + 1);
055: }
056: }
057: ExecutorResult result = null;
058: synchronized (lock) {
059: try {
060: log.debug("locking " + processInstanceId + " " + lock);
061: result = processInstanceManager.doWithProcessInstance(
062: processInstanceId, callback);
063: } finally {
064: log.debug("unlocking " + processInstanceId);
065: lock.set(lock.get() - 1);
066: if (lock.get() == 0) {
067: locks.remove(processInstanceId);
068: }
069: }
070: }
071: return result;
072: }
073:
074: public String createProcessInstance(String parentProcessInstanceId,
075: String processName, String operation)
076: throws BpmScriptException {
077: return processInstanceManager.createProcessInstance(
078: parentProcessInstanceId, processName, operation);
079: }
080:
081: public List<IProcessInstance> getChildProcessInstances(
082: String processInstanceId) throws BpmScriptException {
083: return processInstanceManager
084: .getChildProcessInstances(processInstanceId);
085: }
086:
087: public IProcessInstance getProcessInstance(String processInstanceId)
088: throws BpmScriptException {
089: return processInstanceManager
090: .getProcessInstance(processInstanceId);
091: }
092:
093: public IPagedResult<IProcessInstance> getProcessInstances(
094: IQuery query) throws BpmScriptException {
095: return processInstanceManager.getProcessInstances(query);
096: }
097:
098: public void setProcessManager(
099: IProcessInstanceManager processInstanceManager) {
100: this .processInstanceManager = processInstanceManager;
101: }
102:
103: public Timestamp getProcessInstanceVersion(String processInstanceId)
104: throws BpmScriptException {
105: return processInstanceManager
106: .getProcessInstanceVersion(processInstanceId);
107: }
108:
109: }
|