Package org.intalio.tempo.workflow.tms.server

Source Code of org.intalio.tempo.workflow.tms.server.TMSServer

/**
* Copyright (c) 2005-2008 Intalio inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Intalio inc. - initial API and implementation
*
* $Id: TaskManagementServicesFacade.java 5440 2006-06-09 08:58:15Z imemruk $
* $Log:$
*/

package org.intalio.tempo.workflow.tms.server;

import java.net.URL;
import java.util.HashMap;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.commons.lang.StringUtils;
import org.intalio.tempo.workflow.auth.AuthException;
import org.intalio.tempo.workflow.auth.AuthIdentifierSet;
import org.intalio.tempo.workflow.auth.IAuthProvider;
import org.intalio.tempo.workflow.auth.UserRoles;
import org.intalio.tempo.workflow.task.InvalidTaskException;
import org.intalio.tempo.workflow.task.PATask;
import org.intalio.tempo.workflow.task.PIPATask;
import org.intalio.tempo.workflow.task.Task;
import org.intalio.tempo.workflow.task.TaskState;
import org.intalio.tempo.workflow.task.attachments.Attachment;
import org.intalio.tempo.workflow.task.traits.ITaskWithAttachments;
import org.intalio.tempo.workflow.task.traits.ITaskWithOutput;
import org.intalio.tempo.workflow.task.traits.ITaskWithState;
import org.intalio.tempo.workflow.task.xml.TaskTypeMapper;
import org.intalio.tempo.workflow.task.xml.XmlTooling;
import org.intalio.tempo.workflow.tms.AccessDeniedException;
import org.intalio.tempo.workflow.tms.InvalidTaskStateException;
import org.intalio.tempo.workflow.tms.TMSException;
import org.intalio.tempo.workflow.tms.TaskIDConflictException;
import org.intalio.tempo.workflow.tms.UnavailableAttachmentException;
import org.intalio.tempo.workflow.tms.UnavailableTaskException;
import org.intalio.tempo.workflow.tms.server.dao.ITaskDAOConnection;
import org.intalio.tempo.workflow.tms.server.permissions.TaskPermissions;
import org.intalio.tempo.workflow.util.jpa.TaskFetcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import com.intalio.bpms.workflow.taskManagementServices20051109.TaskMetadata;

public class TMSServer implements ITMSServer {

    private static final Logger _logger = LoggerFactory.getLogger(TMSServer.class);
    private IAuthProvider _authProvider;
    private TaskPermissions _permissions;
    private int _httpTimeout = 10000;

    public TMSServer() {
    }

    public TMSServer(IAuthProvider authProvider, TaskPermissions permissions) {
        _logger.info("New TMS Instance");
        assert authProvider != null : "IAuthProvider implementation is absent!";
       
        setAuthProvider(authProvider);

        setPermissions(permissions);
    }

    public void setPermissions(TaskPermissions permissions) {
        this._permissions = permissions;
    }

    public int getHttpTimeout() {
        return _httpTimeout;
    }

    public void setHttpTimeout(int httpTimeout) {
        _httpTimeout = httpTimeout;
    }

    public void setAuthProvider(IAuthProvider authProvider) {
        this._authProvider = authProvider;
        _logger.info("IAuthProvider implementation : " + _authProvider.getClass());
    }


/*JIRA WF-1466 Changes have been made to get the dao in the method
instead of creating and opening connections in the method itself */
    public Task[] getTaskList(ITaskDAOConnection dao,String participantToken) throws AuthException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        Task[] result = dao.fetchAllAvailableTasks(credentials);
        return result;
    }

    public UserRoles getUserRoles(String participantToken) throws AuthException {
        return _authProvider.authenticate(participantToken);
    }

    public Task getTask(ITaskDAOConnection dao,String taskID, String participantToken) throws AuthException, UnavailableTaskException,
            AccessDeniedException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        
        Task task = dao.fetchTaskIfExists(taskID);
        if ((task != null)) {
            checkIsAvailable(taskID, task, credentials);
            if (_logger.isDebugEnabled())
                _logger.debug("Workflow Task " + taskID + " for user " + credentials.getUserID());
            return task;
        } else {
            throw new UnavailableTaskException("No task with" + taskID + " has been found");
        }
    }

    protected ServiceClient getServiceClient() throws AxisFault {
        return new ServiceClient();
    }

    private void checkIsAvailable(String taskID, Task task, UserRoles credentials) throws AccessDeniedException {
        // the task has been assign to those credentials
        if (task.isAvailableTo(credentials))
            return;
        // some admin access user has been defined in the configuration file
        else if (_permissions.isAuthorized(TaskPermissions.ACTION_READ, task, credentials))
            return;
        // fire the exception, this user cannot read this task
        else
            throw new AccessDeniedException(credentials.getUserID() + " cannot access task:" + taskID);
    }

    public void setOutput(ITaskDAOConnection dao,String taskID, Document output, String participantToken) throws AuthException,
            UnavailableTaskException, AccessDeniedException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        Task task = dao.fetchTaskIfExists(taskID);
        checkIsAvailable(taskID, task, credentials);
        if (task instanceof ITaskWithOutput) {
            ITaskWithOutput taskWithOutput = (ITaskWithOutput) task;
            taskWithOutput.setOutput(output);
            dao.updateTask(task);
            dao.commit();
            if (_logger.isDebugEnabled())
                _logger.debug(credentials.getUserID() + " has set output for Workflow Task " + task);
        } else
            throw new UnavailableTaskException(credentials.getUserID() + " cannot set output for Workflow Task " + task);
    }

    public void complete(ITaskDAOConnection dao,String taskID, String participantToken) throws AuthException, UnavailableTaskException,
            InvalidTaskStateException, AccessDeniedException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        Task task = dao.fetchTaskIfExists(taskID);
        checkIsAvailable(taskID, task, credentials);
        if (task instanceof ITaskWithState) {
            ITaskWithState taskWithState = (ITaskWithState) task;
            taskWithState.setState(TaskState.COMPLETED);
            dao.updateTask(task);
            dao.commit();
            if (_logger.isDebugEnabled())
                _logger.debug(credentials.getUserID() + " has completed the Workflow Task " + task);
        } else {
            throw new UnavailableTaskException(credentials.getUserID() + " cannot complete Workflow Task " + task);
        }
    }

    public void setOutputAndComplete(ITaskDAOConnection dao,String taskID, Document output, String participantToken) throws AuthException,
            UnavailableTaskException, InvalidTaskStateException, AccessDeniedException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        Task task = dao.fetchTaskIfExists(taskID);
        checkIsAvailable(taskID, task, credentials);
        if (task instanceof ITaskWithOutput && task instanceof ITaskWithState) {
            ((ITaskWithOutput) task).setOutput(output);
            ((ITaskWithState) task).setState(TaskState.COMPLETED);
            dao.updateTask(task);
            dao.commit();
            if (_logger.isDebugEnabled())
                _logger.debug(credentials.getUserID() + " has set output and completed Workflow Task " + task);
        } else {
            throw new UnavailableTaskException(credentials.getUserID()
                    + " cannot set output and complete Workflow Task " + task);
        }
    }

    public void fail(ITaskDAOConnection dao,String taskID, String failureCode, String failureReason, String participantToken)
            throws AuthException, UnavailableTaskException {
        boolean available = false;

        // UserRoles credentials = _authProvider.authenticate(participantToken);
        Task task = dao.fetchTaskIfExists(taskID);
        available = task instanceof ITaskWithState;
        // && task.isAvailableTo(credentials)
        if (available) {
            ITaskWithState taskWithState = (ITaskWithState) task;
            taskWithState.setState(TaskState.FAILED);
            taskWithState.setFailureCode(failureCode);
            taskWithState.setFailureReason(failureReason);
            dao.updateTask(task);
            dao.commit();
            _logger.debug(
            // credentials.getUserID() +
            " fails Workflow Task " + task + " with code: " + failureCode + " and reason: " + failureReason);
        }
        if (!available) {
            throw new UnavailableTaskException("Cannot set state as FAILED for Workflow Task " + task);
        }
    }

    public void delete(ITaskDAOConnection dao,String[] taskIDs, String participantToken) throws AuthException, UnavailableTaskException {
        HashMap<String, Exception> problemTasks = new HashMap<String, Exception>();
        UserRoles credentials = _authProvider.authenticate(participantToken);

        String userID = credentials.getUserID();
        for (String taskID : taskIDs) {
            try {
                Task task = dao.fetchTaskIfExists(taskID);
                if (_permissions.isAuthorized(TaskPermissions.ACTION_DELETE, task, credentials)) {
                    dao.deleteTask(task.getInternalId(), taskID);
                    dao.commit();
                    if (_logger.isDebugEnabled())
                        _logger.debug(userID + " has deleted Workflow Task " + task);
                } else {
                    problemTasks.put(taskID, new AuthException(userID + " cannot delete" + taskID));
                }
            } catch (Exception e) {
                _logger.error("Cannot retrieve Workflow Tasks", e);
                problemTasks.put(taskID, e);
            }
        }
        if (problemTasks.size() > 0) {
            throw new UnavailableTaskException(userID + " cannot delete Workflow Tasks: " + problemTasks.keySet());
        }
    }

    public void create(ITaskDAOConnection dao,Task task, String participantToken) throws AuthException, TaskIDConflictException {
        // UserRoles credentials =
        // _authProvider.authenticate(participantToken);// FIXME: decide on this
        // issue

        try {
            dao.createTask(task);
            dao.commit();
            if (_logger.isDebugEnabled())
                _logger.debug("Workflow Task " + task + " was created");
            // TODO : Use credentials.getUserID() :vb
        } catch (Exception e) {
            _logger.error("Cannot create Workflow Tasks", e); // TODO :
            // TaskIDConflictException
            // must be rethrowed :vb
        }
    }

    public void update(ITaskDAOConnection dao,TaskMetadata task, String participantToken) throws AuthException, TMSException, AxisFault {
        try {
            String id = task.getTaskId();
            Task previous = dao.fetchTaskIfExists(id);
            if (previous != null && (previous instanceof PATask)) {
                PATask paPrevious = (PATask) previous;

                // security ?
                UserRoles credentials = _authProvider.authenticate(participantToken);
                // checkIsAvailable(id, previous, credentials);

                try {
                    paPrevious.setPriority(task.getPriority());
                } catch (Exception e) {
                    _logger.debug("Ignoring invalid priority value:" + task.xgetPriority().toString());
                }
                String desc = task.getDescription();
                if (!StringUtils.isEmpty(desc))
                    paPrevious.setDescription(desc);

                dao.updateTask(previous);
                dao.commit();
                if (_logger.isDebugEnabled())
                    _logger.debug("Workflow Task " + task + " was updated");
            } else {
                throw new RuntimeException("No previous activity task with the given id:" + id + (previous != null)
                        + (previous instanceof PATask));
            }
        } catch (Exception e) {
          _logger.error("Error while sending updating:" + e.getClass(), e);
            throw AxisFault.makeFault(e);
        }
    }

    private Document sendInitMessage(PIPATask task, String user, String formUrl, String participantToken, Document input)
            throws AxisFault {

        OMFactory omFactory = OMAbstractFactory.getOMFactory();
        OMNamespace omNamespace = omFactory.createOMNamespace(task.getInitMessageNamespaceURI().toString(), "user");

        OMElement omInitProcessRequest = omFactory.createOMElement("initProcessRequest", omNamespace);
        OMElement omTaskId = omFactory.createOMElement("taskId", omNamespace, omInitProcessRequest);
        omTaskId.setText(task.getID());
        OMElement omParticipantToken = omFactory.createOMElement("participantToken", omNamespace, omInitProcessRequest);
        omParticipantToken.setText(participantToken);

        OMElement omUser = omFactory.createOMElement("user", omNamespace, omInitProcessRequest);
        omUser.setText(user);

        OMElement omFormUrl = omFactory.createOMElement("formUrl", omNamespace, omInitProcessRequest);
        omFormUrl.setText(formUrl);

        OMElement omTaskOutput = omFactory.createOMElement("taskOutput", omNamespace, omInitProcessRequest);

        XmlTooling xmlTooling = new XmlTooling();
        if (input != null)
            omTaskOutput.addChild(xmlTooling.convertDOMToOM(input, omFactory));

        Options options = new Options();
        EndpointReference endpointReference = new EndpointReference(task.getProcessEndpoint().toString());
        options.setTo(endpointReference);
        options.setAction(task.getInitOperationSOAPAction());

        if (_logger.isDebugEnabled()) {
            _logger.debug(task + " was used to start the process with endpoint:" + task.getProcessEndpoint());
            _logger.debug("Request to Ode:\n" + omInitProcessRequest.toString());
        }

        ServiceClient client = getServiceClient();
        client.setOptions(options);
        try {
            options.setTimeOutInMilliSeconds(_httpTimeout);
            OMElement response = client.sendReceive(omInitProcessRequest);
            return xmlTooling.convertOMToDOM(response);
        } catch (Exception e) {
            _logger.error("Error while sending initProcessRequest:" + e.getClass(), e);
            throw AxisFault.makeFault(e);
        }

    }

    public Document initProcess(ITaskDAOConnection dao,String taskID, String user, String formUrl, Document input, String participantToken)
            throws AuthException, UnavailableTaskException, AccessDeniedException, AxisFault {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        Task task = dao.fetchTaskIfExists(taskID);
        checkIsAvailable(taskID, task, credentials);
        if (task instanceof PIPATask) {
            PIPATask pipaTask = (PIPATask) task;
            Document document = sendInitMessage(pipaTask, user, formUrl, participantToken, input);
            if (_logger.isDebugEnabled())
                _logger.debug(credentials.getUserID() + " has initialized process " + pipaTask.getProcessEndpoint()
                        + " with Workflow PIPA Task " + task);
            return document;
        } else {
            throw new UnavailableTaskException("Task (" + taskID
                    + ") is not a PIPA task cannot be used to initiate a process");
        }
    }

    public Attachment[] getAttachments(ITaskDAOConnection dao,String taskID, String participantToken) throws AuthException,
            UnavailableTaskException, AccessDeniedException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        Task task = dao.fetchTaskIfExists(taskID);
        checkIsAvailable(taskID, task, credentials);
        if (task instanceof ITaskWithAttachments) {
            ITaskWithAttachments taskWithAttachments = (ITaskWithAttachments) task;
            return taskWithAttachments.getAttachments().toArray(new Attachment[] {});
        } else {
            throw new RuntimeException("Task (" + taskID + ") does not have attachment");
        }
    }

    public void addAttachment(ITaskDAOConnection dao,String taskID, Attachment attachment, String participantToken) throws AuthException,
            UnavailableTaskException, AccessDeniedException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        Task task = dao.fetchTaskIfExists(taskID);
        checkIsAvailable(taskID, task, credentials);
        if (task instanceof ITaskWithAttachments == false) {
            throw new UnavailableTaskException("Task does not support attachments");
        }
        ITaskWithAttachments taskWithAttachments = (ITaskWithAttachments) task;
        taskWithAttachments.addAttachment(attachment);
        dao.updateTask(task);
        dao.commit();
        if (_logger.isDebugEnabled())
            _logger.debug(credentials.getUserID() + " has added attachment " + attachment + "to Workflow Task " + task);
    }

    public void removeAttachment(ITaskDAOConnection dao,String taskID, URL attachmentURL, String participantToken) throws AuthException,
            UnavailableAttachmentException, UnavailableTaskException {

        Task task = null;
        boolean availableTask = false;
        boolean availableAttachment = false;

        UserRoles credentials = _authProvider.authenticate(participantToken);
        try {
            task = dao.fetchTaskIfExists(taskID);
            availableTask = task instanceof ITaskWithAttachments && task.isAvailableTo(credentials);
            if (availableTask) {
                ITaskWithAttachments taskWithAttachments = (ITaskWithAttachments) task;
                Attachment removedAttachment = taskWithAttachments.removeAttachment(attachmentURL);
                availableAttachment = (removedAttachment != null);
                if (availableAttachment) {
                    dao.updateTask(task);
                    dao.commit();
                    if (_logger.isDebugEnabled())
                        _logger.debug(credentials.getUserID() + " has removed attachment " + attachmentURL
                                + " for Workflow Task " + task);
                }
            }
        } catch (Exception e) {
            _logger.error("Error while delete attachment " + attachmentURL + " for Workflow Task " + taskID, e);
        }
        if (!availableTask || !availableAttachment) {
            throw new UnavailableTaskException(credentials.getUserID() + " cannot remove attachment for Workflow Task "
                    + task + ", is problem with task? - " + availableTask + ", is problem with attachment? - "
                    + availableAttachment);
        }
    }

    public void reassign(ITaskDAOConnection dao,String taskID, AuthIdentifierSet users, AuthIdentifierSet roles, TaskState state,
            String participantToken) throws AuthException, UnavailableTaskException {
        // UserRoles credentials = _authProvider
        // TODO: this requires SYSTEM
        // role
        // to be present
        // .authenticate(participantToken); // for the Escalations to work. This
        // is
        // a security hole for now!

        Task task = null;
        boolean available = false;

        try {
            task = dao.fetchTaskIfExists(taskID);
            // if (task.isAvailableTo(credentials) && (task instanceof
            // ITaskWithState)) { // TODO: see above
            available = task instanceof ITaskWithState;
            if (available) {
                ((ITaskWithState) task).setState(state);
                task.setUserOwners(users);
                task.setRoleOwners(roles);

                dao.updateTask(task);
                dao.commit();
                if (_logger.isDebugEnabled())
                    _logger.debug(" changed to user owners " + users + " and role owners " + roles);
            }
        } catch (Exception e) {
            _logger.error("Cannot retrieve Workflow Tasks", e);
        }
        if (!available) {
            throw new UnavailableTaskException("Error to ressign Workflow Task " + task);
        }
    }

    public void deletePipa(ITaskDAOConnection dao,String formUrl, String participantToken) throws AuthException, UnavailableTaskException {
        HashMap<String, Exception> problemTasks = new HashMap<String, Exception>();

        // DOTO due to all the service from wds is 'x'
        if (participantToken.equalsIgnoreCase("x")) {
            dao.deletePipaTask(formUrl);
            dao.commit();
        } else {
            UserRoles credentials = _authProvider.authenticate(participantToken);
            String userID = credentials.getUserID();
            try {
                Task task = dao.fetchPipa(formUrl);
                if (_permissions.isAuthorized(TaskPermissions.ACTION_DELETE, task, credentials)) {
                    dao.deletePipaTask(formUrl);
                    dao.commit();
                    if (_logger.isDebugEnabled())
                        _logger.debug(userID + " has deleted PIPA Task " + task);
                } else {
                    problemTasks.put(formUrl, new AuthException(userID + " cannot delete" + formUrl));
                }
            } catch (Exception e) {
                _logger.error("Cannot retrieve PIPA Tasks", e);
                problemTasks.put(formUrl, e);
            }
            if (problemTasks.size() > 0) {
                throw new UnavailableTaskException(userID + " cannot delete PIPA Tasks: " + problemTasks.keySet());
            }
        }

    }

    public PIPATask getPipa(ITaskDAOConnection dao,String formUrl, String participantToken) throws AuthException, UnavailableTaskException {
        try {
            return dao.fetchPipa(formUrl);
        } catch (Exception e) {
            throw new UnavailableTaskException(e);
        }
    }

    public void storePipa(ITaskDAOConnection dao,PIPATask task, String participantToken) throws AuthException, InvalidTaskException {
        try {
            dao.storePipaTask(task);
            dao.commit();
        } catch (Exception e) {
            throw new InvalidTaskException(e);
        }
    }

    public Task[] getAvailableTasks(ITaskDAOConnection dao,String participantToken, String taskType, String subQuery) throws AuthException {
        HashMap map = new HashMap(3);
        map.put(TaskFetcher.FETCH_CLASS_NAME, taskType);
        map.put(TaskFetcher.FETCH_SUB_QUERY, subQuery);
        return this.getAvailableTasks(dao,participantToken, map);
    }

    public Long countAvailableTasks(ITaskDAOConnection dao,String participantToken, HashMap parameters) throws AuthException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        try {
            parameters.put(TaskFetcher.FETCH_USER, credentials);
            String klass = (String) parameters.get(TaskFetcher.FETCH_CLASS_NAME);
            if (klass != null)
                parameters.put(TaskFetcher.FETCH_CLASS, TaskTypeMapper.getTaskClassFromStringName(klass));
            return dao.countAvailableTasks(parameters);
        } catch (Exception e) {
            _logger.error("Error while tasks list retrieval for user " + credentials.getUserID(), e);
            throw new RuntimeException(e);
        }
    }

    public Task[] getAvailableTasks(ITaskDAOConnection dao,String participantToken, HashMap parameters) throws AuthException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        try {
            parameters.put(TaskFetcher.FETCH_USER, credentials);
            String klass = (String) parameters.get(TaskFetcher.FETCH_CLASS_NAME);
            if (klass != null)
                parameters.put(TaskFetcher.FETCH_CLASS, TaskTypeMapper.getTaskClassFromStringName(klass));
            return dao.fetchAvailableTasks(parameters);
        } catch (Exception e) {
            _logger.error("Error while tasks list retrieval for user " + credentials.getUserID(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * Get the list of task ids to be deleted, and then delegate to the regular
     * delete method
     */
    public void deleteAll(ITaskDAOConnection dao,boolean fakeDelete, String subquery, String taskType, String participantToken)
            throws AuthException, UnavailableTaskException {
        Task[] tasks = null;
        if (taskType != null && taskType.length() != 0) {
            if (subquery == null || subquery.length() == 0)
                subquery = "";
            tasks = getAvailableTasks(dao,participantToken, taskType, subquery);
        } else {
            tasks = getTaskList(dao,participantToken);
        }
        int length = tasks.length;
        String[] ids = new String[length];
        for (int i = 0; i < length; i++) {
            _logger.info("Task:" + tasks[i].getClass() + ":" + tasks[i].getID() + " has been selected for deletion");
            ids[i] = tasks[i].getID();
        }
        if (fakeDelete) {
            _logger.info("Fake delete enabled. Not deleting any tasks");
        } else {
            delete(dao,ids, participantToken);
        }
    }

    public void skip(ITaskDAOConnection dao,String taskID, String participantToken) throws AuthException, UnavailableTaskException,
            InvalidTaskStateException, AccessDeniedException {
        UserRoles credentials = _authProvider.authenticate(participantToken);
        Task task = dao.fetchTaskIfExists(taskID);
        checkIsAvailable(taskID, task, credentials);
        if (task instanceof ITaskWithState) {
            ITaskWithState taskWithState = (ITaskWithState) task;
            taskWithState.setState(TaskState.OBSOLETE);
            dao.updateTask(task);
            dao.commit();
            if (_logger.isDebugEnabled())
                _logger.debug(credentials.getUserID() + " has skiped the Workflow Task " + task);
        } else {
            throw new UnavailableTaskException(credentials.getUserID() + " cannot skip Workflow Task " + task);
        }
    }
}
TOP

Related Classes of org.intalio.tempo.workflow.tms.server.TMSServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.