mrglavas    2004/09/29 13:23:58

  Modified:    java/src/org/apache/xerces/xinclude XIncludeHandler.java
                        XIncludeTextReader.java
               java/src/org/apache/xerces/impl XMLEntityManager.java
  Added:       java/src/org/apache/xerces/util HTTPInputSource.java
  Log:
  XInclude: Support content negotation for parse='xml'.

  Restructured interaction between XIncludeTextReader

  and XIncludeHandler for accept and accept-language

  attributes. Created new HTTPInputSource class which

  glues it all together.
  
  Revision  Changes    Path
  1.36      +36 -19    
xml-xerces/java/src/org/apache/xerces/xinclude/XIncludeHandler.java
  
  Index: XIncludeHandler.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/java/src/org/apache/xerces/xinclude/XIncludeHandler.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- XIncludeHandler.java      16 Aug 2004 01:27:29 -0000      1.35
  +++ XIncludeHandler.java      29 Sep 2004 20:23:58 -0000      1.36
  @@ -28,6 +28,7 @@
   import org.apache.xerces.impl.io.MalformedByteSequenceException;
   import org.apache.xerces.impl.msg.XMLMessageFormatter;
   import org.apache.xerces.util.AugmentationsImpl;
  +import org.apache.xerces.util.HTTPInputSource;
   import org.apache.xerces.util.IntStack;
   import org.apache.xerces.util.ParserConfigurationSettings;
   import org.apache.xerces.util.SecurityManager;
  @@ -1377,6 +1378,16 @@
   
                   includedSource =
                       fEntityResolver.resolveEntity(resourceIdentifier);
  +                
  +                if (includedSource != null &&
  +                    !(includedSource instanceof HTTPInputSource) &&
  +                    (accept != null || acceptLanguage != null) &&
  +                    includedSource.getCharacterStream() == null &&
  +                    includedSource.getByteStream() == null) {
  +                    
  +                    includedSource = 
createInputSource(includedSource.getPublicId(), includedSource.getSystemId(), 
  +                        includedSource.getBaseSystemId(), accept, acceptLanguage);
  +                }
               }
               catch (IOException e) {
                   reportResourceError(
  @@ -1387,12 +1398,15 @@
           }
   
           if (includedSource == null) {
  -            includedSource =
  -                new XMLInputSource(
  -                    null,
  -                    href,
  -                    fCurrentBaseURI.getExpandedSystemId());
  +            // setup an HTTPInputSource if either of the content negotation 
attributes were specified.
  +            if (accept != null || acceptLanguage != null) {
  +                includedSource = createInputSource(null, href, 
fCurrentBaseURI.getExpandedSystemId(), accept, acceptLanguage);
  +            }
  +            else {
  +                includedSource = new XMLInputSource(null, href, 
fCurrentBaseURI.getExpandedSystemId());
  +            }
           }
  +        
           if (parse.equals(XINCLUDE_PARSE_XML)) {
               // Instead of always creating a new configuration, the first one can be 
reused
               if (fChildConfig == null) {
  @@ -1429,15 +1443,6 @@
               copyFeatures(fSettings, fChildConfig);
   
               try {
  -                // REVISIT: If we're going to support content negotation for
  -                // parse=xml we need to find a clean way to propogate the
  -                // parameters to the child parser. We cannot set those parameters
  -                // here because we may lose some information if we process the
  -                // URLConnection and then open a stream. The parser needs a
  -                // URLConnection to follow HTTP redirects and may also need
  -                // this object in the future to read external encoding information
  -                // which may be available in the Content-Type. -- mrglavas
  -
                   fNamespaceContext.pushScope();
                   fChildConfig.parse(includedSource);
                   // necessary to make sure proper location is reported in errors
  @@ -1495,10 +1500,6 @@
                       }
                       textReader = fXInclude11TextReader;
                   }
  -                if (includedSource.getCharacterStream() == null
  -                    && includedSource.getByteStream() == null) {
  -                     textReader.setHttpProperties(accept, acceptLanguage);
  -                }
                   textReader.setErrorReporter(fErrorReporter);
                   textReader.parse();
               }
  @@ -2565,4 +2566,20 @@
           return true;
       }
       
  +    /**
  +     * Returns a new <code>XMLInputSource</code> from the given parameters.
  +     */
  +    private XMLInputSource createInputSource(String publicId, 
  +            String systemId, String baseSystemId, 
  +            String accept, String acceptLanguage) {
  +
  +        HTTPInputSource httpSource = new HTTPInputSource(publicId, systemId, 
baseSystemId);
  +        if (accept != null && accept.length() > 0) {
  +            httpSource.setHTTPRequestProperty(XIncludeHandler.HTTP_ACCEPT, accept);
  +        }
  +        if (acceptLanguage != null && acceptLanguage.length() > 0) {
  +            httpSource.setHTTPRequestProperty(XIncludeHandler.HTTP_ACCEPT_LANGUAGE, 
acceptLanguage);
  +        }
  +        return httpSource;
  +    }
   }
  
  
  
  1.12      +17 -24    
xml-xerces/java/src/org/apache/xerces/xinclude/XIncludeTextReader.java
  
  Index: XIncludeTextReader.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/java/src/org/apache/xerces/xinclude/XIncludeTextReader.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- XIncludeTextReader.java   18 Jul 2004 19:57:42 -0000      1.11
  +++ XIncludeTextReader.java   29 Sep 2004 20:23:58 -0000      1.12
  @@ -23,7 +23,9 @@
   import java.net.HttpURLConnection;
   import java.net.URL;
   import java.net.URLConnection;
  +import java.util.Iterator;
   import java.util.Locale;
  +import java.util.Map;
   
   import org.apache.xerces.impl.XMLEntityManager;
   import org.apache.xerces.impl.XMLErrorReporter;
  @@ -31,6 +33,7 @@
   import org.apache.xerces.impl.io.UTF8Reader;
   import org.apache.xerces.impl.msg.XMLMessageFormatter;
   import org.apache.xerces.util.EncodingMap;
  +import org.apache.xerces.util.HTTPInputSource;
   import org.apache.xerces.util.MessageFormatter;
   import org.apache.xerces.util.XMLChar;
   import org.apache.xerces.xni.XMLString;
  @@ -64,10 +67,6 @@
       private XMLInputSource fSource;
       private XMLErrorReporter fErrorReporter;
       private XMLString fTempString = new XMLString();
  -    
  -    // Content negotation parameters
  -    private String fAccept;
  -    private String fAcceptLanguage;
    
       /**
        * Construct the XIncludeReader using the XMLInputSource and XIncludeHandler.
  @@ -93,17 +92,6 @@
       public void setErrorReporter(XMLErrorReporter errorReporter) {
           fErrorReporter = errorReporter;
       }
  -    
  -    /**
  -     * Sets content negotation parameters to be attached to an HTTP request.
  -     * 
  -     * @param accept the Accept HTTP request property
  -     * @param acceptLanguage the Accept-Language HTTP request property
  -     */
  -    public void setHttpProperties(String accept, String acceptLanguage) {
  -        fAccept = accept;
  -        fAcceptLanguage = acceptLanguage;
  -    }
   
       /**
        * Return the Reader for given XMLInputSource.
  @@ -134,15 +122,20 @@
                   URL url = new URL(expandedSystemId);
                   URLConnection urlCon = url.openConnection();
                                
  -                // If this is an HTTP connection attach any 
  -                // content negotation parameters to the request.
  -                if (urlCon instanceof HttpURLConnection) {
  -                    if( fAccept != null && fAccept.length() > 0) {
  -                        urlCon.setRequestProperty(XIncludeHandler.HTTP_ACCEPT, 
fAccept);
  -                    }
  -                    if( fAcceptLanguage != null && fAcceptLanguage.length() > 0) {
  -                        
urlCon.setRequestProperty(XIncludeHandler.HTTP_ACCEPT_LANGUAGE, fAcceptLanguage);
  +                // If this is an HTTP connection attach any request properties to 
the request.
  +                if (urlCon instanceof HttpURLConnection && source instanceof 
HTTPInputSource) {
  +                    final HttpURLConnection urlConnection = (HttpURLConnection) 
urlCon;
  +                    final HTTPInputSource httpInputSource = (HTTPInputSource) 
source;
  +                    
  +                    // set request properties
  +                    Iterator propIter = httpInputSource.getHTTPRequestProperties();
  +                    while (propIter.hasNext()) {
  +                        Map.Entry entry = (Map.Entry) propIter.next();
  +                        urlConnection.setRequestProperty((String) entry.getKey(), 
(String) entry.getValue());
                       }
  +                    
  +                    // set preference for redirection
  +                    
urlConnection.setInstanceFollowRedirects(httpInputSource.getFollowHTTPRedirects());
                   }
                   
                   // Wrap the InputStream so that it is possible to rewind it.
  
  
  
  1.87      +41 -13    xml-xerces/java/src/org/apache/xerces/impl/XMLEntityManager.java
  
  Index: XMLEntityManager.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/java/src/org/apache/xerces/impl/XMLEntityManager.java,v
  retrieving revision 1.86
  retrieving revision 1.87
  diff -u -r1.86 -r1.87
  --- XMLEntityManager.java     24 Sep 2004 18:03:01 -0000      1.86
  +++ XMLEntityManager.java     29 Sep 2004 20:23:58 -0000      1.87
  @@ -25,6 +25,8 @@
   import java.net.URL;
   import java.net.URLConnection;
   import java.util.Hashtable;
  +import java.util.Iterator;
  +import java.util.Map;
   import java.util.Locale;
   import java.util.Stack;
   
  @@ -35,6 +37,7 @@
   import org.apache.xerces.impl.validation.ValidationManager;
   import org.apache.xerces.util.AugmentationsImpl;
   import org.apache.xerces.util.EncodingMap;
  +import org.apache.xerces.util.HTTPInputSource;
   import org.apache.xerces.util.SecurityManager;
   import org.apache.xerces.util.SymbolTable;
   import org.apache.xerces.util.URI;
  @@ -923,18 +926,43 @@
               if (stream == null) {
                   URL location = new URL(expandedSystemId);
                   URLConnection connect = location.openConnection();
  -                stream = connect.getInputStream();
  -                
  -                // REVISIT: If the URLConnection has external encoding
  -                // information, we should be reading it here. It's located
  -                // in the charset parameter of Content-Type. -- mrglavas
  -                if (connect instanceof HttpURLConnection) {
  -                    String redirect = connect.getURL().toString();
  -                    // E43: Check if the URL was redirected, and then
  -                    // update literal and expanded system IDs if needed.
  -                    if (!redirect.equals(expandedSystemId)) {
  -                        literalSystemId = redirect;
  -                        expandedSystemId = redirect;
  +                if (!(connect instanceof HttpURLConnection)) {
  +                    stream = connect.getInputStream();
  +                }
  +                else {
  +                    boolean followRedirects = true;
  +                    
  +                    // setup URLConnection if we have an HTTPInputSource
  +                    if (xmlInputSource instanceof HTTPInputSource) {
  +                        final HttpURLConnection urlConnection = (HttpURLConnection) 
connect;
  +                        final HTTPInputSource httpInputSource = (HTTPInputSource) 
xmlInputSource;
  +                        
  +                        // set request properties
  +                        Iterator propIter = 
httpInputSource.getHTTPRequestProperties();
  +                        while (propIter.hasNext()) {
  +                            Map.Entry entry = (Map.Entry) propIter.next();
  +                            urlConnection.setRequestProperty((String) 
entry.getKey(), (String) entry.getValue());
  +                        }
  +                        
  +                        // set preference for redirection
  +                        followRedirects = httpInputSource.getFollowHTTPRedirects();
  +                        urlConnection.setInstanceFollowRedirects(followRedirects);
  +                    }
  +                    
  +                    stream = connect.getInputStream();
  +                    
  +                    // REVISIT: If the URLConnection has external encoding
  +                    // information, we should be reading it here. It's located
  +                    // in the charset parameter of Content-Type. -- mrglavas
  +                    
  +                    if (followRedirects) {
  +                        String redirect = connect.getURL().toString();
  +                        // E43: Check if the URL was redirected, and then
  +                        // update literal and expanded system IDs if needed.
  +                        if (!redirect.equals(expandedSystemId)) {
  +                            literalSystemId = redirect;
  +                            expandedSystemId = redirect;
  +                        }
                       }
                   }
               }
  
  
  
  1.1                  xml-xerces/java/src/org/apache/xerces/util/HTTPInputSource.java
  
  Index: HTTPInputSource.java
  ===================================================================
  /*
   * Copyright 2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.xerces.util;
  
  import java.io.InputStream;
  import java.io.Reader;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.xerces.xni.XMLResourceIdentifier;
  import org.apache.xerces.xni.parser.XMLInputSource;
  
  /**
   * This class represents an input source for an XML resource
   * retrievable over HTTP. In addition to the properties
   * provided by an <code>XMLInputSource</code> an HTTP input
   * source also has HTTP request properties and a preference
   * whether HTTP redirects will be followed. Note that these
   * properties will only be used if reading this input source
   * will induce an HTTP connection.
   * 
   * @author Michael Glavassevich, IBM
   * 
   * @version $Id: HTTPInputSource.java,v 1.1 2004/09/29 20:23:58 mrglavas Exp $
   */
  public class HTTPInputSource extends XMLInputSource {
  
      //
      // Data
      //
      
      /** Preference for whether HTTP redirects should be followed. **/
      protected boolean fFollowRedirects = true;
      
      /** HTTP request properties. **/
      protected Map fHTTPRequestProperties = new HashMap();
      
      //
      // Constructors
      //
      
      /** 
       * Constructs an input source from just the public and system
       * identifiers, leaving resolution of the entity and opening of
       * the input stream up to the caller.
       *
       * @param publicId     The public identifier, if known.
       * @param systemId     The system identifier. This value should
       *                     always be set, if possible, and can be
       *                     relative or absolute. If the system identifier
       *                     is relative, then the base system identifier
       *                     should be set.
       * @param baseSystemId The base system identifier. This value should
       *                     always be set to the fully expanded URI of the
       *                     base system identifier, if possible.
       */
      public HTTPInputSource(String publicId, String systemId, String baseSystemId) {
          super(publicId, systemId, baseSystemId);
      } // <init>(String,String,String)
      
      /** 
       * Constructs an input source from a XMLResourceIdentifier
       * object, leaving resolution of the entity and opening of
       * the input stream up to the caller.
       *
       * @param resourceIdentifier the XMLResourceIdentifier containing the information
       */
      public HTTPInputSource(XMLResourceIdentifier resourceIdentifier) {
          super(resourceIdentifier);
      } // <init>(XMLResourceIdentifier)
      
      /**
       * Constructs an input source from a byte stream.
       *
       * @param publicId     The public identifier, if known.
       * @param systemId     The system identifier. This value should
       *                     always be set, if possible, and can be
       *                     relative or absolute. If the system identifier
       *                     is relative, then the base system identifier
       *                     should be set.
       * @param baseSystemId The base system identifier. This value should
       *                     always be set to the fully expanded URI of the
       *                     base system identifier, if possible.
       * @param byteStream   The byte stream.
       * @param encoding     The encoding of the byte stream, if known.
       */
      public HTTPInputSource(String publicId, String systemId,
              String baseSystemId, InputStream byteStream, String encoding) {
          super(publicId, systemId, baseSystemId, byteStream, encoding);
      } // <init>(String,String,String,InputStream,String)
      
      /**
       * Constructs an input source from a character stream.
       *
       * @param publicId     The public identifier, if known.
       * @param systemId     The system identifier. This value should
       *                     always be set, if possible, and can be
       *                     relative or absolute. If the system identifier
       *                     is relative, then the base system identifier
       *                     should be set.
       * @param baseSystemId The base system identifier. This value should
       *                     always be set to the fully expanded URI of the
       *                     base system identifier, if possible.
       * @param charStream   The character stream.
       * @param encoding     The original encoding of the byte stream
       *                     used by the reader, if known.
       */
      public HTTPInputSource(String publicId, String systemId,
              String baseSystemId, Reader charStream, String encoding) {
          super(publicId, systemId, baseSystemId, charStream, encoding);
      } // <init>(String,String,String,Reader,String)
      
      //
      // Public methods
      //   
      
      /**
       * Returns the preference whether HTTP redirects should
       * be followed. By default HTTP redirects will be followed.
       */
      public boolean getFollowHTTPRedirects() {
          return fFollowRedirects;
      } // getFollowHTTPRedirects():boolean
      
      
      /**
       * Sets the preference whether HTTP redirects should
       * be followed. By default HTTP redirects will be followed.
       */
      public void setFollowHTTPRedirects(boolean followRedirects) {
          fFollowRedirects = followRedirects;
      } // setFollowHTTPRedirects(boolean)
      
      /**
       * Returns the value of the request property 
       * associated with the given property name.
       * 
       * @param key the name of the request property
       * @return the value of the request property or 
       * <code>null</code> if this property has not
       * been set
       */
      public String getHTTPRequestProperty(String key) {
          return (String) fHTTPRequestProperties.get(key);
      } // getHTTPRequestProperty(String):String
      
      /**
       * Returns an iterator for the request properties this
       * input source contains. Each object returned by the
       * iterator is an instance of <code>java.util.Map.Entry</code>
       * where each key and value are a pair of strings corresponding
       * to the name and value of a request property. 
       * 
       * @return an iterator for the request properties this
       * input source contains
       */
      public Iterator getHTTPRequestProperties() {
          return fHTTPRequestProperties.entrySet().iterator();
      } // getHTTPRequestProperties():Iterator
      
      /**
       * Sets the value of the request property
       * associated with the given property name.
       * 
       * @param key the name of the request property
       * @param value the value of the request property
       */
      public void setHTTPRequestProperty(String key, String value) {
          if (value != null) {
              fHTTPRequestProperties.put(key, value);
          }
          else {
              fHTTPRequestProperties.remove(key);
          }
      } // setHTTPRequestProperty(String,String)
      
  } // class HTTPInputSource
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to