XalanJ2
  1. XalanJ2
  2. XALANJ-2264

Supporting xi:include (and other factory features) on xalan Process command-line

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.7.1
    • Fix Version/s: None
    • Component/s: Xalan-CmdLine
    • Labels:
      None
    • Environment:
      all
    • Xalan info:
      PatchAvailable

      Description

      The xi:include-awareness should be specifiable on the command-line.

      The default is on, since I think in the normal case it is useful.
      In the special case, the default has to be swiched off with -NIA.
      (Of course, it may be good keep the current behavior on default. I think, that the xi:include is not in wide use, so I want to risk to change the default. )
      In our project we want to include declarations in a programming language
      in the xslt-file, so the option -XSLIA.

        Issue Links

          Activity

          Hide
          Rudolf Weber added a comment -

          My patch

          Show
          Rudolf Weber added a comment - My patch
          Hide
          Brian Minchau added a comment -

          I wrote this to the xalan-dev mailing in response to Rudolf's post, before he created this issue:

          Rudolf,

          The DocumentBuilderFactory method setXIncludeAware() has existed since JAXP 1.3, which is what Xalan-J supports, so all in all I'm in favour of your patch, and with the new functionality, it just needs a little polishing.

          Your request looks perfectly reasonable to me. I had a look at the class javax.xml.parsers.DocumentBuilderFactory. Amoung its methods is this one:
          public void setXIncludeAware(boolean b);

          Already in use by Xalan code, in various places are these methods on the same class:
          public abstract void setAttribute(String s, Object o);
          public abstract void setFeature(String s, boolean b);
          public void setNamespaceAware(boolean b);
          public void setValidating(boolean b);

          It looks to me like having a command line option to call setXIncludeAware(boolean b) as you suggest is reasonable. However the current behavior is that the factory is not XInclude aware. So I don't agree that the default value should be true your variable
          boolean isXIncludeAware = true;

          Your patch has some messages in German (sehr interresant, aber es gibt viele andere Sprachen). Excuse my rusty German, but there are other languages so we would might use the English messages but leave the translation to the usual processes. However, the one area in you patch which really needs a message is this one:

          try

          { dfactory.setXIncludeAware(isXIncludeAware); }

          catch(UnsupportedOperationException uoe)
          {

          }

          If a DocumentBuilderFactory doesn't support this API it will throw the UnsupportedOperationException, yet your patch would silently absorb the exception. An informational message that the API is not supported would be useful when someone wants to use the new options but they don't seem to work. Class path issues can be tricky and they might not be using the factory they expect, so a message here would be very useful.

          Show
          Brian Minchau added a comment - I wrote this to the xalan-dev mailing in response to Rudolf's post, before he created this issue: Rudolf, The DocumentBuilderFactory method setXIncludeAware() has existed since JAXP 1.3, which is what Xalan-J supports, so all in all I'm in favour of your patch, and with the new functionality, it just needs a little polishing. Your request looks perfectly reasonable to me. I had a look at the class javax.xml.parsers.DocumentBuilderFactory. Amoung its methods is this one: public void setXIncludeAware(boolean b); Already in use by Xalan code, in various places are these methods on the same class: public abstract void setAttribute(String s, Object o); public abstract void setFeature(String s, boolean b); public void setNamespaceAware(boolean b); public void setValidating(boolean b); It looks to me like having a command line option to call setXIncludeAware(boolean b) as you suggest is reasonable. However the current behavior is that the factory is not XInclude aware. So I don't agree that the default value should be true your variable boolean isXIncludeAware = true; Your patch has some messages in German (sehr interresant, aber es gibt viele andere Sprachen). Excuse my rusty German, but there are other languages so we would might use the English messages but leave the translation to the usual processes. However, the one area in you patch which really needs a message is this one: try { dfactory.setXIncludeAware(isXIncludeAware); } catch(UnsupportedOperationException uoe) { } If a DocumentBuilderFactory doesn't support this API it will throw the UnsupportedOperationException, yet your patch would silently absorb the exception. An informational message that the API is not supported would be useful when someone wants to use the new options but they don't seem to work. Class path issues can be tricky and they might not be using the factory they expect, so a message here would be very useful.
          Hide
          Brian Minchau added a comment -

          There is a -FLAVOR command line options for the org.apache.xalan.xslt.Process main method.

          Right after this option is the flavor which can be one three values:
          "s2s" (the default value)
          "d2d"
          "th"

          The "d2d" option means that the stylesheet itself is a DOM. This block of code in
          org.apache.xalan.xslt.Process can be modified (as already seen in Rudolf Weber's patch:
          if (flavor.equals("d2d"))
          {

          // Parse in the xml data into a DOM
          DocumentBuilderFactory dfactory =
          DocumentBuilderFactory.newInstance();

          dfactory.setNamespaceAware(true);
          if (isSecureProcessing)
          {
          try

          { dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); }

          catch (ParserConfigurationException pce) {}
          }

          DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
          Node xslDOM = docBuilder.parse(new InputSource(xslFileName));

          stylesheet = tfactory.newTemplates(new DOMSource(xslDOM,
          xslFileName));
          }

          It already sets a feature and namespace awareness of the DocumentBuilderFactory.

          The else case of the block above, when the flavor is not "d2d" is more troublesome:
          else

          { // System.out.println("Calling newTemplates: "+xslFileName); stylesheet = tfactory.newTemplates(new StreamSource(xslFileName)); // System.out.println("Done calling newTemplates: "+xslFileName); }

          A StreamSource is presented to the TransformerFactory newTemplates method.

          Inside of that method is this code which can be exercised:
          ===============================================================
          javax.xml.parsers.SAXParserFactory factory =
          javax.xml.parsers.SAXParserFactory.newInstance();

          factory.setNamespaceAware(true);

          if (m_isSecureProcessing)
          {
          try

          { factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); }

          catch (org.xml.sax.SAXException se) {}
          }

          javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser();

          reader = jaxpParser.getXMLReader();
          ==============================================================

          So it looks like we need to transfer options parsed in Process to TransformerFactoryImpl

          The one method that does so is TransformerFactory.setFeature(String s, boolean b) but in
          currently only handles the 'secure' feature.

          Likewise this class might use TransformerIdentityImpl which also has a constructor that
          takes this 'secure' boolean. So some work is needed here to support other features.

          Besides XInclude, there are plenty of other factory features.
          I was thinking of something like a command line -XMLPARSER option, e.g.

          org.apache.xalan.xslt.Process -XMLPARSER setFeature(someNewFeature,true) -IN a.xml -XSL a.xsl

          or for XINclude use -XMLPARSER setXIncludeAware(true)

          Through Java reflection the method name could be obtained, and the args obtained.
          Other suggestions on a flexible API to set the factory features?

          This work is not so easy. Can anyone give a more comprehensive patch? One that
          sets the features of the DocumentBuilderFactory/SAXParserFactory in all situations?

          Show
          Brian Minchau added a comment - There is a -FLAVOR command line options for the org.apache.xalan.xslt.Process main method. Right after this option is the flavor which can be one three values: "s2s" (the default value) "d2d" "th" The "d2d" option means that the stylesheet itself is a DOM. This block of code in org.apache.xalan.xslt.Process can be modified (as already seen in Rudolf Weber's patch: if (flavor.equals("d2d")) { // Parse in the xml data into a DOM DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); dfactory.setNamespaceAware(true); if (isSecureProcessing) { try { dfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); } catch (ParserConfigurationException pce) {} } DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); Node xslDOM = docBuilder.parse(new InputSource(xslFileName)); stylesheet = tfactory.newTemplates(new DOMSource(xslDOM, xslFileName)); } It already sets a feature and namespace awareness of the DocumentBuilderFactory. The else case of the block above, when the flavor is not "d2d" is more troublesome: else { // System.out.println("Calling newTemplates: "+xslFileName); stylesheet = tfactory.newTemplates(new StreamSource(xslFileName)); // System.out.println("Done calling newTemplates: "+xslFileName); } A StreamSource is presented to the TransformerFactory newTemplates method. Inside of that method is this code which can be exercised: =============================================================== javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance(); factory.setNamespaceAware(true); if (m_isSecureProcessing) { try { factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); } catch (org.xml.sax.SAXException se) {} } javax.xml.parsers.SAXParser jaxpParser = factory.newSAXParser(); reader = jaxpParser.getXMLReader(); ============================================================== So it looks like we need to transfer options parsed in Process to TransformerFactoryImpl The one method that does so is TransformerFactory.setFeature(String s, boolean b) but in currently only handles the 'secure' feature. Likewise this class might use TransformerIdentityImpl which also has a constructor that takes this 'secure' boolean. So some work is needed here to support other features. Besides XInclude, there are plenty of other factory features. I was thinking of something like a command line -XMLPARSER option, e.g. org.apache.xalan.xslt.Process -XMLPARSER setFeature(someNewFeature,true) -IN a.xml -XSL a.xsl or for XINclude use -XMLPARSER setXIncludeAware(true) Through Java reflection the method name could be obtained, and the args obtained. Other suggestions on a flexible API to set the factory features? This work is not so easy. Can anyone give a more comprehensive patch? One that sets the features of the DocumentBuilderFactory/SAXParserFactory in all situations?
          Hide
          Brian Minchau added a comment -

          Oliver Paulus set this note to xalan-dev@xml.apache.org:

          Hello Brian,

          sounds good to me. In your case I can enable the fixup-base-uri [1]
          feature
          with the following parameter:

          -XMLPARSER
          setFeature("http://apache.org/xml/features/xinclude/fixup-base-uris",
          false)

          I have a question: Because the reflection code for this feature can be
          complicated you
          can also use the setFeature(string, boolean) method of e.g.
          DocumentBuilderFactory (I
          think it is defined in JAXP 1.3).
          The user can set the feature with a call like this: -XMLPARSER
          featurestring=true and
          you can call the setFeature method with this "feature-string" and true.
          The setXIncludeAware feature is new to JAXP 1.3 (I think) - I did not
          found it in JAXP 1.2
          spec. This feature can be set in xerces with the following feature too:
          [2].
          Perhaps you can add a new option only for the setXIncludeAware feature
          and another for
          all xml parser specific "feature strings"?
          I think this would be easier to implement comparing to the reflection
          code.
          What do you think?

          [1]
          http://xerces.apache.org/xerces2-j/features.html#xinclude.fixup-base-uri
          [2] http://xerces.apache.org/xerces2-j/features.html#xinclude

          Show
          Brian Minchau added a comment - Oliver Paulus set this note to xalan-dev@xml.apache.org: Hello Brian, sounds good to me. In your case I can enable the fixup-base-uri [1] feature with the following parameter: -XMLPARSER setFeature("http://apache.org/xml/features/xinclude/fixup-base-uris", false) I have a question: Because the reflection code for this feature can be complicated you can also use the setFeature(string, boolean) method of e.g. DocumentBuilderFactory (I think it is defined in JAXP 1.3). The user can set the feature with a call like this: -XMLPARSER featurestring=true and you can call the setFeature method with this "feature-string" and true. The setXIncludeAware feature is new to JAXP 1.3 (I think) - I did not found it in JAXP 1.2 spec. This feature can be set in xerces with the following feature too: [2] . Perhaps you can add a new option only for the setXIncludeAware feature and another for all xml parser specific "feature strings"? I think this would be easier to implement comparing to the reflection code. What do you think? [1] http://xerces.apache.org/xerces2-j/features.html#xinclude.fixup-base-uri [2] http://xerces.apache.org/xerces2-j/features.html#xinclude
          Hide
          Brian Minchau added a comment -

          I'm torn between:
          1) A single new option with an argument that specifies the method name and arguments to that method, to call the appropriate method with arguments on the underlying factory

          2) An option per method on the underlying factory, with an argument that specifiec only the arguments to that method.

          As Oliver pointed out setXIncludeAware might be new to JAXP 1.3, ... which might make option 1) more attractive.

          Please note that even if a user interface is designed, it still may be difficult to implement this for all the locations where such factories are used inside of Xalan-J.

          Show
          Brian Minchau added a comment - I'm torn between: 1) A single new option with an argument that specifies the method name and arguments to that method, to call the appropriate method with arguments on the underlying factory 2) An option per method on the underlying factory, with an argument that specifiec only the arguments to that method. As Oliver pointed out setXIncludeAware might be new to JAXP 1.3, ... which might make option 1) more attractive. Please note that even if a user interface is designed, it still may be difficult to implement this for all the locations where such factories are used inside of Xalan-J.
          Hide
          Brian Minchau added a comment -

          Comments on more possible complications:
          There are two factories, SAXParserFactory and DocumentBuilderFactory. SAXParserFactory has a setFeature() method and SAXParser has a setProperty() method, so things can be set on either the factory or the parser itself.

          Each has different ways of setting features. Each is created in different locations in Xalan, so one bit of code might have access to options from Process command line, but other locations in the code where a factory is created.

          The FLAVOR can be set on the Process command line and this also affects which factories are in use, and this could influence the validity of what is being set on the factory.

          Xalan might need a super-factory to create a factory, just so that the super-factory can set features on the factory in a consistent way (i.e. to set features based on the Process command line).

          Show
          Brian Minchau added a comment - Comments on more possible complications: There are two factories, SAXParserFactory and DocumentBuilderFactory. SAXParserFactory has a setFeature() method and SAXParser has a setProperty() method, so things can be set on either the factory or the parser itself. Each has different ways of setting features. Each is created in different locations in Xalan, so one bit of code might have access to options from Process command line, but other locations in the code where a factory is created. The FLAVOR can be set on the Process command line and this also affects which factories are in use, and this could influence the validity of what is being set on the factory. Xalan might need a super-factory to create a factory, just so that the super-factory can set features on the factory in a consistent way (i.e. to set features based on the Process command line).
          Hide
          Brian Minchau added a comment -

          Comments from JIRA bug Triage on Febrary 7, 2006:
          > Patch needs to be more robust to be taken into Xalan-J
          > Other parer options need to be considered, such as validating
          > This is the Process command. If someone really needs these APIs
          they can use JAXP APIs. Do we need to support every possibility
          through the Process command?
          > Entity resolver is the only real parser option that we handle
          with "Process"
          > This impacts the products APIs and documentation, so we are
          hesitant to do this.
          > Brian M. will look at existing parser options.

          Show
          Brian Minchau added a comment - Comments from JIRA bug Triage on Febrary 7, 2006: > Patch needs to be more robust to be taken into Xalan-J > Other parer options need to be considered, such as validating > This is the Process command. If someone really needs these APIs they can use JAXP APIs. Do we need to support every possibility through the Process command? > Entity resolver is the only real parser option that we handle with "Process" > This impacts the products APIs and documentation, so we are hesitant to do this. > Brian M. will look at existing parser options.
          Hide
          Brian Minchau added a comment -

          Per the JIRA meeting on Oct 16, 2005, the developers think that there are lots of parser options and that they don't all need to be replicated on the command line.

          One can write a Java program, create an instance of the XML parser with xi:include enabled and pass it into the transformer, so supporting this with the Process command-line is not high priority.

          Show
          Brian Minchau added a comment - Per the JIRA meeting on Oct 16, 2005, the developers think that there are lots of parser options and that they don't all need to be replicated on the command line. One can write a Java program, create an instance of the XML parser with xi:include enabled and pass it into the transformer, so supporting this with the Process command-line is not high priority.
          Hide
          Kenneth Stephen added a comment -

          I respectfully disagree with the decision you have made. Your decision is based on developer opinions. As an end-user of Xalan, it is very annoying and user-unfriendly to require a Java program to be written to support features that are based on an XML standard atleast three years old. Consider the case of a stylesheet which is either written in "pull" mode or is fundamentally nothing more than an HTML page with chunks of XSL embedded within it. It is really desirable in such cases that the large chunks of static html be relegated to "include" files, and that the stylesheet should just be able to include them. This greatly increases the maintainability of code. This is hardly an esoteric need. In my humble opinion, people arent demanding this feature more only because they dont know it already has been addressed and defined by the standards bodies as an appropriate solution.

          Please, please implement this feature.

          Show
          Kenneth Stephen added a comment - I respectfully disagree with the decision you have made. Your decision is based on developer opinions. As an end-user of Xalan, it is very annoying and user-unfriendly to require a Java program to be written to support features that are based on an XML standard atleast three years old. Consider the case of a stylesheet which is either written in "pull" mode or is fundamentally nothing more than an HTML page with chunks of XSL embedded within it. It is really desirable in such cases that the large chunks of static html be relegated to "include" files, and that the stylesheet should just be able to include them. This greatly increases the maintainability of code. This is hardly an esoteric need. In my humble opinion, people arent demanding this feature more only because they dont know it already has been addressed and defined by the standards bodies as an appropriate solution. Please, please implement this feature.
          Hide
          Michael Glavassevich added a comment -

          If you're using Xerces it's already possible to enable XInclude processing without writing any code. Overriding the default parser configuration [1] with org.apache.xerces.parsers.XIncludeParserConfiguration will do the trick.

          [1] http://xerces.apache.org/xerces2-j/faq-xni.html#faq-2

          Show
          Michael Glavassevich added a comment - If you're using Xerces it's already possible to enable XInclude processing without writing any code. Overriding the default parser configuration [1] with org.apache.xerces.parsers.XIncludeParserConfiguration will do the trick. [1] http://xerces.apache.org/xerces2-j/faq-xni.html#faq-2
          Hide
          Kenneth Stephen added a comment -

          Thanks for the info. I havent gotten this to work yet. This may be due to a bug in the IBM JRE - which I have to use. I am working the issue with IBM support

          Show
          Kenneth Stephen added a comment - Thanks for the info. I havent gotten this to work yet. This may be due to a bug in the IBM JRE - which I have to use. I am working the issue with IBM support

            People

            • Assignee:
              Unassigned
              Reporter:
              Rudolf Weber
            • Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:

                Development