private void registerObserverGateway(String gatewayClassName) {
    ObserverGateway gateway;
    try {
      Class gatewayClass = Class.forName(gatewayClassName);

      // If the class has a getInstance() method, call that method rather than
      // calling a constructor (& thus instantiating 2 instances of the class)
      try {
        Method instMethod = gatewayClass.getDeclaredMethod("getInstance");
        gateway = (ObserverGateway) instMethod.invoke(null);
      }

      // no getInstance(), so just create a plain new instance
      catch (NoSuchMethodException nsme) {
        gateway = (ObserverGateway) gatewayClass.newInstance();
      }

      if (gateway != null) _engine.registerObserverGateway(gateway);
      else _log.warn("Error registering external ObserverGateway '{}'.", gatewayClassName);
    } catch (ClassNotFoundException e) {
      _log.warn("Unable to locate external ObserverGateway '" + gatewayClassName + "'.", e);
    } catch (InstantiationException ie) {
      _log.warn(
          "Unable to instantiate external ObserverGateway '"
              + gatewayClassName
              + "'. Perhaps it is missing a no-argument constructor.",
          ie);
    } catch (YAWLException ye) {
      _log.warn("Failed to register external ObserverGateway '" + gatewayClassName + "'.", ye);
    } catch (Exception e) {
      _log.warn("Unable to instantiate external ObserverGateway '" + gatewayClassName + "'.", e);
    }
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {

    OutputStreamWriter outputWriter = ServletUtils.prepareResponse(response);
    StringBuilder output = new StringBuilder();
    output.append("<response>");
    output.append(processPostQuery(request));
    output.append("</response>");
    if (_engine.enginePersistenceFailure()) {
      _log.fatal("************************************************************");
      _log.fatal("A failure has occurred whilst persisting workflow state to the");
      _log.fatal("database. Check the status of the database connection defined");
      _log.fatal("for the YAWL service, and restart the YAWL web application.");
      _log.fatal("Further information may be found within the Tomcat log files.");
      _log.fatal("************************************************************");
      response.sendError(500, "Database persistence failure detected");
    }
    outputWriter.write(output.toString());
    outputWriter.flush();
    outputWriter.close();
    // todo find out how to provide a meaningful 500 message in the format of  a fault message.
  }
  public void init() throws ServletException {
    int maxWaitSeconds = 5; // a default

    try {
      ServletContext context = getServletContext();

      // init engine reference
      _engine = (EngineGateway) context.getAttribute("engine");
      if (_engine == null) {
        Class<? extends YEngine> engineImpl = getEngineImplClass();
        boolean persist = getBooleanFromContext("EnablePersistence");
        boolean enableHbnStats = getBooleanFromContext("EnableHibernateStatisticsGathering");
        _engine = new EngineGatewayImpl(engineImpl, persist, enableHbnStats);
        _engine.setActualFilePath(context.getRealPath("/"));
        context.setAttribute("engine", _engine);
      }

      // set flag to disable logging (only if false) - enabled with persistence by
      // default
      String logStr = context.getInitParameter("EnableLogging");
      if ((logStr != null) && logStr.equalsIgnoreCase("false")) {
        _engine.disableLogging();
      }

      // add the reference to the default worklist
      _engine.setDefaultWorklist(context.getInitParameter("DefaultWorklist"));

      // set flag for generic admin account (only if set to true)
      String allowAdminID = context.getInitParameter("AllowGenericAdminID");
      if ((allowAdminID != null) && allowAdminID.equalsIgnoreCase("true")) {
        _engine.setAllowAdminID(true);
      }

      // set the path to external db gateway plugin classes (if any)
      String pluginPath = context.getInitParameter("ExternalPluginsPath");
      ExternalDBGatewayFactory.setExternalPaths(pluginPath);
      PredicateEvaluatorFactory.setExternalPaths(pluginPath);

      // override the max time that initialisation events wait for between
      // final engine init and server start completion
      int maxWait =
          StringUtil.strToInt(context.getInitParameter("InitialisationAnnouncementTimeout"), -1);
      if (maxWait >= 0) maxWaitSeconds = maxWait;

      // read the current version properties
      _engine.initBuildProperties(
          context.getResourceAsStream("/WEB-INF/classes/version.properties"));

      // init any 3rd party observer gateways
      String gatewayStr = context.getInitParameter("ObserverGateway");
      if (gatewayStr != null) {

        // split multiples on the semi-colon (if any)
        for (String gateway : gatewayStr.split(";")) {
          registerObserverGateway(gateway);
        }
      }
    } catch (YPersistenceException e) {
      _log.fatal("Failure to initialise runtime (persistence failure)", e);
      throw new UnavailableException("Persistence failure");
    }

    if (_engine != null) {
      _engine.notifyServletInitialisationComplete(maxWaitSeconds);
    } else {
      _log.fatal(
          "Failed to initialise Engine (unspecified failure). Please "
              + "consult the logs for details");
      throw new UnavailableException("Unspecified engine failure");
    }
  }
  private String processPostQuery(HttpServletRequest request) {
    StringBuilder msg = new StringBuilder();
    String sessionHandle = request.getParameter("sessionHandle");
    String action = request.getParameter("action");
    String workItemID = request.getParameter("workItemID");
    String specIdentifier = request.getParameter("specidentifier");
    String specVersion = request.getParameter("specversion");
    String specURI = request.getParameter("specuri");
    String taskID = request.getParameter("taskID");

    try {
      debug(request, "Post");

      if (action != null) {
        if (action.equals("checkConnection")) {
          msg.append(_engine.checkConnection(sessionHandle));
        } else if (action.equals("connect")) {
          String userID = request.getParameter("userid");
          String password = request.getParameter("password");
          int interval = request.getSession().getMaxInactiveInterval();
          msg.append(_engine.connect(userID, password, interval));
        } else if ("disconnect".equals(action)) {
          msg.append(_engine.disconnect(sessionHandle));
        } else if (action.equals("checkout")) {
          msg.append(_engine.startWorkItem(workItemID, sessionHandle));
        } else if (action.equals("checkin")) {
          String data = request.getParameter("data");
          String logPredicate = request.getParameter("logPredicate");
          msg.append(
              _engine.completeWorkItem(workItemID, data, logPredicate, false, sessionHandle));
        } else if (action.equals("rejectAnnouncedEnabledTask")) {
          msg.append(_engine.rejectAnnouncedEnabledTask(workItemID, sessionHandle));
        } else if (action.equals("launchCase")) {
          YSpecificationID specID = new YSpecificationID(specIdentifier, specVersion, specURI);
          URI completionObserver = getCompletionObserver(request);
          String caseParams = request.getParameter("caseParams");
          String logDataStr = request.getParameter("logData");
          String mSecStr = request.getParameter("mSec");
          String startStr = request.getParameter("start");
          String waitStr = request.getParameter("wait");
          if (mSecStr != null) {
            msg.append(
                _engine.launchCase(
                    specID,
                    caseParams,
                    completionObserver,
                    logDataStr,
                    StringUtil.strToLong(mSecStr, 0),
                    sessionHandle));
          } else if (startStr != null) {
            long time = StringUtil.strToLong(startStr, 0);
            Date date = time > 0 ? new Date(time) : new Date();
            msg.append(
                _engine.launchCase(
                    specID, caseParams, completionObserver, logDataStr, date, sessionHandle));
          } else if (waitStr != null) {
            msg.append(
                _engine.launchCase(
                    specID,
                    caseParams,
                    completionObserver,
                    logDataStr,
                    StringUtil.strToDuration(waitStr),
                    sessionHandle));
          } else
            msg.append(
                _engine.launchCase(
                    specID, caseParams, completionObserver, logDataStr, sessionHandle));
        } else if (action.equals("cancelCase")) {
          String caseID = request.getParameter("caseID");
          msg.append(_engine.cancelCase(caseID, sessionHandle));
        } else if (action.equals("getWorkItem")) {
          msg.append(_engine.getWorkItem(workItemID, sessionHandle));
        } else if (action.equals("startOne")) {
          String userID = request.getParameter("user");
          msg.append(_engine.startWorkItem(userID, sessionHandle));
        } else if (action.equals("getLiveItems")) {
          msg.append(_engine.describeAllWorkItems(sessionHandle));
        } else if (action.equals("getAllRunningCases")) {
          msg.append(_engine.getAllRunningCases(sessionHandle));
        } else if (action.equals("getWorkItemsWithIdentifier")) {
          String idType = request.getParameter("idType");
          String id = request.getParameter("id");
          msg.append(_engine.getWorkItemsWithIdentifier(idType, id, sessionHandle));
        } else if (action.equals("getWorkItemsForService")) {
          String serviceURI = request.getParameter("serviceuri");
          msg.append(_engine.getWorkItemsForService(serviceURI, sessionHandle));
        } else if (action.equals("taskInformation")) {
          YSpecificationID specID = new YSpecificationID(specIdentifier, specVersion, specURI);
          msg.append(_engine.getTaskInformation(specID, taskID, sessionHandle));
        } else if (action.equals("getMITaskAttributes")) {
          YSpecificationID specID = new YSpecificationID(specIdentifier, specVersion, specURI);
          msg.append(_engine.getMITaskAttributes(specID, taskID, sessionHandle));
        } else if (action.equals("getResourcingSpecs")) {
          YSpecificationID specID = new YSpecificationID(specIdentifier, specVersion, specURI);
          msg.append(_engine.getResourcingSpecs(specID, taskID, sessionHandle));
        } else if (action.equals("checkIsAdmin")) {
          msg.append(_engine.checkConnectionForAdmin(sessionHandle));
        } else if (action.equals("checkAddInstanceEligible")) {
          msg.append(_engine.checkElegibilityToAddInstances(workItemID, sessionHandle));
        } else if (action.equals("getSpecificationPrototypesList")) {
          msg.append(_engine.getSpecificationList(sessionHandle));
        } else if (action.equals("getSpecification")) {
          YSpecificationID specID = new YSpecificationID(specIdentifier, specVersion, specURI);
          msg.append(_engine.getProcessDefinition(specID, sessionHandle));
        } else if (action.equals("getSpecificationData")) {
          YSpecificationID specID = new YSpecificationID(specIdentifier, specVersion, specURI);
          msg.append(_engine.getSpecificationData(specID, sessionHandle));
        } else if (action.equals("getSpecificationDataSchema")) {
          YSpecificationID specID = new YSpecificationID(specIdentifier, specVersion, specURI);
          msg.append(_engine.getSpecificationDataSchema(specID, sessionHandle));
        } else if (action.equals("getCasesForSpecification")) {
          YSpecificationID specID = new YSpecificationID(specIdentifier, specVersion, specURI);
          msg.append(_engine.getCasesForSpecification(specID, sessionHandle));
        } else if (action.equals("getSpecificationForCase")) {
          String caseID = request.getParameter("caseID");
          msg.append(_engine.getSpecificationForCase(caseID, sessionHandle));
        } else if (action.equals("getSpecificationIDForCase")) {
          String caseID = request.getParameter("caseID");
          msg.append(_engine.getSpecificationIDForCase(caseID, sessionHandle));
        } else if (action.equals("getCaseState")) {
          String caseID = request.getParameter("caseID");
          msg.append(_engine.getCaseState(caseID, sessionHandle));
        } else if (action.equals("getCaseData")) {
          String caseID = request.getParameter("caseID");
          msg.append(_engine.getCaseData(caseID, sessionHandle));
        } else if (action.equals("getChildren")) {
          msg.append(_engine.getChildrenOfWorkItem(workItemID, sessionHandle));
        } else if (action.equals("getWorkItemExpiryTime")) {
          msg.append(_engine.getWorkItemExpiryTime(workItemID, sessionHandle));
        } else if (action.equals("getCaseInstanceSummary")) {
          msg.append(_engine.getCaseInstanceSummary(sessionHandle));
        } else if (action.equals("getWorkItemInstanceSummary")) {
          String caseID = request.getParameter("caseID");
          msg.append(_engine.getWorkItemInstanceSummary(caseID, sessionHandle));
        } else if (action.equals("getParameterInstanceSummary")) {
          String caseID = request.getParameter("caseID");
          msg.append(_engine.getParameterInstanceSummary(caseID, workItemID, sessionHandle));
        } else if (action.equals("createInstance")) {
          String paramValueForMICreation = request.getParameter("paramValueForMICreation");
          msg.append(_engine.createNewInstance(workItemID, paramValueForMICreation, sessionHandle));
        } else if (action.equals("suspend")) {
          msg.append(_engine.suspendWorkItem(workItemID, sessionHandle));
        } else if (action.equals("rollback")) {
          msg.append(_engine.rollbackWorkItem(workItemID, sessionHandle));
        } else if (action.equals("unsuspend")) {
          msg.append(_engine.unsuspendWorkItem(workItemID, sessionHandle));
        } else if (action.equals("skip")) {
          msg.append(_engine.skipWorkItem(workItemID, sessionHandle));
        } else if (action.equals("getStartingDataSnapshot")) {
          msg.append(_engine.getStartingDataSnapshot(workItemID, sessionHandle));
        }
      } // action is null
      else if (request.getRequestURI().endsWith("ib")) {
        msg.append(_engine.getAvailableWorkItemIDs(sessionHandle));
      } else if (request.getRequestURI().contains("workItem")) {
        msg.append(
            _engine.getWorkItemOptions(
                workItemID, request.getRequestURL().toString(), sessionHandle));
      } else _log.error("Interface B called with null action.");
    } catch (RemoteException e) {
      _log.error("Remote Exception in Interface B with action: " + action, e);
    }
    _log.debug("InterfaceB_EngineBasedServer::doPost() result = {}", msg);
    return msg.toString();
  }
 public void destroy() {
   _engine.shutdown();
   super.destroy();
 }