/*
 * ProcessTemplateCreateAndStartInstance.java
 *
 * Created on December 15, 2002, 3:34 AM
 */

/**
 *
 * @authors  Sreenivas Bandaru, John McDonald
 */

////////////////////////////////////////////////////////////////////////////////
//  This program sends an XML message to create and start a process instance  //
//  of the CreditRequest ProcessTemplate.                                     //
//                                                                            //
//  Note: Before executing this program, the FDL of CreditRequest sample      //
//  shipped along with the product should be imported into the runtime.       //
//                                                                            //
//  Usage:                                                                    //
//  java ProcessTemplateCreateAndStartInstance <XMLInputQueue> <MQWF QMGR>    //
//                     <ReplyQMGR> <ReplyQueue>                               //
//                                                                            //
//  You must specify <XMLInputQueue> and <MQWF QMGR>                          //
//  If you wish to receive a reply you must also specify <ReplyQMGR> and      //
//  <ReplyQueue>.  NOTE that you must ensure that <ReplyQMGR> and <ReplyQueue>//
//  both are in existance.                                                    //
//                                                                            //
//  Eg:                                                                       //
//  java ProcessTemplateCreateAndStartInstance EXEXMLINPUTQ  FMCQM1           //
//                                                                            //
//  java ProcessTemplateCreateAndStartInstance EXEXMLINPUTQ  FMCQM1           //
//      FMCQM1 REPLYQUEUE                                                     //
//                                                                            //
//  THIS is simply an illustration.  Use this as a base to build a general    //
//  Purpose XMLProcessStarter for your installation.                          //
////////////////////////////////////////////////////////////////////////////////



import java.io.*;
import java.util.*;
import com.ibm.mq.*;
public class ProcessTemplateCreateAndStartInstance {

  private static final String INAMETAG = "<ProcInstName>";
  private static final String STATETAG = "<ProcInstState>";
  private static final String TIMETAG  = "<LastStateChangeTime>";
  private static final String ENDTAG = "</";

  /** Creates a new instance of ProcessTemplateCreateAndStartInstance */
  public ProcessTemplateCreateAndStartInstance() {
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
    try {
      String WorkFlowQMGR = null;
      String UPESQueue = null;
      String ReplyQMGR = null;
      String ReplyQueue = null;
      boolean responseRequired = false;
      if ( args.length != 4 &&
            args.length != 2) {
        System.out.println("Paramters are: Queue, QueueManager, ReplyQMGR, ReplyQueue");
        System.out.println("Note that ReplyQMGR and ReplyQueue are OPTIONAL " +
            "And if one is specified BOTH must be specified");
        System.exit(-1);
      }
      UPESQueue = args[0];
      WorkFlowQMGR = args[1];
      if (args.length > 2) {
        responseRequired = true;
        ReplyQMGR = args[2];
        ReplyQueue = args[3];
      }
      System.out.println("WorkFlowQMGR: " + WorkFlowQMGR);
      System.out.println("UPESQueue: " + UPESQueue);
      if (responseRequired) {
        System.out.println("Response is required.  Qmgr is " + ReplyQMGR);
        System.out.println("                       Queue is " + ReplyQueue);
      }
      MQQueueManager qmgr = new MQQueueManager(WorkFlowQMGR ) ;
      System.out.println("Connected to QMGR " + WorkFlowQMGR);

      int openOptions = MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING |
                        MQC.MQOO_SET_IDENTITY_CONTEXT;

      MQQueue queue = qmgr.accessQueue(UPESQueue, openOptions,
                                        null, null, "ADMIN");
      String DEFAULT_MQUSERID = "ADMIN";
      MQMessage inMsg = new MQMessage();
      String MessageInXMLFmt;
      inMsg.userId = DEFAULT_MQUSERID;
      if (responseRequired) {
        inMsg.replyToQueueManagerName = ReplyQMGR;
        inMsg.replyToQueueName = ReplyQueue;
      }
      MessageInXMLFmt = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "<!-- This document is to create and start a process template  -->"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "<WfMessage>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "   <WfMessageHeader>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "      <ResponseRequired>Yes</ResponseRequired>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "      <UserContext>I want this data back</UserContext>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "   </WfMessageHeader>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "   <ProcessTemplateCreateAndStartInstance>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "      <ProcTemplName>CreditRequest</ProcTemplName>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "      <ProcInstName>MyCreditRequest1</ProcInstName>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "      <KeepName>false</KeepName>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "      <ProcInstInputData>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "         <PersonInfo>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "            <FirstName>Sreenivas</FirstName>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "            <LastName>Bandaru</LastName>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "         </PersonInfo>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "      </ProcInstInputData>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "   </ProcessTemplateCreateAndStartInstance>"  + "\n";
      MessageInXMLFmt = MessageInXMLFmt + "</WfMessage>"  + "\n";


      inMsg.writeString(MessageInXMLFmt);
      MQPutMessageOptions pmo = new MQPutMessageOptions();
      pmo.options = MQC.MQPMO_SET_IDENTITY_CONTEXT;
      queue.put(inMsg, pmo);
      System.out.println("Start message sent");
      qmgr.disconnect() ;
      if (responseRequired) {
        MQQueueManager replyQM = new MQQueueManager(ReplyQMGR);
        System.out.println("ReplyQMGR accessed");
        int ReplyOpenOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_INQUIRE ;
        MQQueue replyQueue = replyQM.accessQueue(ReplyQueue,
                           ReplyOpenOptions, null, null, null);
        System.out.println("ReplyQueue accessed");
        MQMessage currentMessage = new MQMessage();
        MQGetMessageOptions gmo = new MQGetMessageOptions( );
        gmo.options      = MQC.MQGMO_WAIT;
        gmo.matchOptions = MQC.MQMO_MATCH_CORREL_ID;
        gmo.waitInterval = -1;
        replyQueue.get( currentMessage, gmo );
        byte buffer[] = new byte[ currentMessage.getDataLength() ];
        currentMessage.readFully( buffer, 0, currentMessage.getDataLength() );
        String curMsg = new String(buffer);
        if ( curMsg.indexOf("<Exception>") != -1 )
          System.out.println("An Error has occurred during Process Start\n" +
                curMsg);
        else {
          int inamePos = curMsg.indexOf(INAMETAG) + INAMETAG.length() ;
          int statePos = curMsg.indexOf(STATETAG) + STATETAG.length();
          int timePos  = curMsg.indexOf(TIMETAG) + TIMETAG.length();

          String PIName = new String( curMsg.substring( inamePos ,
                          curMsg.indexOf(ENDTAG,inamePos) ) );
          String PIState = new String( curMsg.substring( statePos,
                          curMsg.indexOf(ENDTAG,statePos) ) );
          String PITime = new String( curMsg.substring( timePos,
                          curMsg.indexOf(ENDTAG,timePos) ) );
          System.out.println("Instance '" + PIName +
            "' is in the " + PIState + " state as of " + PITime);
        }

        replyQM.disconnect();
      }

    }
    catch(MQException ex){
        System.out.println("MQ Error - Reason code :" + ex.reasonCode);
    }
    catch (Exception e){
        System.out.println("Error : " + e);
    }
  } // end main

} // end CLASS
