You are viewing a plain text version of this content. The canonical link for it is here.
Posted to soap-dev@ws.apache.org by ne...@locus.apache.org on 2000/11/07 03:05:20 UTC

cvs commit: xml-soap/java/src/org/apache/soap/transport EnvelopeEditor.java EnvelopeEditorAdapter.java EnvelopeEditorFactory.java FilterTransport.java

neyama      00/11/06 18:05:19

  Modified:    java/src/org/apache/soap/server/http
                        MessageRouterServlet.java RPCRouterServlet.java
                        ServerHTTPUtils.java
  Added:       java/src/org/apache/soap/transport EnvelopeEditor.java
                        EnvelopeEditorAdapter.java
                        EnvelopeEditorFactory.java FilterTransport.java
  Log:
  Transport hook extension.
  
  ------
  (Figures are omitted. See the archive of the soap-dev mailng list)
  The Fig.1 illustrates the current message flow between SOAP client
  and server in the Apache SOAP 2.0 and the Fig.2 shows our proposal.
  Vertical lines are timelines of functions and horizontal lines are
  message flows between functions.
  
  The proposed change in the Fig.2 is to add XML-in/XML-out hooks
  (EnvelopeEditors in the chart below) between a network transport and
  SOAP message handlers where a string format of XML message flows.  The
  advantage of this hook is flexibility that a programmer can add any
  functions that modify raw SOAP messages in any sense, such as sign a
  message, transcode a format with XSLT processor, and so on.  One of
  the disadvantage of this approach is performance because there is a
  possibility of calling a XML parser multiple times in each added
  function.  At this time, we would like to take the flexibility.
  
  There is another change proposed in the Fig.2  The current SOAP 2.0
  implementation invokes a hard-coded XML parser.  We would like to
  propose to make is replaceable with any other XML parsers.  This gives
  programmers a freedom of parser choice.  Another advantage is that
  this may be able to improve perfomance by eliminating multiple parser
  calls because this is regarded as another kind of XML-in/DOM-out hook
  and extension can be implemented as a part of parser (liaison)
  functions.
  
  Revision  Changes    Path
  1.4       +140 -2    xml-soap/java/src/org/apache/soap/server/http/MessageRouterServlet.java
  
  Index: MessageRouterServlet.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/http/MessageRouterServlet.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- MessageRouterServlet.java	2000/10/17 12:03:41	1.3
  +++ MessageRouterServlet.java	2000/11/07 02:05:14	1.4
  @@ -70,13 +70,90 @@
   import org.apache.soap.util.* ;
   import org.apache.soap.util.xml.* ;
   
  +/*
  + * Begin Transport-Hook-Extension
  + */
  +import org.apache.soap.transport.EnvelopeEditor ;
  +import org.apache.soap.transport.EnvelopeEditorFactory ;
  +/*
  + * End Transport-Hook-Extension
  + */
  +
   /**
    * This servlet routes messages to the approriate listener method.
    *
    * @author Sanjiva Weerawarana <sa...@watson.ibm.com>
    */
   public class MessageRouterServlet extends HttpServlet {
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +    // Unlike client-side, EnvelopeEditorFactory, which creates an
  +    // EnvelopeEditor, and XMLParser are specified by servlet
  +    // init-parameters at the server-side.  For example, you may add
  +    // the following description to web.xml with Tomcat.
  +    // <servlet>
  +    //  <servlet-name>MessageRouterServlet</servlet-name>
  +    //    <servlet-class>org.apache.soap.server.http.MessageRouterServlet</servlet-class>
  +    //    <init-param>
  +    //      <param-name>EnvelopeEditor</param-name>
  +    //      <param-value>MyEnvelopeEditorFactory</param-value>
  +    //    </init-param>
  +    //    <init-param>
  +    //      <param-name>XMLParser</param-name>
  +    //      <param-value>samples.messaging.SampleXMLParserLiaison</param-value>
  +    //    </init-param>
  +    // </servlet>
  +    private static final String ENVELOPE_EDITOR_FACTORY = "EnvelopeEditorFactory" ;
  +    private static final String XML_PARSER = "XMLParser" ;
  +
  +    private EnvelopeEditor editor = null;
  +    private XMLParserLiaison xpl = new XercesParserLiaison();
  +    public void init() {
  +        if (System.getProperties().getProperty("org.apache.soap.TransportHookExtension") != null) {
  +            EnvelopeEditorFactory factory ;
  +            if ((factory = (EnvelopeEditorFactory)createObject(ENVELOPE_EDITOR_FACTORY)) != null) {
  +                try {
  +                    Properties props = new Properties() ;
  +                    Enumeration enum = getServletConfig().getInitParameterNames() ;
  +                    while(enum.hasMoreElements()) {
  +                        String name = (String)enum.nextElement() ;
  +                        if (!ENVELOPE_EDITOR_FACTORY.equals(name) &&
  +                            !XML_PARSER.equals(name))
  +                            props.setProperty(name, getServletConfig().getInitParameter(name)) ;
  +                    }
  +                    editor = factory.create(props) ;
  +                } catch (SOAPException e) {
  +                    System.err.println("WARNING: Can't create editor: " + e.getMessage());
  +                }
  +            }
  +            if ((xpl = (XMLParserLiaison)createObject(XML_PARSER)) == null)
  +                xpl = new XercesParserLiaison() ;
  +        }
  +    }
   
  +    private Object createObject(String name) {
  +            String value ;
  +            if ((value = getServletConfig().getInitParameter(name)) == null) {
  +                System.err.println(getClass().getName() + " cannot get a init parameter '" + name) ;
  +                return null ;
  +            }
  +            System.err.println(getClass().getName() + " god a init parameter '" + name + "'=" + value) ;
  +        try {
  +            return Class.forName(value).newInstance() ;
  +        } catch (ClassNotFoundException e) {
  +            System.err.println("WARNING: Can't find class named '" + value + "'");
  +        } catch (InstantiationException e) {
  +            System.err.println("WARNING: Can't instantiate class '" + value + "'");
  +        } catch (IllegalAccessException e) {
  +            System.err.println("WARNING: Can't access constructor of class '" + value + "'");
  +        }
  +        return null ;
  +    }
  +    /*
  +     * End Transport-Hook-Extension
  +     */
  +
     public void doGet (HttpServletRequest req, HttpServletResponse res)
          throws ServletException, IOException {
       PrintWriter out = res.getWriter ();
  @@ -89,6 +166,31 @@
     }
   
     public void doPost (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +      // Invokes EnvelopeEditor (editIncoming)
  +      Reader in ;
  +      int contentLength ;
  +      if (System.getProperties().getProperty("org.apache.soap.TransportHookExtension") != null && editor != null) {
  +          try {
  +              StringWriter sout = new StringWriter() ;
  +              editor.editIncoming(req.getReader(), sout) ;
  +              String xml = sout.getBuffer().toString() ;
  +              in = new StringReader(xml) ;
  +              contentLength = xml.length() ;
  +          } catch (SOAPException e) {
  +              e.printStackTrace() ;
  +              // SOAPException must be handled here.
  +              return ;
  +          }
  +      } else {
  +          in = req.getReader() ;
  +          contentLength = req.getContentLength() ;
  +      }
  +    /*
  +     * End Transport-Hook-Extension
  +     */
   
       ServletConfig config = getServletConfig();
       ServletContext context = config.getServletContext ();
  @@ -106,7 +208,21 @@
   
       try {
         // get the envelope
  -      Envelope msgEnv = ServerHTTPUtils.readEnvelopeFromRequest (req, res);
  +      /*
  +       * Begin Transport-Hook-Extension
  +       */
  +      //Envelope msgEnv = ServerHTTPUtils.readEnvelopeFromRequest (req, res);
  +
  +      // Generate Envelope after the incoming message is translated by
  +      // EnvelopeEditor
  +      // Note: XMLParser that is specified by init-param isused in
  +      // this process.
  +      Envelope msgEnv = ServerHTTPUtils.readEnvelopeFromRequest (xpl, req.getContentType(), contentLength, in, res);
  +      if (msgEnv == null)
  +          return ;
  +      /*
  +       * End Transport-Hook-Extension
  +       */
   
         // get the namespace URI and and localpart of the first child
         // element of the body of the envelope
  @@ -154,7 +270,8 @@
   
         Fault fault = new Fault (e);
         fault.setFaultActorURI (req.getRequestURI ());
  -	dd.buildFaultRouter().notifyListeners(fault, e);
  +      if (dd != null)
  +          dd.buildFaultRouter().notifyListeners(fault, e);
   
   	//determine the correct return HTTP status
   	if (fault.getFaultCode().startsWith (Constants.FAULT_CODE_CLIENT)) {
  @@ -171,6 +288,27 @@
         out.close ();
       }
       
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +    // Translates response from server application with EnvelopeEditor
  +    if (System.getProperties().getProperty("org.apache.soap.TransportHookExtension") != null && editor != null) {
  +        in = new InputStreamReader(new ByteArrayInputStream(bytes.toByteArray())) ;
  +        Writer tout = new OutputStreamWriter(bytes = new ByteArrayOutputStream()) ;
  +        try {
  +            editor.editOutgoing(in, tout) ;
  +        } catch (SOAPException e) {
  +            e.printStackTrace() ;
  +            // SOAPException must be handled here.
  +            return ;
  +        }
  +        tout.flush() ;
  +        tout.close() ;
  +    }
  +    /*
  +     * End Transport-Hook-Extension
  +     */
  +
       // ship it out
       res.setStatus (status);
       res.setContentType (Constants.HEADERVAL_CONTENT_TYPE_UTF8);
  
  
  
  1.8       +140 -3    xml-soap/java/src/org/apache/soap/server/http/RPCRouterServlet.java
  
  Index: RPCRouterServlet.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/http/RPCRouterServlet.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- RPCRouterServlet.java	2000/11/07 00:35:00	1.7
  +++ RPCRouterServlet.java	2000/11/07 02:05:14	1.8
  @@ -70,6 +70,14 @@
   import org.apache.soap.util.* ;
   import org.apache.soap.util.xml.* ;
   
  +/*
  + * Begin Transport-Hook-Extension
  + */
  +import org.apache.soap.transport.EnvelopeEditor ;
  +import org.apache.soap.transport.EnvelopeEditorFactory ;
  +/*
  + * End Transport-Hook-Extension
  + */
   
   /**
    * This servlet routes RPC requests to the intended method of
  @@ -82,6 +90,74 @@
    * @author Kevin J. Mitchell (kevin.mitchell@xmls.com)
    */
   public class RPCRouterServlet extends HttpServlet {
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +    // Unlike client-side, EnvelopeEditorFactory, which creates an
  +    // EnvelopeEditor, and XMLParser are specified by servlet
  +    // init-parameters at the server-side.  For example, you may add
  +    // the following description to web.xml with Tomcat.
  +    // <servlet>
  +    //  <servlet-name>MessageRouterServlet</servlet-name>
  +    //    <servlet-class>org.apache.soap.server.http.MessageRouterServlet</servlet-class>
  +    //    <init-param>
  +    //      <param-name>EnvelopeEditor</param-name>
  +    //      <param-value>MyEnvelopeEditorFactory</param-value>
  +    //    </init-param>
  +    //    <init-param>
  +    //      <param-name>XMLParser</param-name>
  +    //      <param-value>samples.messaging.SampleXMLParserLiaison</param-value>
  +    //    </init-param>
  +    // </servlet>
  +    private static final String ENVELOPE_EDITOR_FACTORY = "EnvelopeEditorFactory" ;
  +    private static final String XML_PARSER = "XMLParser" ;
  +
  +    private EnvelopeEditor editor = null;
  +    private XMLParserLiaison xpl = new XercesParserLiaison();
  +    public void init() {
  +        if (System.getProperties().getProperty("org.apache.soap.TransportHookExtension") != null) {
  +            EnvelopeEditorFactory factory ;
  +            if ((factory = (EnvelopeEditorFactory)createObject(ENVELOPE_EDITOR_FACTORY)) != null) {
  +                try {
  +                    Properties props = new Properties() ;
  +                    Enumeration enum = getServletConfig().getInitParameterNames() ;
  +                    while(enum.hasMoreElements()) {
  +                        String name = (String)enum.nextElement() ;
  +                        if (!ENVELOPE_EDITOR_FACTORY.equals(name) &&
  +                            !XML_PARSER.equals(name))
  +                            props.setProperty(name, getServletConfig().getInitParameter(name)) ;
  +                    }
  +                    editor = factory.create(props) ;
  +                } catch (SOAPException e) {
  +                    System.err.println("WARNING: Can't create editor: " + e.getMessage());
  +                }
  +            }
  +            if ((xpl = (XMLParserLiaison)createObject(XML_PARSER)) == null)
  +                xpl = new XercesParserLiaison() ;
  +        }
  +    }
  +
  +    private Object createObject(String name) {
  +            String value ;
  +            if ((value = getServletConfig().getInitParameter(name)) == null) {
  +                System.err.println(getClass().getName() + " cannot get a init parameter '" + name) ;
  +                return null ;
  +            }
  +            System.err.println(getClass().getName() + " god a init parameter '" + name + "'=" + value) ;
  +        try {
  +            return Class.forName(value).newInstance() ;
  +        } catch (ClassNotFoundException e) {
  +            System.err.println("WARNING: Can't find class named '" + value + "'");
  +        } catch (InstantiationException e) {
  +            System.err.println("WARNING: Can't instantiate class '" + value + "'");
  +        } catch (IllegalAccessException e) {
  +            System.err.println("WARNING: Can't access constructor of class '" + value + "'");
  +        }
  +        return null ;
  +    }
  +    /*
  +     * End Transport-Hook-Extension
  +     */
   
     public void doGet (HttpServletRequest req, HttpServletResponse res)
          throws ServletException, IOException {
  @@ -94,8 +170,33 @@
       out.println ("HTTP POST to talk to me.</p></body></html>");
     }
   
  -  public void doPost (HttpServletRequest req, HttpServletResponse res) 
  +  public void doPost (HttpServletRequest req, HttpServletResponse res)
          throws ServletException, IOException {
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +      // Invokes EnvelopeEditor (editIncoming)
  +      Reader in ;
  +      int contentLength ;
  +      if (System.getProperties().getProperty("org.apache.soap.TransportHookExtension") != null && editor != null) {
  +          try {
  +              StringWriter sout = new StringWriter() ;
  +              editor.editIncoming(req.getReader(), sout) ;
  +              String xml = sout.getBuffer().toString() ;
  +              in = new StringReader(xml) ;
  +              contentLength = xml.length() ;
  +          } catch (SOAPException e) {
  +              e.printStackTrace() ;
  +              // SOAPException must be handled here.
  +              return ;
  +          }
  +      } else {
  +          in = req.getReader() ;
  +          contentLength = req.getContentLength() ;
  +      }
  +    /*
  +     * End Transport-Hook-Extension
  +     */
   
       ServletConfig config = getServletConfig();
       ServletContext context = config.getServletContext ();
  @@ -114,7 +215,21 @@
   
         // extract the call
         try {
  -        Envelope callEnv = ServerHTTPUtils.readEnvelopeFromRequest (req, res);
  +      /*
  +       * Begin Transport-Hook-Extension
  +       */
  +        //Envelope callEnv = ServerHTTPUtils.readEnvelopeFromRequest (req, res);
  +
  +      // Generate Envelope after the incoming message is translated by
  +      // EnvelopeEditor
  +      // Note: XMLParser that is specified by init-param isused in
  +      // this process.
  +      Envelope callEnv = ServerHTTPUtils.readEnvelopeFromRequest (xpl, req.getContentType(), contentLength, in, res);
  +      if (callEnv == null)
  +          return ;
  +      /*
  +       * End Transport-Hook-Extension
  +       */
           call = RPCRouter.extractCallFromEnvelope (serviceManager, callEnv);
           targetID = call.getTargetObjectURI ();
   	fullTargetID = call.getFullTargetObjectURI ();
  @@ -163,7 +278,8 @@
   
         Fault fault = new Fault (e);
         fault.setFaultActorURI (req.getRequestURI ());
  -	dd.buildFaultRouter().notifyListeners(fault, e);
  +      if (dd != null)
  +          dd.buildFaultRouter().notifyListeners(fault, e);
   
   	//determine the correct return HTTP status
   	if (fault.getFaultCode().startsWith (Constants.FAULT_CODE_CLIENT)) {
  @@ -199,6 +315,27 @@
   
       // close the temporary writer to flush stuff out
       out.close ();
  +
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +    // Translates response from server application with EnvelopeEditor
  +    if (System.getProperties().getProperty("org.apache.soap.TransportHookExtension") != null && editor != null) {
  +        in = new InputStreamReader(new ByteArrayInputStream(bytes.toByteArray())) ;
  +        Writer tout = new OutputStreamWriter(bytes = new ByteArrayOutputStream()) ;
  +        try {
  +            editor.editOutgoing(in, tout) ;
  +        } catch (SOAPException e) {
  +            e.printStackTrace() ;
  +            // SOAPException must be handled here.
  +            return ;
  +        }
  +        tout.flush() ;
  +        tout.close() ;
  +    }
  +    /*
  +     * End Transport-Hook-Extension
  +     */
   
       // ship the stuff out
       res.setContentType (Constants.HEADERVAL_CONTENT_TYPE_UTF8);
  
  
  
  1.6       +34 -5     xml-soap/java/src/org/apache/soap/server/http/ServerHTTPUtils.java
  
  Index: ServerHTTPUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/server/http/ServerHTTPUtils.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ServerHTTPUtils.java	2000/11/07 00:35:00	1.5
  +++ ServerHTTPUtils.java	2000/11/07 02:05:15	1.6
  @@ -111,11 +111,28 @@
      * @exception IOException if something fails while sending an
      *            error response
      */
  -  public static Envelope readEnvelopeFromRequest (HttpServletRequest req,
  +  static Envelope readEnvelopeFromRequest (
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +                                           //HttpServletRequest req,
  +                                           XMLParserLiaison xpl,
  +                                           String contentType,
  +                                           int contentLength,
  +                                           Reader requestReader,
  +    /*
  +     * End Transport-Hook-Extension
  +     */
                                              HttpServletResponse res) 
          throws SOAPException, IOException {
  -    String contentType = req.getContentType ();
  -    int contentLength = req.getContentLength ();
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +    //String contentType = req.getContentType ();
  +    //int contentLength = req.getContentLength ();
  +    /*
  +     * End Transport-Hook-Extension
  +     */
   
       if ((contentType == null) ||
           !contentType.equals (Constants.HEADERVAL_CONTENT_TYPE)) {
  @@ -128,7 +145,13 @@
       }
   
       // read the stuff
  -    Reader requestReader = req.getReader ();
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +    //Reader requestReader = req.getReader ();
  +    /*
  +     * End Transport-Hook-Extension
  +     */
       char[] payload = new char[contentLength];
       int    offset = 0;
       int    bytesRead = 0;
  @@ -141,7 +164,13 @@
       }
   
       // Parse the stuff
  -    XMLParserLiaison xpl = new XercesParserLiaison ();
  +    /*
  +     * Begin Transport-Hook-Extension
  +     */
  +    //XMLParserLiaison xpl = new XercesParserLiaison ();
  +    /*
  +     * End Transport-Hook-Extension
  +     */
       Document doc = xpl.read ("SOAP Envelope", new CharArrayReader (payload));
       if (doc == null) {
         throw new SOAPException (Constants.FAULT_CODE_CLIENT, "parsing error");
  
  
  
  1.1                  xml-soap/java/src/org/apache/soap/transport/EnvelopeEditor.java
  
  Index: EnvelopeEditor.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2000, International
   * Business Machines, Inc., http://www.apache.org.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * Begin Transport-Hook-Extension
   */
  package org.apache.soap.transport ;
  
  import java.io.Reader ;
  import java.io.Writer ;
  import org.apache.soap.SOAPException ;
  
  /**
   * @author Ryo Neyama (neyama@jp.ibm.com)
   */
  public interface EnvelopeEditor {
      // Callback mehtod to translate incoming messages
      public void editIncoming(Reader in, Writer out) throws SOAPException ;
      // Callback mehtod to translate outgoing messages
      public void editOutgoing(Reader in, Writer out) throws SOAPException ;
  }
  /*
   * End Transport-Hook-Extension
   */
  
  
  
  1.1                  xml-soap/java/src/org/apache/soap/transport/EnvelopeEditorAdapter.java
  
  Index: EnvelopeEditorAdapter.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2000, International
   * Business Machines, Inc., http://www.apache.org.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * Begin Transport-Hook-Extension
   */
  package org.apache.soap.transport ;
  
  import java.io.Reader ;
  import java.io.Writer ;
  import java.io.IOException ;
  import org.apache.soap.SOAPException ;
  import org.apache.soap.Constants ;
  
  /**
   * @author Ryo Neyama (neyama@jp.ibm.com)
   */
  public class EnvelopeEditorAdapter implements EnvelopeEditor {
      private static final int BUF_SIZE = 4096 ;
      public void editIncoming(Reader in, Writer out) throws SOAPException {
          passThrough(in, out) ;
      }
  
      public void editOutgoing(Reader in, Writer out) throws SOAPException {
          passThrough(in, out) ;
      }
  
      protected void passThrough(Reader in, Writer out) throws SOAPException {
          try {
              char[] data = new char[BUF_SIZE] ;
              int len ;
              READ_LOOP:
              while (true) {
                  int off = 0;
                  do {
                      if ((len = in.read(data, off, data.length-off)) == -1) {
                          out.write(data, 0, off) ;
                          break READ_LOOP ;
                      }
                  } while ((off += len) < data.length) ;
                  out.write(data) ;
              }
          } catch (IOException e) {
              throw new SOAPException(Constants.FAULT_CODE_SERVER, e.getMessage(), e) ;
          } finally {
              try { out.flush() ; } catch (IOException e) {
                  throw new SOAPException(Constants.FAULT_CODE_SERVER, e.getMessage(), e) ;
              }
          }
      }
  }
  /*
   * End Transport-Hook-Extension
   */
  
  
  
  1.1                  xml-soap/java/src/org/apache/soap/transport/EnvelopeEditorFactory.java
  
  Index: EnvelopeEditorFactory.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2000, International
   * Business Machines, Inc., http://www.apache.org.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * Begin Transport-Hook-Extension
   */
  package org.apache.soap.transport ;
  
  import java.util.Properties ;
  import org.apache.soap.SOAPException ;
  
  /**
   * @author Ryo Neyama (neyama@jp.ibm.com)
   */
  public interface EnvelopeEditorFactory {
      public EnvelopeEditor create(Properties props) throws SOAPException ;
  }
  /*
   * End Transport-Hook-Extension
   */
  
  
  
  1.1                  xml-soap/java/src/org/apache/soap/transport/FilterTransport.java
  
  Index: FilterTransport.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2000 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "SOAP" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2000, International
   * Business Machines, Inc., http://www.apache.org.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * Begin Transport-Hook-Extension
   */
  package org.apache.soap.transport ;
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import org.w3c.dom.*;
  import org.apache.soap.util.net.*;
  import org.apache.soap.util.xml.*;
  import org.apache.soap.*;
  import org.apache.soap.encoding.*;
  import org.apache.soap.transport.*;
  
  /**
   * <code>SOAPHTTPConnection</code> is an implementation of the
   * <code>SOAPTransport</code> interface for <em>HTTP</em>.
   *
   * @author Matthew J. Duftler (duftler@us.ibm.com)
   * @author Sanjiva Weerawarana (sanjiva@watson.ibm.com)
   * @author Ryo Neyama (neyama@jp.ibm.com)
   */
  public class FilterTransport implements SOAPTransport
  {
      private EnvelopeEditor editor ;
      private SOAPTransport transport ;
  
      public FilterTransport(EnvelopeEditor editor, SOAPTransport transport) {
          this.editor = editor ;
          this.transport = transport ;
      }
  
      //private BufferedReader responseReader;
      //private Hashtable responseHeaders;
  
      /**
       * This method is used to request that an envelope be posted to the
       * given URL. The response (if any) must be gotten by calling the
       * receive() function.
       *
       * @param sendTo the URL to send the envelope to
       * @param action the SOAPAction header field value
       * @param headers any other header fields to go to as protocol headers
       * @param env the envelope to send
       * @param smr the XML<->Java type mapping registry (passed on)
       *
       * @exception SOAPException with appropriate reason code if problem
       */
      public void send (URL sendTo, String action, Hashtable headers,
                        Envelope env,
                        SOAPMappingRegistry smr, int timeout) throws SOAPException {
          try {
              StringWriter sout = new StringWriter() ;
              env.marshall (sout, smr);
  
              StringReader sin = new StringReader(sout.getBuffer().toString()) ;
              if (editor != null) {
                  sout = new StringWriter() ;
                  editor.editOutgoing(sin, sout) ;
                  sout.flush() ;
                  sin = new StringReader(sout.getBuffer().toString()) ;
              }
  
              XMLParserLiaison xpl = new XercesParserLiaison() ;
              Envelope env2 = Envelope.unmarshall(xpl.read("On-the-fly SOAP Envelope", sin).getDocumentElement()) ;
              transport.send(sendTo, action, headers, env2, smr, timeout) ;
          } catch (IllegalArgumentException e) {
              throw new SOAPException (Constants.FAULT_CODE_CLIENT, e.getMessage(), e);
          } catch (IOException e) {
              throw new SOAPException (Constants.FAULT_CODE_CLIENT, e.getMessage(), e);
          }
      }
  
      /**
       * Return a buffered reader to receive back the response to whatever
       * was sent to whatever.
       *
       * @return a reader to read the results from or null if that's not
       *         possible.
       */
      public BufferedReader receive () {
          try {
              BufferedReader in = transport.receive() ;
              if (editor == null)
                  return in ;
              else {
                  StringWriter sout = new StringWriter() ;
                  editor.editIncoming(in, sout) ;
                  sout.flush() ;
                  StringReader sin = new StringReader(sout.getBuffer().toString()) ;
                  return new BufferedReader(sin) ;
              }
          } catch (SOAPException e) {
              e.printStackTrace() ;
              // This exception should be thrown to the application.
              return null ;
          }
      }
  
      /**
       * Return access to headers generated by the protocol.
       * 
       * @return a hashtable containing all the headers
       */
      public Hashtable getHeaders () {
          return transport.getHeaders() ;
      }
  }
  /*
   * End Transport-Hook-Extension
   */
  
  
  

Re: cvs commit: xml-soap/java/src/org/apache/soap/transport EnvelopeEditor.java EnvelopeEditorAdapter.java EnvelopeEditorFactory.java FilterTransport.java

Posted by Ryo Neyama <ne...@trl.ibm.co.jp>.
As the CVS server notified, I have committed the transport hook extension.

Basically, the behavior of Apache SOAP will not be changed by this
extension.  Only when a system property named
"org.apache.soap.TransportHookExtension" is set, the transport hook
extension will be woken up.  Even if the system property is set, the
applications which does not know about the extension will work
correctly, although some warning messages will be printed to the
System.err stream.

Once the system property is set, {RPC,Message}RouterServlet reads an
init parameter named "EnvelopeEditorFactory", the value of the
parameter should be the name of an application-specific class, which
is an implementation of
org.apache.soap.transport.EnvelopeEditorFacotry. And then, the servlet
creates an instance of org.apache.soap.transport.EnvelopeEditor by
using the method EnvelopeEditorFactory#create(Properties).  An
application can provide any application-specific EnvelopeEditor by
implementing EnvelopeEditorFactory.

For example, if you are using Tomcat as a servlet engine, the
description of "web.xml" for application "purchaseOrder" will be as
follows:

<servlet>
    <servlet-name>messagerouter</servlet-name>
    <servlet-class>
        org.apache.soap.server.http.MessageRouterServlet
    </servlet-class>
    <init-param>
        <param-name>EnvelopeEditorFactory</param-name>
        <param-value>purchaseOrder.MyEnvelopeEditorFactory</param-value>
    </init-param>
    <init-param>
        .... Any other init parameters ....
    </init-param>
</servlet>

Also, you have to set the system property to enable the transport hook
extension.  In Tomcat, the environment variable "TOMCAT_OPTS" is
useful.  You may set it as
"-Dorg.apache.soap.TransportHookExtension=1."

I'm wondering I have to write out some documentation for this extension.
How should I do that?
I guess "xml-soap/java/docs/guide/" is an appropriate directory to put
the documentation.

Regards,
    Ryo Neyama @ IBM Research, Tokyo Research Laboratory
    Internet Technology
    neyama@trl.ibm.co.jp

Re: cvs commit: xml-soap/java/src/org/apache/soap/transport EnvelopeEditor.java EnvelopeEditorAdapter.java EnvelopeEditorFactory.java FilterTransport.java

Posted by Ryo Neyama <ne...@trl.ibm.co.jp>.
As the CVS server notified, I have committed the transport hook extension.

Basically, the behavior of Apache SOAP will not be changed by this
extension.  Only when a system property named
"org.apache.soap.TransportHookExtension" is set, the transport hook
extension will be woken up.  Even if the system property is set, the
applications which does not know about the extension will work
correctly, although some warning messages will be printed to the
System.err stream.

Once the system property is set, {RPC,Message}RouterServlet reads an
init parameter named "EnvelopeEditorFactory", the value of the
parameter should be the name of an application-specific class, which
is an implementation of
org.apache.soap.transport.EnvelopeEditorFacotry. And then, the servlet
creates an instance of org.apache.soap.transport.EnvelopeEditor by
using the method EnvelopeEditorFactory#create(Properties).  An
application can provide any application-specific EnvelopeEditor by
implementing EnvelopeEditorFactory.

For example, if you are using Tomcat as a servlet engine, the
description of "web.xml" for application "purchaseOrder" will be as
follows:

<servlet>
    <servlet-name>messagerouter</servlet-name>
    <servlet-class>
        org.apache.soap.server.http.MessageRouterServlet
    </servlet-class>
    <init-param>
        <param-name>EnvelopeEditorFactory</param-name>
        <param-value>purchaseOrder.MyEnvelopeEditorFactory</param-value>
    </init-param>
    <init-param>
        .... Any other init parameters ....
    </init-param>
</servlet>

Also, you have to set the system property to enable the transport hook
extension.  In Tomcat, the environment variable "TOMCAT_OPTS" is
useful.  You may set it as
"-Dorg.apache.soap.TransportHookExtension=1."

I'm wondering I have to write out some documentation for this extension.
How should I do that?
I guess "xml-soap/java/docs/guide/" is an appropriate directory to put
the documentation.

Regards,
    Ryo Neyama @ IBM Research, Tokyo Research Laboratory
    Internet Technology
    neyama@trl.ibm.co.jp