📄 abstractworkitemstore.java
字号:
/* * Copyright (c) 2005, John Mettraux, OpenWFE.org * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * . Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * . Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * . Neither the name of the "OpenWFE" nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $Id: AbstractWorkItemStore.java,v 1.42 2005/07/07 08:57:14 jmettraux Exp $ *///// AbstractWorkItemStore.java//// jmettraux@openwfe.org//// generated with // jtmpl 1.0.04 20.11.2001 John Mettraux (jmettraux@openwfe.org)//package openwfe.org.worklist.impl;import javax.security.auth.Subject;import openwfe.org.Cache;import openwfe.org.MapUtils;import openwfe.org.Application;import openwfe.org.AbstractService;import openwfe.org.ServiceException;import openwfe.org.ApplicationContext;import openwfe.org.auth.BasicPrincipal;import openwfe.org.time.Time;import openwfe.org.engine.workitem.CancelItem;import openwfe.org.engine.workitem.InFlowWorkItem;import openwfe.org.engine.workitem.WorkItemCoder;import openwfe.org.engine.workitem.WorkItemCoderLoader;import openwfe.org.engine.dispatch.DispatchingException;import openwfe.org.engine.expressions.FlowExpressionId;import openwfe.org.engine.participants.Participant;import openwfe.org.engine.participants.ParticipantMap;import openwfe.org.worklist.Header;import openwfe.org.worklist.CachedHeaders;import openwfe.org.worklist.HeaderFactory;import openwfe.org.worklist.WorkListException;import openwfe.org.worklist.store.Lock;import openwfe.org.worklist.store.WorkItemStore;import openwfe.org.worklist.store.StoreException;import openwfe.org.worklist.auth.StorePermission;/** * A lot of things that were developed as 'FileWorkItemStore' can be found * here, these functionalities will now be shared by other WorkItemStore * implementations, most notably the XdbcWorkItemStore. * * <p><font size=2>CVS Info : * <br>$Author: jmettraux $ * <br>$Date: 2005/07/07 08:57:14 $ * <br>$Id: AbstractWorkItemStore.java,v 1.42 2005/07/07 08:57:14 jmettraux Exp $ </font> * * @author jmettraux@openwfe.org */public abstract class AbstractWorkItemStore extends AbstractService implements WorkItemStore{ private final static org.apache.log4j.Logger log = org.apache.log4j.Logger .getLogger(AbstractWorkItemStore.class.getName()); // // CONSTANTS (definitions) /** * The parameter 'cacheSize' defines how many workitems should be cached * in memory. The bigger the size the faster workitem retrieval may * be. */ public final static String P_CACHE_SIZE = "cacheSize"; /** * Constant for the parameter named 'headerFactory' : a header is a * summary of a workitem for display in a selection list, a header * factory is a piece of code that creates a header for a workitem. Use * this parameter to indicate the workitem store which header factory * (an OpenWFE like an other) it should use. */ public final static String P_HEADER_FACTORY = "headerFactory"; /** * Constant for the time parameter named 'lockTimeout' : how many * time an idle lock should be maintained on a workitem ? */ public final static String P_LOCK_TIMEOUT = "lockTimeout"; /** * Constant for the time parameter named 'unlockFrequency' : how * frequently should the workitem store check for workitem whose * locks did time out ? */ public final static String P_UNLOCK_FREQUENCY = "unlockFrequency"; /** * Constant for the time parameter named 'maxStorageThreads' : after how * many concurrent storage thread should storage be performed sequentially * (lower response time) to avoid a JVM crash ? */ public final static String P_MAX_STORAGE_THREADS = "maxStorageThreads"; /** * The parameter 'workItemCoder' should point to the name of a workitem * coder as defined by the 'workItemCoderLoader' service. */ public final static String P_WORKITEM_CODER = "workItemCoder"; /** * If the parameter 'default' for this store is set to 'true' or 'yes', * the store will be a default store. */ public final static String P_DEFAULT = "default"; /** * Set to 15m */ public final static String DEFAULT_LOCK_TIMEOUT = "15m"; /** * Set to 7m */ public final static String DEFAULT_UNLOCK_FREQUENCY = "7m"; /** * Set to 100 (workitems) */ public final static int DEFAULT_CACHE_SIZE = 100; /** * Set to 100 (concurrent storage threads) */ public final static int DEFAULT_MAX_STORAGE_THREADS = 100; // // FIELDS private Cache cache = null; private HeaderFactory headerFactoryService = null; private CachedHeaders cachedHeaders = null; // no headers determined for the moment private String[] acceptedParticipants = null; private java.util.Map lockMap = new java.util.HashMap(); private long lockTimeout = 0; private UnlockDaemon unlockDaemon = null; private int maxStorageThreads = 30; private int activeStorageThreads = 0; private String workItemCoderName = null; // // CONSTRUCTORS public void init (final String serviceName, final ApplicationContext context, final java.util.Map serviceParams) throws ServiceException { super.init(serviceName, context, serviceParams); // // init cache final int cacheSize = MapUtils.getAsInt (getParams(), P_CACHE_SIZE, DEFAULT_CACHE_SIZE); this.cache = new Cache(cacheSize); log.info("init() cache size set to "+this.cache.size()); // // determine max storage threads this.maxStorageThreads = MapUtils.getAsInt (getParams(), P_MAX_STORAGE_THREADS, DEFAULT_MAX_STORAGE_THREADS); log.info("init() max storage threads set to "+this.maxStorageThreads); // // determine workItemCoder this.workItemCoderName = MapUtils.getAsString (getParams(), P_WORKITEM_CODER); log.info("init() workItemCoder set to '"+this.workItemCoderName+"'"); // // init accepted participants initAcceptedParticipants(serviceParams); // // init UnlockDaemon initUnlockDaemon(); // // display OpenWFE version in logs log.info ("OpenWFE version : "+ openwfe.org.engine.Definitions.OPENWFE_VERSION); } // // GETTERS and SETTERS // // METHODS /** * Loads the workitem coder */ public WorkItemCoder getCoder () { final WorkItemCoderLoader coderLoader = openwfe.org.engine.Definitions .getWorkItemCoderLoader(getContext()); if (this.workItemCoderName != null) return coderLoader.getCoder(this.workItemCoderName); return coderLoader.getDefaultCoder(); } // // METHODS from WorkItemStore /** * Returns true if the given workitem is locked. */ public boolean isLocked (final FlowExpressionId workitemId) { return this.lockMap.keySet().contains(workitemId); } /** * Returns the lock set on the workitem, will return null if no lock is set * on the workitem. */ public Lock getLock (final FlowExpressionId workitemId) { return (Lock)this.lockMap.get(workitemId); } public boolean isDefaultStore () { return MapUtils.getAsBoolean(getParams(), P_DEFAULT, false); } /** * Adds the given workitem to this expression store. */ public void store (final InFlowWorkItem wi) throws StoreException { log.debug("store() in '"+getName()+"' for "+wi.getLastExpressionId()); // // cache workitem this.cache.put(wi.getLastExpressionId(), wi); //logDebugCache(); // // uncache headers this.cachedHeaders = null; // // 'physical' storage if (this.activeStorageThreads >= this.maxStorageThreads) // // unthreaded storage { storeWorkItem(wi); } else // // threaded storage { this.activeStorageThreads++; log.debug ("store() this.activeStorageThreads = "+ this.activeStorageThreads); (new Thread() { public void run () { final FlowExpressionId fei = wi.getLastExpressionId(); this.setName ("storage thread for "+fei.getWorkflowInstanceId()+ " exp "+fei.getExpressionId()); try { AbstractWorkItemStore.this.storeWorkItem(wi); } catch (final Throwable t) { //log.warn // ("store() failed to store workitem "+ // wi.getLastExpressionId()+ // " : "+t); log.error ("store() failed to store workitem "+ wi.getLastExpressionId(), t); } AbstractWorkItemStore.this.activeStorageThreads--; } }).start(); } } public void cancel (final CancelItem ci) throws StoreException { final FlowExpressionId id = ci.getLastExpressionId(); this.cache.remove(id); this.cachedHeaders = null; removeWorkItem(id); } /** * Updates a workitem in the store */ public void save (final Subject s, final InFlowWorkItem wi) throws StoreException { java.security.AccessController.checkPermission (StorePermission.newStorePermission(getName(), "write")); synchronized (this) // check impact on perf { final FlowExpressionId id = wi.getLastExpressionId(); // // is the item locked ? Lock lock = (Lock)this.lockMap.get(id); if (lock != null) { Subject locker = lock.getLocker(); // // is the subject the locker ? if ( ! s.equals(locker)) { throw new StoreException ("WorkItem '"+id+ "' is already locked by someone else."); } } else { //log.debug("Saving a workitem that was not locked before..."); throw new StoreException ("Cannot save workitem : you have no lock on it."); } // // proceed wi.touch(); // update wi.lastModified store(wi); // // notify : the headers for this participant // are not up to date anymore this.cachedHeaders = null; // leave lock untouched } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -