@Override
  public WorkflowEvent getEvent(String id) {

    WorkflowRequestHandler requestHandler =
        WorkflowServiceDataHolder.getInstance().getRequestHandler(id);
    if (requestHandler != null) {
      WorkflowEvent event = new WorkflowEvent();
      event.setEventId(requestHandler.getEventId());
      event.setEventFriendlyName(requestHandler.getFriendlyName());
      event.setEventDescription(requestHandler.getDescription());
      event.setEventCategory(requestHandler.getCategory());
      if (requestHandler.getParamDefinitions() != null) {
        Parameter[] parameters = new Parameter[requestHandler.getParamDefinitions().size()];
        int i = 0;
        for (Map.Entry<String, String> paramEntry :
            requestHandler.getParamDefinitions().entrySet()) {
          Parameter parameter = new Parameter();
          parameter.setParamName(paramEntry.getKey());
          parameter.setParamValue(paramEntry.getValue());
          parameters[i] = parameter;
          i++;
        }
        event.setParameters(parameters);
      }
      return event;
    }
    return null;
  }
  @Override
  public List<WorkflowEvent> listWorkflowEvents() {

    List<WorkflowRequestHandler> workflowRequestHandlers =
        WorkflowServiceDataHolder.getInstance().listRequestHandlers();
    List<WorkflowEvent> eventList = new ArrayList<>();
    if (workflowRequestHandlers != null) {
      for (WorkflowRequestHandler requestHandler : workflowRequestHandlers) {
        WorkflowEvent event = new WorkflowEvent();
        event.setEventId(requestHandler.getEventId());
        event.setEventFriendlyName(requestHandler.getFriendlyName());
        event.setEventDescription(requestHandler.getDescription());
        event.setEventCategory(requestHandler.getCategory());
        // note: parameters are not set at here in list operation. It's set only at get operation
        if (requestHandler.getParamDefinitions() != null) {
          Parameter[] parameterDTOs = new Parameter[requestHandler.getParamDefinitions().size()];
          int i = 0;
          for (Map.Entry<String, String> paramEntry :
              requestHandler.getParamDefinitions().entrySet()) {
            Parameter parameterDTO = new Parameter();
            parameterDTO.setParamName(paramEntry.getKey());
            parameterDTO.setParamValue(paramEntry.getValue());
            parameterDTOs[i] = parameterDTO;
            i++;
          }
          event.setParameters(parameterDTOs);
        }
        eventList.add(event);
      }
    }
    return eventList;
  }
 @Override
 public Template getTemplate(String templateId) throws WorkflowException {
   AbstractTemplate abstractTemplate =
       WorkflowServiceDataHolder.getInstance().getTemplates().get(templateId);
   Template template = null;
   if (abstractTemplate != null) {
     template = new Template();
     template.setTemplateId(abstractTemplate.getTemplateId());
     template.setName(abstractTemplate.getName());
     template.setDescription(abstractTemplate.getDescription());
     template.setParametersMetaData(abstractTemplate.getParametersMetaData());
   }
   return template;
 }
  @Override
  public List<Association> listAllAssociations() throws WorkflowException {

    List<Association> associations = workflowDAO.listAssociations();
    for (Iterator<Association> iterator = associations.iterator(); iterator.hasNext(); ) {
      Association association = iterator.next();
      WorkflowRequestHandler requestHandler =
          WorkflowServiceDataHolder.getInstance().getRequestHandler(association.getEventId());
      if (requestHandler != null) {
        association.setEventName(requestHandler.getFriendlyName());
      } else {
        // invalid reference, probably event id is renamed or removed
        iterator.remove();
      }
    }
    return associations;
  }
  @Override
  public void addWorkflow(Workflow workflow, List<Parameter> parameterList, int tenantId)
      throws WorkflowException {

    // TODO:Workspace Name may contain spaces , so we need to remove spaces and prepare process for
    // that
    Parameter workflowNameParameter =
        new Parameter(
            workflow.getWorkflowId(),
            WFConstant.ParameterName.WORKFLOW_NAME,
            workflow.getWorkflowName(),
            WFConstant.ParameterName.WORKFLOW_NAME,
            WFConstant.ParameterHolder.WORKFLOW_IMPL);

    if (!parameterList.contains(workflowNameParameter)) {
      parameterList.add(workflowNameParameter);
    } else {
      workflowNameParameter = parameterList.get(parameterList.indexOf(workflowNameParameter));
    }
    if (!workflowNameParameter.getParamValue().equals(workflow.getWorkflowName())) {
      workflowNameParameter.setParamValue(workflow.getWorkflowName());
      // TODO:Since the user has changed the workflow name, we have to undeploy bpel package that is
      // already
      // deployed using previous workflow name.
    }

    AbstractWorkflow abstractWorkflow =
        WorkflowServiceDataHolder.getInstance()
            .getWorkflowImpls()
            .get(workflow.getTemplateId())
            .get(workflow.getWorkflowImplId());
    // deploying the template
    abstractWorkflow.deploy(parameterList);

    // add workflow to the database
    if (workflowDAO.getWorkflow(workflow.getWorkflowId()) == null) {
      workflowDAO.addWorkflow(workflow, tenantId);
      WorkflowManagementUtil.createAppRole(
          StringUtils.deleteWhitespace(workflow.getWorkflowName()));
    } else {
      workflowDAO.removeWorkflowParams(workflow.getWorkflowId());
      workflowDAO.updateWorkflow(workflow);
    }
    workflowDAO.addWorkflowParams(parameterList, workflow.getWorkflowId());
  }
 @Override
 public List<WorkflowImpl> listWorkflowImpls(String templateId) throws WorkflowException {
   Map<String, AbstractWorkflow> abstractWorkflowMap =
       WorkflowServiceDataHolder.getInstance().getWorkflowImpls().get(templateId);
   List<WorkflowImpl> workflowList = new ArrayList<WorkflowImpl>();
   if (abstractWorkflowMap != null) {
     List<AbstractWorkflow> abstractWorkflowList = new ArrayList<>(abstractWorkflowMap.values());
     for (AbstractWorkflow abstractWorkflow : abstractWorkflowList) {
       WorkflowImpl workflow = new WorkflowImpl();
       workflow.setWorkflowImplId(abstractWorkflow.getWorkflowImplId());
       workflow.setWorkflowImplName(abstractWorkflow.getWorkflowImplName());
       workflow.setParametersMetaData(abstractWorkflow.getParametersMetaData());
       workflow.setTemplateId(abstractWorkflow.getTemplateId());
       workflowList.add(workflow);
     }
   }
   return workflowList;
 }
 @Override
 public List<Template> listTemplates() throws WorkflowException {
   Map<String, AbstractTemplate> templateMap =
       WorkflowServiceDataHolder.getInstance().getTemplates();
   List<AbstractTemplate> templateList = new ArrayList<>(templateMap.values());
   List<Template> templates = new ArrayList<Template>();
   if (templateList != null) {
     for (AbstractTemplate abstractTemplate : templateList) {
       Template template = new Template();
       template.setTemplateId(abstractTemplate.getTemplateId());
       template.setName(abstractTemplate.getName());
       template.setDescription(abstractTemplate.getDescription());
       template.setParametersMetaData(abstractTemplate.getParametersMetaData());
       templates.add(template);
     }
   }
   return templates;
 }
  @Override
  public void deleteWorkflowRequest(String requestId) throws WorkflowException {
    String loggedUser = CarbonContext.getThreadLocalCarbonContext().getUsername();
    String createdUser = workflowRequestDAO.retrieveCreatedUserOfRequest(requestId);
    if (!loggedUser.equals(createdUser)) {
      throw new WorkflowException("User not authorized to delete this request");
    }
    List<WorkflowRequestDeleteListener> workflowRequestDeleteListenerList =
        WorkflowServiceDataHolder.getInstance().getWorkflowRequestDeleteListenerList();

    WorkflowRequest workflowRequest = new WorkflowRequest();
    workflowRequest.setRequestId(requestId);
    workflowRequest.setCreatedBy(createdUser);

    for (WorkflowRequestDeleteListener workflowRequestDeleteListener :
        workflowRequestDeleteListenerList) {
      try {
        workflowRequestDeleteListener.doPreDeleteWorkflowRequest(workflowRequest);
      } catch (WorkflowException e) {
        throw new WorkflowException(
            "Error occurred while calling doPreDeleteWorkflowRequest in WorkflowRequestDeleteListener ,"
                + workflowRequestDeleteListener.getClass().getName(),
            e);
      }
    }

    workflowRequestDAO.updateStatusOfRequest(requestId, WorkflowRequestStatus.DELETED.toString());
    workflowRequestAssociationDAO.updateStatusOfRelationshipsOfPendingRequest(
        requestId, WFConstant.HT_STATE_SKIPPED);
    requestEntityRelationshipDAO.deleteRelationshipsOfRequest(requestId);

    for (WorkflowRequestDeleteListener workflowRequestDeleteListener :
        workflowRequestDeleteListenerList) {
      try {
        workflowRequestDeleteListener.doPostDeleteWorkflowRequest(workflowRequest);
      } catch (WorkflowException e) {
        throw new WorkflowException(
            "Error occurred while calling doPostDeleteWorkflowRequest in WorkflowRequestDeleteListener ,"
                + workflowRequestDeleteListener.getClass().getName(),
            e);
      }
    }
  }
  @Override
  public WorkflowImpl getWorkflowImpl(String templateId, String workflowImplId)
      throws WorkflowException {

    WorkflowImpl workflowImpl = null;
    Map<String, AbstractWorkflow> abstractWorkflowMap =
        WorkflowServiceDataHolder.getInstance().getWorkflowImpls().get(templateId);
    if (abstractWorkflowMap != null) {
      AbstractWorkflow tmp = abstractWorkflowMap.get(workflowImplId);
      if (tmp != null) {
        workflowImpl = new WorkflowImpl();
        workflowImpl.setWorkflowImplId(tmp.getWorkflowImplId());
        workflowImpl.setWorkflowImplName(tmp.getWorkflowImplName());
        workflowImpl.setParametersMetaData(tmp.getParametersMetaData());
        workflowImpl.setTemplateId(tmp.getTemplateId());
      }
    }
    return workflowImpl;
  }