001: package org.enhydra.shark;
002:
003: import java.util.ArrayList;
004: import java.util.HashMap;
005: import java.util.Iterator;
006: import java.util.List;
007: import java.util.Map;
008:
009: import org.enhydra.shark.api.client.wfmc.wapi.WMSessionHandle;
010: import org.enhydra.shark.api.common.SharkConstants;
011: import org.enhydra.shark.api.internal.instancepersistence.ActivityPersistenceObject;
012: import org.enhydra.shark.api.internal.working.WfActivityInternal;
013: import org.enhydra.shark.api.internal.working.WfProcessInternal;
014:
015: /**
016: * Cache for storing process's activities.
017: *
018: * @author Sasa Bojanic
019: */
020: public class ActivityCache {
021: /**
022: * Activity cache.
023: */
024: protected Map cache = new HashMap();
025:
026: protected WfProcessInternal proc;
027:
028: protected boolean openLoaded = false;
029:
030: protected boolean allLoaded = false;
031:
032: /**
033: * Creates activity cache for the process instance.
034: */
035: public ActivityCache(WfProcessInternal proc,
036: boolean newProcessInstance) {
037: this .proc = proc;
038: if (newProcessInstance) {
039: openLoaded = true;
040: allLoaded = true;
041: }
042: }
043:
044: /**
045: * Adds activity to the cache.
046: *
047: * @param actId Activity id.
048: * @param act WfActivityInternal object to be added to the cache.
049: */
050: public synchronized void add(String actId, WfActivityInternal act) {
051: cache.put(actId, act);
052: }
053:
054: /**
055: * Removes activity from the cache.
056: *
057: * @param actId Activity id.
058: */
059: public synchronized WfActivityInternal remove(String actId) {
060: return (WfActivityInternal) cache.remove(actId);
061: }
062:
063: /**
064: * Returns specific activity from the cache.
065: *
066: * @param actId Activity id.
067: * @return Activity from the cache for the given Id if exists, otherwise null.
068: */
069: protected WfActivityInternal get(String actId) {
070: return (WfActivityInternal) cache.get(actId);
071: }
072:
073: /**
074: * Returns how many activities are currently in the cache.
075: */
076: public int howManyEntries() {
077: return cache.size();
078: }
079:
080: /**
081: * Removes all the activities from the cache.
082: */
083: public synchronized void clear() {
084: allLoaded = false;
085: openLoaded = false;
086: cache.clear();
087: }
088:
089: /**
090: * Removes only the open activities from the cache.
091: */
092: public synchronized void clearOpen(WMSessionHandle shandle)
093: throws Exception {
094: Iterator it = cache.values().iterator();
095: while (it.hasNext()) {
096: WfActivityInternal act = (WfActivityInternal) it.next();
097: if (act.state(shandle).startsWith(
098: SharkConstants.STATEPREFIX_OPEN)) {
099: it.remove();
100: }
101:
102: }
103: }
104:
105: /**
106: * Returns all the activities for the process. If there was no query to DB in order to
107: * get all the activities (and this is not a cache for the new process instance), the
108: * query will be performed, and cache will be filled before returning the result.
109: */
110: public List getAll(WMSessionHandle shandle) throws Exception {
111: if (!allLoaded) {
112: loadAll(shandle);
113: }
114: return new ArrayList(cache.values());
115: }
116:
117: /**
118: * Returns all the open activities for the process. If there was no query to DB in
119: * order to get all the open activities (and this is not a cache for the new process
120: * instance), the query will be performed, and cache will be filled before returning
121: * the result.
122: */
123: public List getOpen(WMSessionHandle shandle) throws Exception {
124: if (!openLoaded) {
125: loadOpen(shandle);
126: }
127: List ret = new ArrayList();
128: Iterator it = cache.values().iterator();
129: while (it.hasNext()) {
130: WfActivityInternal act = (WfActivityInternal) it.next();
131: if (act.state(shandle).startsWith(
132: SharkConstants.STATEPREFIX_OPEN)) {
133: ret.add(act);
134: }
135: }
136: return ret;
137: }
138:
139: /**
140: * Returns the activity for the given Id. If there is no such activity in the cache,
141: * there will be a query on DB that will fill the cache with the given activity if it
142: * exists.
143: */
144: public WfActivityInternal getAny(WMSessionHandle shandle,
145: String procId, String actId) throws Exception {
146: WfActivityInternal act = get(actId);
147: if (act == null && !allLoaded) {
148: loadAny(shandle, procId, actId);
149: act = get(actId);
150: }
151: return act;
152: }
153:
154: /**
155: * Returns the open activity for the given Id. If there is no such activity in the
156: * cache, there will be a query on DB that will fill the cache with all open
157: * activities.
158: */
159: public WfActivityInternal getOpen(WMSessionHandle shandle,
160: String actId) throws Exception {
161: WfActivityInternal act = get(actId);
162: if (act == null && !openLoaded) {
163: loadOpen(shandle);
164: act = get(actId);
165: }
166: if (act != null
167: && !act.state(shandle).startsWith(
168: SharkConstants.STATEPREFIX_OPEN)) {
169: act = null;
170: }
171: return act;
172: }
173:
174: /**
175: * Loads all the activities for the process from DB into the cache.
176: */
177: public synchronized void loadAll(WMSessionHandle shandle)
178: throws Exception {
179: if (allLoaded) {
180: return;
181: }
182:
183: SharkEngineManager sharkEngineManager = SharkEngineManager
184: .getInstance();
185: List l = sharkEngineManager.getInstancePersistenceManager()
186: .getAllActivitiesForProcess(shandle, proc.key(shandle));
187: for (int i = 0; i < l.size(); i++) {
188: ActivityPersistenceObject po = (ActivityPersistenceObject) l
189: .get(i);
190: WfActivityInternal act = get(po.getId());
191: if (act == null) {
192: act = sharkEngineManager.getObjectFactory()
193: .createActivity(po, proc);
194: add(po.getId(), act);
195: }
196: }
197:
198: allLoaded = true;
199: openLoaded = true;
200: }
201:
202: /**
203: * Loads all the open activities for the process from DB into the cache.
204: */
205: public synchronized void loadOpen(WMSessionHandle shandle)
206: throws Exception {
207: if (openLoaded) {
208: return;
209: }
210:
211: SharkEngineManager sharkEngineManager = SharkEngineManager
212: .getInstance();
213: List l = sharkEngineManager.getInstancePersistenceManager()
214: .getAllActiveActivitiesForProcess(shandle,
215: proc.key(shandle));
216: for (int i = 0; i < l.size(); i++) {
217: ActivityPersistenceObject po = (ActivityPersistenceObject) l
218: .get(i);
219: WfActivityInternal act = get(po.getId());
220: if (act == null) {
221: act = sharkEngineManager.getObjectFactory()
222: .createActivity(po, proc);
223: add(po.getId(), act);
224: }
225: }
226:
227: openLoaded = true;
228: }
229:
230: /**
231: * Loads specific activity from DB into the cache.
232: */
233: protected synchronized void loadAny(WMSessionHandle shandle,
234: String procId, String actId) throws Exception {
235: ActivityPersistenceObject po = SharkEngineManager.getInstance()
236: .getInstancePersistenceManager().restoreActivity(
237: shandle, procId, actId);
238: if (po != null) {
239: WfActivityInternal act = SharkEngineManager.getInstance()
240: .getObjectFactory().createActivity(po, proc);
241: add(actId, act);
242: }
243: }
244:
245: /**
246: * Duplicates this cache to be used in another process instance.
247: */
248: public synchronized ActivityCache duplicate(WfProcessInternal p)
249: throws Exception {
250: ActivityCache dup = new ActivityCache(p, false);
251: Iterator it = this .cache.entrySet().iterator();
252: while (it.hasNext()) {
253: Map.Entry me = (Map.Entry) it.next();
254: String aKey = (String) me.getKey();
255: WfActivityInternal aInt = (WfActivityInternal) me
256: .getValue();
257: dup.cache.put(aKey, aInt.duplicate(p));
258: }
259:
260: dup.allLoaded = this.allLoaded;
261: dup.openLoaded = this.openLoaded;
262: return dup;
263: }
264:
265: }
|