Accessing Process Name, Container Name and Step Name within XSL - Forum - Technology Partner - Progress Community

Accessing Process Name, Container Name and Step Name within XSL

 Forum

Accessing Process Name, Container Name and Step Name within XSL

  • I would like to access the current process name, step name and/or container name from within my XSL. I am aware of the MessageExtensions and HeaderExtensions functions, however I don't think these information are available in the message header or message itself. I know they are available in the tracking message but I'm trying to perform a XSL transformation on the actual message, not a tracking message.

    Other suggestions are welcome. If I could pass them in as XSL parameters, that's fine by me too. However I would prefer not to hard-code the parameter in the Stylesheet parameters of the Transformation Service's Runtime Parameters definition, it would be better if I could read that from somewhere.

    Thanks,

    Wendy

  • These are in the ProcessContext which is passed to the service.  I think the only way to get them from a Stylesheet is to use the JavaScript parameter on the XSLT service and copy the values either to StyleSheet Parameters (which you didn't want to do), or to XQMessage headers.   Then you could use the 'getHeader' XSL extension to see them.

    In the JavaScript, you have access to the XQServiceContext, and the XQMessage object.   You can just do something like:

    //Copy the Process Name into the header of the Message.
    XQMessage.setHeader('XSL-ProcessName', XQServiceContext.getProcessContext().getName())

    ,

  • Thanks for your response.

    How would I use Javascript to copy the values to the stylesheet parameters? I didn't want to hardcode the process name by specifying"processName=myProcessABC" in the stylesheet parameters run time parameters field, but if I could read them from Javascript, that would work fo rme.

    Thanks,

    Wendy

  • (Copied from older documentation on the ESB --- I could not find this in the online help for Sonic ESB XML Transformation)

    The basic use of the transformation service is to apply a stylesheet to a message to transform the format of the content. The parameter stylesheet URL specifies the default stylesheet to apply to the message part index and the stylesheet parameters. Optionally, you can apply a different stylesheet to a different message part with a different stylesheet parameter.

    For advanced transformations, you can override the default stylesheet and have a behavior based on message content and headers (that is, apply a rules-based selection of the  transformation). A rules-based transformation selection provides flexibility in the choice of transformation based on message contents and header values.

    The key component of this feature is a JavaScript RuleEvaluator that evaluates transformation rules written in the JavaScript scripting language (using the Rhino JavaScript Engine). The JavaScript rules govern the choice of transformation to be applied on the input message. The transformation rule contains multiple conditions; all defined conditionsare applied to every request. The rule uses accessor objects to retrieve header and content values from the input message and determine which transformation to apply to that request.


    Rules-based processing offers the ability to choose between transformations based on any of the following:

    • Runtime parameters
    • Message XML content (using XPath APIs)
    • Message header values
    • Calls to external Java classes or adapters


    The transformation rule is defined in a JavaScript file, the URL of which is specified by the configuration parameter ruleFile. In all cases, the JavaScript rule file must have a
    function, rule( ). This function can return one of the following:

    • null — No transformation is applied to the incoming message
    • An ArrayList containing the stylesheetURL — The stylesheet is applied on the first part (index = 0) of the incoming message
    • An ArrayList containing the stylesheetURL and a msgPart index (in that order) — The stylesheet is applied on the specified part of the incoming message
    • An ArrayList containing the stylesheetURL, a msgPart index, and a HashMap of stylesheet parameters (in that order) —
      The stylesheet parameters are passed to the XSLT processor and the stylesheet is applied on the specified part of the incoming message)

    The ruleFile containing the rule( ) function is an optional service configuration parameter. When the ruleFile is not specified, the service uses the default stylesheetURL, msgPartIndex (default value 0) and stylesheetParams (default value "") configuration parameters.

    Here is an example of the rule( ) function that returns an ArrayList object containing the stylesheetURL, the msgPart index, and a HashMap of stylesheet
    parameters.

    function rule()
    {
      JMSPriority = XQ_getProperty("JMSPriority", -1);
      if (JMSPriority > 4 )
      {
        myArray = new java.util.ArrayList();
        //Create a Params HashMap and add name value pairs in it.
        paramsHashMap = new java.util.HashMap();
        paramsHashMap.put("amount","1000");
        paramsHashMap.put("deliveryDate","10/21/01");
        //Create MsgPartIndex Integer
        msgPart = new java.lang.Integer(0);
        myArray.add("sonicfs:///stylesheets/priority.xsl");
        myArray.add(msgPart);
        myArray.add(paramsHashMap);
        return myArray;
      }
      else
         return null;
    }

  • I just realized that the container name is not available in the XQProcessContext, though process name and step name are. Do you kno where I might go to get the container name from within a javascript file?

    Thanks.

  • The Container name is available even when not in a Process, so it is on the XQServiceContext (and the subclass, XQInitContext).  It is available as a Parameter.  Something like:

     // Get the Container Name from the XQServiceContext
    XQServiceContext.getParameters().getParameter(XQConstants.PARAM_CONTAINER_NAME, XQConstants.PARAM_STRING)

    //(NOTE:in JavaScript, you may need to qualify the entire Packages.com.sonicsw.xq.XQConstants.)
    //

    See the doc on:

    com.sonicsw.xq
    Interface XQContext

    Subinterfaces:   XQInitContext, XQServiceContext

    XQParametersgetParameters()
              Returns parameters required for initialization of a service.

    com.sonicsw.xq
    Interface XQParameters

    java.lang.StringgetParameter(java.lang.String name, int type)
              Get a parameter as a String based on its name and type.

    com.sonicsw.xq
    Interface XQConstants

    static java.lang.StringPARAM_CONTAINER_NAME
              XQParameters key value used to retrieve the MF container name from the service environment provided in both the XQInitContext and the XQServiceContext.
    static intPARAM_STRING
              Parameter type used to retrieve an XQParameter value as a STRING.

  • Without fully qualifying XQConstants, I am getting a undefined error. However when I fully qualify it, I get the following error. Any ideas how to resolve this?

    This is what I have in my javascript:

    XQServiceContext.getParameters().getParameter(com.sonicsw.xq.XQConstants.PARAM_CONTAINER_NAME, com.sonicsw.xq.XQConstants.PARAM_STRING);

    com.sonicsw.xq.XQServiceException:  (Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.) (Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.))) (Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.) (Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.)) (Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.) (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.)))
         at com.sonicsw.xq.service.common.RulesProcessor.evaluate(RulesProcessor.java:305)
         at com.sonicsw.xq.service.common.RulesProcessor.processRules(RulesProcessor.java:133)
         at com.sonicsw.xq.service.xform.Xformer.processRules(Xformer.java:166)
         at com.sonicsw.xq.service.xform.TransformationService.service(TransformationService.java:86)
         at com.sonicsw.xqimpl.service.debug.DebugServiceInterceptor.intercept(DebugServiceInterceptor.java:118)
         at com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper.intercept(XQServiceChain.java:481)
         at com.sonicsw.xqimpl.service.XQServiceChain$XQInterceptorServiceWrapper.service(XQServiceChain.java:470)
         at com.sonicsw.xqimpl.service.XQServiceChain.service(XQServiceChain.java:151)
         at com.sonicsw.xqimpl.service.ServiceMessageHandler.callService(ServiceMessageHandler.java:413)
         at com.sonicsw.xqimpl.service.ServiceMessageHandler.handleMessage(ServiceMessageHandler.java:182)
         at com.sonicsw.xqimpl.service.ProcessMessageHandler.doHandleMessage(ProcessMessageHandler.java:308)
         at com.sonicsw.xqimpl.service.ProcessMessageHandler.handleMessage(ProcessMessageHandler.java:90)
         at com.sonicsw.xqimpl.service.XQDispatcher.onMessage(XQDispatcher.java:422)
         at com.sonicsw.xqimpl.endpoint.container.EndpointContextContainer.onMessage(EndpointContextContainer.java:84)
         at com.sonicsw.xq.connector.jms.JMSEndpoint$JMSEndpointListener.onMessage(JMSEndpoint.java:570)
         at progress.message.jimpl.Session.deliver(Session.java:2998)
         at progress.message.jimpl.Session.run(Session.java:2390)
         at progress.message.jimpl.Session$SessionThread.run(Session.java:2775)
    Caused by: com.sonicsw.xq.rules.EvaluatorException: Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.) (Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.)) (Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.) (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.))
         at com.sonicsw.xq.service.common.ScriptEvaluator.evaluateRule(ScriptEvaluator.java:327)
         at com.sonicsw.xq.service.common.RulesProcessor.evaluate(RulesProcessor.java:296)
         ... 17 more
    Caused by: com.sonicsw.xq.rules.EvaluatorException: Desired evaluation could not be performed: JavaScript Error: Internal Error: ReferenceError: "com" is not defined. (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.) (JavaScript Error: Internal Error: ReferenceError: "com" is not defined.)
         at com.sonicsw.xq.service.common.ScriptEvaluator.evaluateRule(ScriptEvaluator.java:305)
         ... 18 more
    Caused by: com.ibm.bsf.BSFException: JavaScript Error: Internal Error: ReferenceError: "com" is not defined.
         at com.ibm.bsf.engines.javascript.JavaScriptEngine.handleError(JavaScriptEngine.java:182)
         at com.ibm.bsf.engines.javascript.JavaScriptEngine.eval(JavaScriptEngine.java:87)
         at com.sonicsw.xq.service.common.ScriptEvaluator.evaluateRule(ScriptEvaluator.java:301)
         ... 18 more
  • You can always just get the values and use those directly

    I think this was recently on the Sonic Forum... my mistake for not remembering... but in JavaScript you need to use "Packages." as the prefix (so "Packages.com.sonicws.xq.XQConstants").

    See the related post:  /javascript:;

  • I have had good luck with the following as well.  This will allow you to import all classes within a particular pkg and not have to fully qualify your name every time, if that is desirable to you.

    importPackage(Packages.foo.bar.name)

    function whatever() {

         name = new Name();

    }

    where Name is a class within package foo.bar.name.

    HTH.