Java tutorial
/* * Copyright (c) 2004-2012 The YAWL Foundation. All rights reserved. * The YAWL Foundation is a collaboration of individuals and * organisations who are committed to improving workflow technology. * * This file is part of YAWL. YAWL is free software: you can * redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation. * * YAWL is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with YAWL. If not, see <http://www.gnu.org/licenses/>. */ package org.yawlfoundation.yawl.resourcing; import org.jdom2.Element; import org.yawlfoundation.yawl.engine.interfce.Marshaller; import org.yawlfoundation.yawl.engine.interfce.WorkItemRecord; import org.yawlfoundation.yawl.resourcing.datastore.WorkItemCache; import org.yawlfoundation.yawl.resourcing.datastore.eventlog.EventLogger; import org.yawlfoundation.yawl.resourcing.datastore.persistence.Persister; import org.yawlfoundation.yawl.util.JDOMUtil; import org.yawlfoundation.yawl.util.StringUtil; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** * Convenience class that encapsulates the various work queues for a Participant and/or * Administrator - each instance representing a single queue * * @author Michael Adams * v0.1, 03/08/2007 */ public class WorkQueue { // different queue types public final static int UNDEFINED = -1; public final static int OFFERED = 0; public final static int ALLOCATED = 1; public final static int STARTED = 2; public final static int SUSPENDED = 3; public final static int UNOFFERED = 4; // administrator only public final static int WORKLISTED = 5; // administrator only // the workitems assigned to this queue: <item's id, item> private Map<String, WorkItemRecord> _workitems = new ConcurrentHashMap<String, WorkItemRecord>(); private long _id; // hibernate primary key private String _ownerID; // who owns this queue? private int _queueType; private boolean _persisting; /******************************************************************************/ // CONSTRUCTORS // public WorkQueue() { } public WorkQueue(String ownerID, int qType, boolean persisting) { _ownerID = ownerID != null ? ownerID : "admin"; _queueType = qType; _persisting = persisting; if (_persisting) Persister.getInstance().insert(this); } public WorkQueue(String ownerID, WorkItemRecord item, int qType, boolean persisting) { this(ownerID, qType, persisting); add(item, true); } public WorkQueue(String ownerID, HashMap<String, WorkItemRecord> items, int qType, boolean persisting) { this(ownerID, qType, persisting); addQueue(items); } public WorkQueue(String ownerID, WorkQueue queue, int qType, boolean persisting) { this(ownerID, qType, persisting); addQueue(queue); } /******************************************************************************/ // PRIVATE METHODS // /** Called when this workqueue's contents have changed. * Note that the admin worklisted queue is dynamically constructed from the union * of all participant queues and thus does not need to be persisted */ private void persistThis() { if (_persisting && _queueType < WORKLISTED) { Persister.getInstance().update(this); } } /** * adds an entry in the process log when a workitem is added to a queue * (since that signifies a resourcing status change). * Additions to the admin worklisted queue is ignored. * * @param wir the workitem effecting the change */ private void logEvent(WorkItemRecord wir) { if (_queueType < WORKLISTED) EventLogger.log(wir, _ownerID, _queueType); } private void logEvent(Map<String, WorkItemRecord> map) { if (_queueType < WORKLISTED) for (WorkItemRecord wir : map.values()) logEvent(wir); } /******************************************************************************/ // ACCESSIBLE METHODS // public void setOwnerID(String id) { _ownerID = id; } public String getOwnerID() { return _ownerID; } public String getID() { return _ownerID; } public int getQueueType() { return _queueType; } public void setQueueType(int qType) { _queueType = qType; } public boolean isPersisting() { return _persisting; } public void setPersisting(boolean persist) { _persisting = persist; } /** * Adds a workitem to the queue * @param item the workitem to add */ public void add(WorkItemRecord item, boolean log) { _workitems.put(item.getID(), item); persistThis(); if (log) logEvent(item); } /** * Adds all members of the Map passed to the queue * @param queueMap the Map of [item id, YWorkItem] to add */ public void addQueue(Map<String, WorkItemRecord> queueMap) { _workitems.putAll(queueMap); persistThis(); logEvent(queueMap); } /** * Adds all the items in the queue passed to this work queue * (i.e. does not replace the queue) * @param queue the queue of items to add */ public void addQueue(WorkQueue queue) { addQueue(queue.getQueueAsMap()); } /** * Sets (replaces) this work queue's members with the members of the queue passed * @param queue the new queue */ public void setQueue(WorkQueue queue) { _workitems = queue.getQueueAsMap(); persistThis(); logEvent(_workitems); } /** * Retrieves a workitem from the queue (but does not remove it) * @param itemID the ID of the workitem to retrieve * @return the retrieved workitem */ public WorkItemRecord get(String itemID) { return _workitems.get(itemID); } /** * Retrieves a Set of all workitems in the queue * @return a Set of all WorkItemRecord objects in the work queue */ public Set<WorkItemRecord> getAll() { Set<WorkItemRecord> result = new HashSet<WorkItemRecord>(); for (WorkItemRecord wir : _workitems.values()) { if (wir != null) result.add(wir); } return result; } /** * Retrieves a HashMap of all workitems in the queue * @return all members of the queue as a HashMap of [item id, YWorkItem] */ public Map<String, WorkItemRecord> getQueueAsMap() { return _workitems; } /** * Removes a workitem from the queue * @param item the workitem to remove */ public void remove(WorkItemRecord item) { if (item != null && _workitems.containsKey(item.getID())) { _workitems.remove(item.getID()); persistThis(); } } /** * Removes all the items in the queue passed from this work queue * (i.e. does not replace the queue) * @param queue the queue of items to remove */ public void removeQueue(WorkQueue queue) { for (WorkItemRecord wir : queue.getAll()) { remove(wir); } } /* Removes all workitems from the queue */ public void clear() { if (!_workitems.isEmpty()) { _workitems.clear(); persistThis(); } } public void refresh(WorkItemRecord wir) { if (_workitems.containsKey(wir.getID())) { _workitems.put(wir.getID(), wir); persistThis(); } } public void cleanse(WorkItemCache cache) { Set<String> clonedQueue = new HashSet<String>(_workitems.keySet()); for (String itemID : clonedQueue) { if (cache.get(itemID) == null) _workitems.remove(itemID); } if (_workitems.size() != clonedQueue.size()) persistThis(); } public void removeCase(String caseID) { Set<WorkItemRecord> clonedQueue = new HashSet<WorkItemRecord>(_workitems.values()); for (WorkItemRecord wir : clonedQueue) { if (wir.getRootCaseID().equals(caseID)) _workitems.remove(wir.getID()); } if (_workitems.size() != clonedQueue.size()) persistThis(); } /** @return true if the work queue contains no work items */ public boolean isEmpty() { return _workitems.isEmpty(); } /** returns the number of workitems in this queue */ public int getQueueSize() { return _workitems.size(); } /** returns the appropriate String identifier for the queue type passed */ public static String getQueueName(int qType) { String result; switch (qType) { case OFFERED: result = "Offered"; break; case ALLOCATED: result = "Allocated"; break; case STARTED: result = "Started"; break; case SUSPENDED: result = "Suspended"; break; case UNOFFERED: result = "Unoffered"; break; case WORKLISTED: result = "Worklisted"; break; default: result = "Invalid Queue Type"; } return result; } public static boolean isValidQueueType(int queueType) { return (queueType >= OFFERED) && (queueType <= WORKLISTED); } /** returns the name of this queue */ public String getQueueName() { return getQueueName(_queueType); } public String toXML() { StringBuilder xml = new StringBuilder("<WorkQueue>"); xml.append(StringUtil.wrap(String.valueOf(_queueType), "queuetype")); xml.append(StringUtil.wrap(_ownerID, "ownerid")); xml.append("<workitems>"); for (WorkItemRecord wir : _workitems.values()) { xml.append(wir.toXML()); } xml.append("</workitems>"); xml.append("</WorkQueue>"); return xml.toString(); } public void fromXML(String xml) { fromXML(JDOMUtil.stringToElement(xml)); } public void fromXML(Element element) { if (element != null) { _queueType = new Integer(element.getChildText("queuetype")); _ownerID = element.getChildText("ownerid"); Element items = element.getChild("workitems"); if (items != null) { for (Element e : items.getChildren()) { WorkItemRecord wir = Marshaller.unmarshalWorkItem(e); _workitems.put(wir.getID(), wir); } } } } // hibernate mappings private String get_ownerID() { return _ownerID; } private void set_ownerID(String ownerID) { _ownerID = ownerID; } private int get_queueType() { return _queueType; } private void set_queueType(int queueType) { _queueType = queueType; } private long get_id() { return _id; } private void set_id(long id) { _id = id; } }