package org.imixs.marty.plugins.minutes;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import javax.mail.internet.AddressException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.imixs.marty.ejb.SystemWorkitemService;
import org.imixs.workflow.ItemCollection;
import org.imixs.workflow.ItemCollectionComparator;
import org.imixs.workflow.WorkflowContext;
import org.imixs.workflow.engine.WorkflowService;
import org.imixs.workflow.engine.plugins.VersionPlugin;
import org.imixs.workflow.exceptions.AccessDeniedException;
import org.imixs.workflow.exceptions.PluginException;
import org.imixs.workflow.exceptions.QueryException;
/**
* This Plugin extends the Version Plugin mechanism and manages child workitems
* in the master version and version of a minute.
*
* When a new version was created, all Child Workitems will copied into this
* version and automatically archived. Child workitems in the current master
* version, which are not archived or deleted will be removed from the current
* version.
*
*
* After a new version was created the property datDate will be deleted in the
* current version.
*
* SequenceNumber
*
* The Plugin also computes a numsequencenumber for childWorkitems. There for
* the plugins computes the child count of the parent woritem.
*
* @author rsoika
* @version 2.0
*
*/
public class MinutePlugin extends VersionPlugin {
private SystemWorkitemService systemWorkitemService = null;
private static Logger logger = Logger.getLogger(MinutePlugin.class
.getName());
public void init(WorkflowContext actx) throws PluginException {
super.init(actx);
// lookup profile service EJB
String jndiName = "ejb/SystemWorkitemService";
InitialContext ictx;
try {
ictx = new InitialContext();
Context ctx = (Context) ictx.lookup("java:comp/env");
systemWorkitemService = (SystemWorkitemService) ctx.lookup(jndiName);
} catch (NamingException e) {
throw new PluginException(MinutePlugin.class.getSimpleName(),
INVALID_CONTEXT,
"[MinutePlugin] unable to find SystemWorkitemService", e);
}
}
/**
* If a version was created, all childWorkitems will be copied into the
* version. Childs from the current master version which are archived or
* deleted will be removed.
*
* To copy a childworkitem the plugin removes the current $UniqueID and
* replaces the $UniqueIDRef with the $UniqueId of the new Version. Next
* this workitem is saved. So it becomes a new entity which is a child to
* the version.
*
* @return
* @throws PluginException
* @throws AddressException
*/
@Override
public ItemCollection run(ItemCollection documentContext,
ItemCollection documentActivity) throws PluginException {
// Compute a sequencenumber for new child workitems
computeSequenceNumber(documentContext);
// Versioning....
documentContext = super.run(documentContext, documentActivity);
// check if a Version was created
ItemCollection version = this.getVersion();
if (version != null) {
logger.info("[MinutePlugin] creating new version....");
String versionUnqiueID = version.getItemValueString("$uniqueid");
String uniqueID = documentContext.getItemValueString("$uniqueid");
// remove datDate from current workitem.
documentContext.removeItem("datDate");
// new version was created - now copy all minute items....
// get childs of original
Collection<ItemCollection> childs = this.getWorkflowService()
.getWorkListByRef(uniqueID);
for (ItemCollection achild : childs) {
String sType = achild.getItemValueString("type");
String sSummary = achild
.getItemValueString("txtWorkflowSummary");
try {
// change ref id!
achild.replaceItemValue("$uniqueidRef", versionUnqiueID);
// when child not archived or deleted, create a new instance
// and change
// the type to archived
if ((!sType.endsWith("deleted"))
&& (!sType.endsWith("archive"))) {
// it is an active workitem!
// so we create a copy and attache it to the new version
// the origin will not be touched!
achild.replaceItemValue("type", sType + "archive");
// duplicate workitem be removing the uniqueId
achild.replaceItemValue("$uniqueid", "");
logger.fine("[MinutePlugin] clone and archive child '"
+ sSummary + "'");
}
// save child with runAs manager access level
// this.getEntityService().save(achild);
systemWorkitemService.save(achild);
} catch (AccessDeniedException e) {
throw new PluginException("could not save", "SAVE_ERROR",
e.getMessage(), e);
}
}
}
return documentContext;
}
/**
* This method compute a new numsequencenumber for childworkitems. The next
* number is computed based on the count childwokitems.
*
*/
@SuppressWarnings("unchecked")
private void computeSequenceNumber(ItemCollection documentContext) {
ItemCollection parent = null;
String sUniqueIdRef=null;
String sType = documentContext.getItemValueString("Type");
// skip if it is no workitem or numsequencenumber already defined
if (documentContext.hasItem("numsequencenumber")
|| !(sType.contains("workitem"))) {
logger.fine("[MinutePlugin] skip computeSequenceNumber - number already exits");
return;
}
// test if a parent workitem exits
List<String> uniqueIdRefList = documentContext
.getItemValue(WorkflowService.UNIQUEIDREF);
for (String id : uniqueIdRefList) {
parent = this.getWorkflowService().getWorkItem(id);
if (parent != null) {
String parentType = parent.getItemValueString("type");
if ("workitem".equals(parentType)) {
sUniqueIdRef=id;
break;
} else {
parent = null;
}
}
}
if (parent==null) {
logger.fine("skip computeSequenceNumber - no parent workitem");
return;
}
logger.fine("computeSequenceNumber for Ref:"
+ sUniqueIdRef + "....");
String searchTerm="( (type:\"workitem\" OR type:\"childworkitem\" OR type:\"workitemarchive\" OR type:\"childworkitemarchive\") AND $uniqueidref:\""+sUniqueIdRef + "\")";
logger.fine("computeSequenceNumber searchterm=" + searchTerm);
List<ItemCollection> childList;
try {
childList = this.getWorkflowService().getDocumentService().find(searchTerm, 1, 0);
// sort by numsequencenumber
Collections.sort(childList, new ItemCollectionComparator("numsequencenumber", true));
int iNumber = 1;
if (childList != null && childList.size() > 0) {
ItemCollection child = childList.iterator().next();
iNumber = child.getItemValueInteger("numsequencenumber");
logger.fine("[MinutePlugin] last sequence number=" + iNumber);
iNumber++;
}
documentContext.replaceItemValue("numsequencenumber", iNumber);
} catch (QueryException e) {
logger.warning("computeSequenceNumber - invalid query: " + e.getMessage());
}
}
}