info.magnolia.module.workflow.jcr.JCRWorkItemAPI.java Source code

Java tutorial

Introduction

Here is the source code for info.magnolia.module.workflow.jcr.JCRWorkItemAPI.java

Source

/**
 *
 * Magnolia and its source-code is licensed under the LGPL.
 * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
 * When copying, adapting, or redistributing this document in keeping with the guidelines above,
 * you are required to provide proper attribution to obinary.
 * If you reproduce or distribute the document without making any substantive modifications to its content,
 * please use the following attribution line:
 *
 * Copyright 2006 obinary Ltd. (http://www.obinary.com) All rights reserved.
 *
 */
package info.magnolia.module.workflow.jcr;

import info.magnolia.cms.beans.config.ContentRepository;
import info.magnolia.cms.core.Content;
import info.magnolia.cms.core.HierarchyManager;
import info.magnolia.cms.core.ItemType;
import info.magnolia.cms.core.search.Query;
import info.magnolia.cms.core.search.QueryManager;
import info.magnolia.cms.core.search.QueryResult;
import info.magnolia.cms.security.AccessDeniedException;
import info.magnolia.cms.util.ContentUtil;
import info.magnolia.context.MgnlContext;
import info.magnolia.module.workflow.WorkflowConstants;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.jcr.RepositoryException;
import javax.jcr.ValueFactory;

import openwfe.org.engine.expressions.FlowExpressionId;
import openwfe.org.engine.workitem.InFlowWorkItem;
import openwfe.org.engine.workitem.StringAttribute;
import openwfe.org.worklist.store.StoreException;
import openwfe.org.xml.XmlCoder;
import openwfe.org.xml.XmlUtils;

import org.apache.commons.lang.StringUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JCRWorkItemAPI {

    public final static Logger log = LoggerFactory.getLogger(JCRWorkItemAPI.class.getName());

    HierarchyManager hm;

    public JCRWorkItemAPI() throws Exception {
        this.hm = ContentRepository.getHierarchyManager(WorkflowConstants.WORKSPACE_STORE);
        if (this.hm == null) {
            Exception e = new Exception("Can't get HierarchyManager Object for workitems repository");
            log.error(e.getMessage(), e);
            throw e;
        }
    }

    /**
     * remove one workItem by its ID
     */
    public void removeWorkItem(FlowExpressionId fei) throws StoreException {
        try {
            Content ct = getWorkItemById(fei);
            if (ct != null) {
                ct.delete();
                this.hm.save();
                if (log.isDebugEnabled()) {
                    log.debug("work item removed");
                }
            }

        } catch (Exception e) {
            log.error("exception:" + e);
        }
    }

    /**
     * retrieve work item by
     * @param storeName
     * @param fei
     * @return
     * @throws StoreException
     */
    public InFlowWorkItem retrieveWorkItem(final String storeName, final FlowExpressionId fei)
            throws StoreException {
        if (log.isDebugEnabled()) {
            log.debug("starting retrieve work item. this = " + this);
            log.debug("retrieve work item for ID = " + fei.toParseableString());
        }

        Content ct = getWorkItemById(fei);

        if (ct == null) {
            throw new StoreException("cannot find workitem " + fei);
        }

        try {
            return loadWorkItem(ct);
        } catch (Exception e) {
            throw new StoreException("load work item form xml failed", e);
        }
    }

    /**
     * load a work item from a JCR content
     * @param ct the content node
     * @return
     * @throws Exception
     */
    public static InFlowWorkItem loadWorkItem(Content ct) throws Exception {
        InFlowWorkItem wi;
        InputStream s = ct.getNodeData(WorkflowConstants.NODEDATA_VALUE).getStream();
        if (log.isDebugEnabled()) {
            log.debug("retrieve work item: value = " + s.toString());
        }
        final org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
        Document doc = builder.build(s);
        wi = (InFlowWorkItem) XmlCoder.decode(doc);

        Iterator itt = wi.getAttributes().alphaStringIterator();
        while (itt.hasNext()) {
            Object o = itt.next();
            String name1 = (String) o;
            if (log.isDebugEnabled()) {
                log.debug(name1 + "=" + wi.getAttribute(name1).toString());
            }
        }
        return wi;
    }

    /**
     * retrieve a work item by participant name
     * @param participant the full participant name (for example, user-superuser)
     */
    public Content getWorkItemByParticipant(String participant) {
        String queryString = "//*[@participant=\"" + participant + "\"]";
        if (log.isDebugEnabled())
            log.debug("xpath query string = " + queryString);
        List list = doQuery(queryString);
        if (list != null && list.size() > 0) {
            return (Content) list.get(0);
        }

        return null;
    }

    /**
     * get work item by id
     * @param fei
     */
    public Content getWorkItemById(FlowExpressionId fei) {
        String path = createPathFromId(fei);
        try {
            return this.hm.getContent(path);
        } catch (Exception e) {
            log.error("get work item by id failed, path = " + path, e);
        }
        return null;
    }

    /**
     * check whether the specified work item exists
     * @param fei expression id of work item
     * @return true if exist, false if not
     */
    public boolean hasWorkItem(FlowExpressionId fei) throws AccessDeniedException, RepositoryException {
        String path = createPathFromId(fei);
        if (StringUtils.isNotEmpty(path) && StringUtils.indexOf(path, "/") != 0) {
            path = "/" + path;
        }
        return this.hm.isExist(path);
    }

    /**
     * check if the content contains the right work Item with same id
     * @param ct JCR content
     * @param eid id of work item
     */
    public boolean checkContentWithEID(Content ct, FlowExpressionId eid) {
        String cid = ct.getNodeData(WorkflowConstants.NODEDATA_ID).getString();
        if (log.isDebugEnabled()) {
            log.debug("checkContentWithEID: ID = " + cid);
        }
        FlowExpressionId id = FlowExpressionId.fromParseableString(cid);
        return id.equals(eid);
    }

    /**
     * convert the name to valid path
     * @param id
     */
    public final String convertPath(String id) {
        return StringUtils.replace(StringUtils.replace(id, WorkflowConstants.BAR, StringUtils.EMPTY),
                WorkflowConstants.COLON, WorkflowConstants.DOT);
    }

    /**
     * create the jcr node path for work Item by its id
     * @param eid
     */
    public String createPathFromId(FlowExpressionId eid) {
        String wlInstId = eid.getWorkflowInstanceId();
        // FIXME someone who knows the code better should have a look
        String groupString = StringUtils.right(StringUtils.substringBefore(wlInstId, "."), 3);
        int groupNumber = Integer.parseInt(groupString) % 100;
        StringBuffer buffer = new StringBuffer(eid.getWorkflowDefinitionName());
        buffer.append(WorkflowConstants.SLASH);
        buffer.append(eid.getWorkflowDefinitionRevision());
        buffer.append(WorkflowConstants.SLASH);
        buffer.append(groupNumber);
        buffer.append(WorkflowConstants.SLASH);
        buffer.append(eid.getWorkflowInstanceId());
        buffer.append(WorkflowConstants.SLASH);
        buffer.append(eid.getExpressionName());
        buffer.append(WorkflowConstants.SLASH);
        buffer.append(eid.getExpressionId());

        return convertPath(buffer.toString());
    }

    /**
    * store work Item
    * 
    * @param arg0
    * @param wi
    *            the work item intends to be stored
    * @throws StoreException
    */
    public void storeWorkItem(String arg0, InFlowWorkItem wi) throws StoreException {
        try {

            // delete it if already exist
            if (hasWorkItem(wi.getId())) {
                // do not use removeWorkItem() since it persist changes immedietely
                this.hm.delete(createPathFromId(wi.getId()));
            }

            // create path from work item id
            String path = createPathFromId(wi.getId());
            if (log.isDebugEnabled())
                log.debug("storing workitem with path = " + path);

            Content newc = ContentUtil.createPath(this.hm, path, ItemType.WORKITEM);

            ValueFactory vf = newc.getJCRNode().getSession().getValueFactory();
            String sId = wi.getLastExpressionId().toParseableString();

            newc.createNodeData(WorkflowConstants.NODEDATA_ID, vf.createValue(sId));
            newc.createNodeData(WorkflowConstants.NODEDATA_PARTICIPANT, vf.createValue(wi.getParticipantName()));

            if (log.isDebugEnabled()) {
                log.debug("ID=" + sId);
                log.debug("participant = " + wi.getParticipantName());
            }

            StringAttribute assignTo = (StringAttribute) wi.getAttribute(WorkflowConstants.ATTRIBUTE_ASSIGN_TO);
            if (assignTo != null) {
                String s = assignTo.toString();
                if (s.length() > 0) {
                    newc.createNodeData(WorkflowConstants.ATTRIBUTE_ASSIGN_TO, vf.createValue(s));
                }
                if (log.isDebugEnabled())
                    log.debug("assignTo=" + s);
            }

            // convert to xml string
            Element encoded = XmlCoder.encode(wi);
            final org.jdom.Document doc = new org.jdom.Document(encoded);
            String s = XmlUtils.toString(doc, null);
            newc.createNodeData(WorkflowConstants.NODEDATA_VALUE, vf.createValue(s));

            if (log.isDebugEnabled())
                log.debug("store work item: value=" + s);

            this.hm.save();

            if (log.isDebugEnabled())
                log.debug("store work item ok. ");
        } catch (Exception e) {
            log.error("store work item failed", e);
            throw new StoreException(e.toString());
        }

    }

    /**
     * execute the xPath Query
     */
    public List doQuery(String queryString) {
        ArrayList list = new ArrayList();
        if (log.isDebugEnabled())
            log.debug("xpath query string: " + queryString);
        try {
            final QueryManager queryManager = MgnlContext.getSystemContext()
                    .getQueryManager(WorkflowConstants.WORKSPACE_STORE);
            final Query q = queryManager.createQuery(queryString, Query.XPATH); //$NON-NLS-1$

            QueryResult result = q.execute();
            if (result == null) {
                log.info("query result was null");
                return null;
            }

            Iterator it = result.getContent(WorkflowConstants.NODENAME_WORKITEM).iterator();
            while (it.hasNext()) {
                Content ct = (Content) it.next();
                String title = ct.getTitle();
                String sname = ct.getName();

                if (log.isDebugEnabled()) {
                    log.debug("title=" + title);
                    log.debug("name=" + sname);
                }

                InFlowWorkItem wi = loadWorkItem(ct);
                if (wi == null) {
                    log.error("can not load found workitem");
                    continue;
                }
                if (log.isDebugEnabled())
                    log.debug("added workitem to return list ok");
                list.add(wi);
            }
        } catch (Exception e) {
            log.error("query flow failed", e);
            return null;
        }
        return list;

    }

}