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]