package org.infoglue.cms.webservices; import java.util.Map; import org.apache.log4j.Logger; import org.infoglue.cms.applications.workflowtool.function.InfoglueFunction; import org.infoglue.cms.controllers.kernel.impl.simple.LanguageController; import org.infoglue.cms.controllers.kernel.impl.simple.UserControllerProxy; import org.infoglue.cms.controllers.kernel.impl.simple.WorkflowController; import org.infoglue.cms.entities.mydesktop.WorkflowVO; import org.infoglue.cms.exception.SystemException; import org.infoglue.cms.security.InfoGluePrincipal; import org.infoglue.deliver.util.webservices.DynamicWebserviceSerializer; import com.opensymphony.workflow.WorkflowException; /** * This service is used for creating workflows from an external application. */ public class RemoteWorkflowServiceImpl extends RemoteInfoGlueService { /** * The class logger. */ private final static Logger logger = Logger.getLogger(RemoteWorkflowServiceImpl.class.getName()); /** * The principal executing the workflow. */ private InfoGluePrincipal principal; /** * The inputs to the workflow. */ private Map inputs; /** * Default constructor. */ public RemoteWorkflowServiceImpl() { super(); } /** * Creates the specified workflow running as the specified principal. * To determine if the workflow executed successfully, the state of the workflow is checked. * A terminated workflow is interpreted as a failure, meaning that all workflows that could * be started from an external application, should terminate directly if an error occurs. * * @param principalName the name of the principal that should execute the workflow. Must have permission to create the workflow. * @param languageId the language to use when executing the workflow. * @param workflowName the name of the workflow. * @param inputsArray the inputs to the workflow. * @return true if the workflow executed sucessfully; false otherwise. */ public Boolean start(final String principalName, final Integer languageId, final String workflowName, final Object[] inputsArray, final Object[] ppp) { try { final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer(); initializePrincipal(principalName, workflowName); initializeInputs((Map) serializer.deserialize(inputsArray), languageId); logger.debug("start(" + principalName + "," + workflowName + "," + languageId + "," + inputs + ")"); final WorkflowVO workflowVO = WorkflowController.getController().initializeWorkflow(principal, workflowName, 0, inputs); if(hasTerminated(workflowVO)) { logger.debug("The workflow has terminated."); return Boolean.FALSE; } } catch(Throwable t) { logger.error("Error:" + t.getMessage(), t); return Boolean.FALSE; } updateCaches(); return Boolean.TRUE; } /** * Invokes an action on the specified workflow as the specified principal. * * @param principalName the name of the principal that should execute the workflow. Must have permission to create the workflow. * @param languageId the language to use when executing the workflow. * @param workflowName the name of the workflow. * @param inputsArray the inputs to the workflow. * @return true if the workflow executed sucessfully; false otherwise. */ public Boolean invokeAction(final String principalName, final Integer languageId, final Long workflowId, final Integer actionId, final Object[] inputsArray, final Object[] ppp) { try { final DynamicWebserviceSerializer serializer = new DynamicWebserviceSerializer(); initializeInputs((Map) serializer.deserialize(inputsArray), languageId); logger.debug("start(" + principalName + "," + workflowId + "," + actionId + "," + languageId + "," + inputs + ")"); final WorkflowVO workflowVO = WorkflowController.getController().invokeAction(principal, workflowId.longValue(), actionId.intValue(), inputs); if(hasTerminated(workflowVO)) { logger.debug("The workflow has terminated."); return Boolean.FALSE; } } catch(Throwable t) { logger.error("Error:" + t.getMessage(), t); return Boolean.FALSE; } updateCaches(); return Boolean.TRUE; } /** * Returns true if the workflow has terminated; false otherwise. * * @param workflowVO the workflow. * @return true if the workflow has terminated; false otherwise. */ private boolean hasTerminated(final WorkflowVO workflowVO) throws WorkflowException { return WorkflowController.getController().hasTerminated(principal, workflowVO.getIdAsPrimitive()); } /** * Initializes the inputs to the workflow. * * @param callerInputs the inputs sent in from the caller of this service. * @param languageId the locale to use when running the workflow. */ private void initializeInputs(final Map callerInputs, final Integer languageId) throws SystemException { inputs = callerInputs; inputs.put(InfoglueFunction.PRINCIPAL_PARAMETER, principal); inputs.put(InfoglueFunction.LOCALE_PARAMETER, LanguageController.getController().getLocaleWithId(languageId)); } /** * Checks if the principal exists and if the principal is allowed to create the workflow. * * @param userName the name of the user. * @param workflowName the name of the workflow to create. * @throws SystemException if the principal doesn't exists or doesn't have permission to create the workflow. */ private void initializePrincipal(final String userName, final String workflowName) throws SystemException { try { principal = UserControllerProxy.getController().getUser(userName); } catch(SystemException e) { throw e; } catch(Exception e) { throw new SystemException(e); } if(principal == null) { throw new SystemException("No such principal [" + userName + "]."); } if(!WorkflowController.getController().getIsAccessApproved(workflowName, principal)) { throw new SystemException("The principal [" + userName + "] is not allowed to create the [" + workflowName + "] workflow."); } } }