cziegeler 01/11/13 04:34:56 Modified: src/scratchpad/org/apache/avalon/excalibur/xml JaxpParser.java Parser.java XercesParser.java Added: src/scratchpad/org/apache/avalon/excalibur/source SourceResolverImpl.java URLSource.java Log: Started SourceResolverImpl and changed Parser to use ContentHandler instead of XMLConsumer Revision Changes Path 1.1 jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/source/SourceResolverImpl.java Index: SourceResolverImpl.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.avalon.excalibur.source; import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.component.Composable; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.logger.AbstractLoggable; import org.apache.avalon.framework.logger.Loggable; import org.apache.avalon.framework.thread.ThreadSafe; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @version $Id: SourceResolverImpl.java,v 1.1 2001/11/13 12:34:56 cziegeler Exp $ */ public class SourceResolverImpl extends AbstractLoggable implements ThreadSafe, Configurable, Disposable, Composable, Contextualizable, SourceResolver { /** The component manager */ protected ComponentManager manager; /** The special Source factories */ protected Map sourceFactories; /** The context */ protected Context context; /** * The base URL */ protected URL baseURL; /** * Configure the SourceFactories */ public void configure(final Configuration conf) throws ConfigurationException { // set the base URL to the current directory try { this.baseURL = new File(System.getProperty("user.dir")).toURL(); } catch (MalformedURLException mue) { throw new ConfigurationException("Malformed URL for user.dir"); } // get the configured factories try { getLogger().debug("Getting the SourceFactories"); HashMap factories = new HashMap(); Configuration[] configs = conf.getChildren("protocol"); SourceFactory sourceFactory = null; String protocol = null; for (int i = 0; i < configs.length; i++) { protocol = configs[i].getAttribute("name"); if (factories.containsKey(protocol) == true) { throw new ConfigurationException("SourceFactory defined twice for protocol: " + protocol); } getLogger().debug("\tfor protocol: " + protocol + " " + configs[i].getAttribute("class")); sourceFactory = (SourceFactory) Class.forName(configs[i].getAttribute("class")).newInstance(); this.init(sourceFactory); factories.put(protocol, sourceFactory); } this.sourceFactories = java.util.Collections.synchronizedMap(factories); } catch (ConfigurationException e) { throw e; } catch (Exception e) { getLogger().error("Could not get SourceFactories", e); throw new ConfigurationException("Could not get parameters because: " + e.getMessage()); } } /** * Get the context */ public void contextualize(Context context) throws ContextException { this.context = context; } /** * Set the current <code>ComponentManager</code> instance used by this * <code>Composable</code>. */ public void compose(ComponentManager manager) throws ComponentException { this.manager = manager; } /** * Dispose */ public void dispose() { Iterator iter = this.sourceFactories.values().iterator(); SourceFactory current; while (iter.hasNext() == true) { current = (SourceFactory) iter.next(); this.deinit(current); } this.sourceFactories = null; } /** * Set the base URL. All relative references are resolved * according to this URL. */ public void setBaseURL(URL base) { if (this.getLogger().isDebugEnabled() == true) { this.getLogger().debug("Changing baseURL to: " + base); } this.baseURL = base; } /** * Get the base URL */ public URL getBaseURL() { return this.baseURL; } /** * Get a <code>Source</code> object. */ public Source resolve(String location) throws MalformedURLException, IOException { return this.resolve(this.baseURL, location); } /** * Get a <code>Source</code> object. */ public Source resolve(URL base, String location) throws MalformedURLException, IOException { this.getLogger().debug("Resolving '"+location+"' in context '" + base + "'"); if (location == null) throw new MalformedURLException("Invalid System ID"); // first step: create systemID String systemID; if (base == null) base = this.baseURL; if (location.length() == 0) { systemID = base.toExternalForm(); } else if (location.indexOf(":") > 1) { systemID = location; } else if (location.charAt(0) == '/') { systemID = new StringBuffer(base.getProtocol()) .append(":").append(location).toString(); // windows: absolute paths can start with drive letter } else if (location.length() > 1 && location.charAt(1) == ':') { systemID = new StringBuffer(base.getProtocol()) .append(":/").append(location).toString(); } else { if (base.getProtocol().equals("file") == true) { File temp = new File(base.toExternalForm().substring("file:".length()), location); String path = temp.getAbsolutePath(); // windows paths starts with drive letter if (path.charAt(0) != File.separator.charAt(0)) { systemID = "file:/" + path; } else { systemID = "file:" + path; } } else { systemID = new URL(base, location).toExternalForm(); } } this.getLogger().debug("Resolved to systemID '"+systemID+"'"); // search for a SourceFactory implementing the protocol final int protocolPos = systemID.indexOf(':'); if ( protocolPos != -1 ) { final String protocol = systemID.substring(0, protocolPos); final SourceFactory factory = ( SourceFactory )this.sourceFactories.get( protocol ); if (factory != null) { return factory.getSource( systemID ); } } // no factory found, so usual url handling stuff... try { getLogger().debug("Making URL from " + systemID); return new URLSource(new URL(systemID), this.manager); } catch (MalformedURLException mue) { getLogger().debug("Making URL - MalformedURLException in getURL:" , mue); getLogger().debug("Making URL a File (assuming that it is full path):" + systemID); return new URLSource((new File(systemID)).toURL(), this.manager); } } /** * Init a source factory */ private void init(SourceFactory factory) throws ContextException, ComponentException { if (factory instanceof Loggable) { ((Loggable) factory).setLogger(getLogger()); } if (factory instanceof Contextualizable) { ((Contextualizable) factory).contextualize (this.context); } if (factory instanceof Composable) { ((Composable) factory).compose(this.manager); } } /** * Deinit a source factory */ private void deinit(SourceFactory factory) { if (factory instanceof Disposable) { ((Disposable) factory).dispose(); } } } 1.1 jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/source/URLSource.java Index: URLSource.java =================================================================== /***************************************************************************** * Copyright (C) The Apache Software Foundation. All rights reserved. * * ------------------------------------------------------------------------- * * This software is published under the terms of the Apache Software License * * version 1.1, a copy of which has been included with this distribution in * * the LICENSE file. * *****************************************************************************/ package org.apache.avalon.excalibur.source; import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.excalibur.xml.Parser; import org.apache.avalon.excalibur.xml.XMLConsumer; import org.apache.avalon.excalibur.xml.XMLizable; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.ext.LexicalHandler; import java.io.*; import java.lang.reflect.Method; import java.net.URL; import java.net.URLConnection; /** * Description of a source which is described by an URL. * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @version CVS $Revision: 1.1 $ $Date: 2001/11/13 12:34:56 $ */ public final class URLSource implements ModifiableSource, XMLizable { /** Identifier for file urls */ private final String FILE = "file:"; /** The last modification date or 0 */ private long lastModificationDate; /** The content length */ private long contentLength; /** The system id */ private String systemId; /** The URL of the source */ private URL url; /** The connection for a real URL */ private URLConnection connection; /** Is this a file or a "real" URL */ private boolean isFile; /** Are we initialized? */ private boolean gotInfos; /** The ComponentManager needed for streaming */ private ComponentManager manager; /** * Construct a new object */ public URLSource(URL url, ComponentManager manager) throws IOException { this.manager = manager; this.systemId = url.toExternalForm(); this.isFile = systemId.startsWith(FILE); this.url = url; this.gotInfos = false; } /** * Get the last modification date and content length of the source. * Any exceptions are ignored. */ private void getInfos() { if (this.gotInfos == false) { if (this.isFile == true) { File file = new File(systemId.substring(FILE.length())); this.lastModificationDate = file.lastModified(); this.contentLength = file.length(); } else { try { if (this.connection == null) { this.connection = this.url.openConnection(); String userInfo = this.getUserInfo(); if (this.url.getProtocol().startsWith("http") == true && userInfo != null) { this.connection.setRequestProperty("Authorization","Basic "+this.encodeBASE64(userInfo)); } } this.lastModificationDate = this.connection.getLastModified(); this.contentLength = this.connection.getContentLength(); } catch (IOException ignore) { this.lastModificationDate = 0; this.contentLength = -1; } } this.gotInfos = true; } } /** * Get the last modification date of the source or 0 if it * is not possible to determine the date. */ public long getLastModified() { this.getInfos(); return this.lastModificationDate; } /** * Get the content length of the source or -1 if it * is not possible to determine the length. */ public long getContentLength() { this.getInfos(); return this.contentLength; } /** * Return an <code>InputStream</code> object to read from the source. * * @throws ResourceNotFoundException if file not found or * HTTP location does not exist. * @throws IOException if I/O error occured. */ public InputStream getInputStream() throws IOException { this.getInfos(); InputStream input = null; if (this.isFile == true) { input = new FileInputStream(this.systemId.substring(FILE.length())); } else { if (this.connection == null) { this.connection = this.url.openConnection(); /* The following requires a jdk 1.3 */ String userInfo = this.getUserInfo(); if (this.url.getProtocol().startsWith("http") == true && userInfo != null) { this.connection.setRequestProperty("Authorization","Basic "+encodeBASE64(userInfo)); } } input = this.connection.getInputStream(); this.connection = null; // make sure a new connection is created next time } return input; } private static boolean checkedURLClass = false; private static boolean urlSupportsGetUserInfo = false; private static Method urlGetUserInfo = null; private static Object[] emptyParams = new Object[0]; /** * Check if the <code>URL</code> class supports the getUserInfo() * method which is introduced in jdk 1.3 */ private String getUserInfo() { if (URLSource.checkedURLClass == true) { if (URLSource.urlSupportsGetUserInfo == true) { try { return (String) URLSource.urlGetUserInfo.invoke(this.url, URLSource.emptyParams); } catch (Exception e){ // ignore this anyway } } return null; } else { // test if the url class supports the getUserInfo method try { URLSource.urlGetUserInfo = URL.class.getMethod("getUserInfo", null); String ui = (String)URLSource.urlGetUserInfo.invoke(this.url, URLSource.emptyParams); URLSource.checkedURLClass = true; URLSource.urlSupportsGetUserInfo = true; return ui; } catch (Exception e){ } URLSource.checkedURLClass = true; URLSource.urlSupportsGetUserInfo = false; URLSource.urlGetUserInfo = null; return null; } } /** * Return the unique identifer for this source */ public String getSystemId() { return this.systemId; } /** * Refresh this object and update the last modified date * and content length. */ public void refresh() { // reset connection this.connection = null; this.gotInfos = false; } /** * Return a new <code>InputSource</code> object * * @throws ResourceNotFoundException if file not found or * HTTP location does not exist. * @throws IOException if I/O error occured. */ public InputSource getInputSource() throws IOException { InputSource newObject = new InputSource(this.getInputStream()); newObject.setSystemId(this.systemId); return newObject; } public static final char [ ] alphabet = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 to 7 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 8 to 15 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 16 to 23 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 24 to 31 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 32 to 39 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 40 to 47 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 48 to 55 '4', '5', '6', '7', '8', '9', '+', '/' }; // 56 to 63 /** * BASE 64 encoding. * See also RFC 1421 * @since 1.2 */ public static String encodeBASE64 ( String s ) { return encodeBASE64 ( s.getBytes ( ) ); } /** * BASE 64 encoding. * See also RFC 1421 * @since 1.2 */ public static String encodeBASE64 ( byte [ ] octetString ) { int bits24; int bits6; char [ ] out = new char [ ( ( octetString.length - 1 ) / 3 + 1 ) * 4 ]; int outIndex = 0; int i = 0; while ( ( i + 3 ) <= octetString.length ) { // store the octets bits24 = ( octetString [ i++ ] & 0xFF ) << 16; bits24 |= ( octetString [ i++ ] & 0xFF ) << 8; bits24 |= ( octetString [ i++ ] & 0xFF ) << 0; bits6 = ( bits24 & 0x00FC0000 ) >> 18; out [ outIndex++ ] = alphabet [ bits6 ]; bits6 = ( bits24 & 0x0003F000 ) >> 12; out [ outIndex++ ] = alphabet [ bits6 ]; bits6 = ( bits24 & 0x00000FC0 ) >> 6; out [ outIndex++ ] = alphabet [ bits6 ]; bits6 = ( bits24 & 0x0000003F ); out [ outIndex++ ] = alphabet [ bits6 ]; } if ( octetString.length - i == 2 ) { // store the octets bits24 = ( octetString [ i ] & 0xFF ) << 16; bits24 |= ( octetString [ i + 1 ] & 0xFF ) << 8; bits6 = ( bits24 & 0x00FC0000 ) >> 18; out [ outIndex++ ] = alphabet [ bits6 ]; bits6 = ( bits24 & 0x0003F000 ) >> 12; out [ outIndex++ ] = alphabet [ bits6 ]; bits6 = ( bits24 & 0x00000FC0 ) >> 6; out [ outIndex++ ] = alphabet [ bits6 ]; // padding out [ outIndex++ ] = '='; } else if ( octetString.length - i == 1 ) { // store the octets bits24 = ( octetString [ i ] & 0xFF ) << 16; bits6 = ( bits24 & 0x00FC0000 ) >> 18; out [ outIndex++ ] = alphabet [ bits6 ]; bits6 = ( bits24 & 0x0003F000 ) >> 12; out [ outIndex++ ] = alphabet [ bits6 ]; // padding out [ outIndex++ ] = '='; out [ outIndex++ ] = '='; } return new String ( out ); } /** * Stream content to a content handler or to an XMLConsumer. * * @throws ResourceNotFoundException if file not found or * HTTP location does not exist. * @throws SAXException if failed to parse source document. */ public void toSAX(ContentHandler handler) throws SAXException { Parser parser = null; try { parser = (Parser)this.manager.lookup(Parser.ROLE); parser.parse(this.getInputSource(), handler); } catch (SAXException e) { // Preserve original exception throw e; } catch (Exception e){ throw new SAXException("Exception during processing of " + this.systemId, e); } finally { if (parser != null) this.manager.release(parser); } } public void recycle() { } } 1.2 +8 -4 jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/JaxpParser.java Index: JaxpParser.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/JaxpParser.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- JaxpParser.java 2001/11/13 11:03:58 1.1 +++ JaxpParser.java 2001/11/13 12:34:56 1.2 @@ -15,6 +15,7 @@ import org.apache.avalon.framework.parameters.Parameters; import org.w3c.dom.Document; import org.xml.sax.*; +import org.xml.sax.ext.LexicalHandler; import javax.xml.parsers.*; import java.io.IOException; @@ -25,7 +26,7 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a> * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/13 11:03:58 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/13 12:34:56 $ */ public class JaxpParser extends AbstractLoggable @@ -52,7 +53,7 @@ this.docfactory.setValidating(validate); } - public void parse(InputSource in, XMLConsumer consumer) + public void parse(InputSource in, ContentHandler consumer) throws SAXException, IOException { SAXParser parser = null; @@ -67,8 +68,11 @@ reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); try { - reader.setProperty("http://xml.org/sax/properties/lexical-handler", - consumer); + if (consumer instanceof XMLConsumer + || consumer instanceof LexicalHandler) { + reader.setProperty("http://xml.org/sax/properties/lexical-handler", + (LexicalHandler)consumer); + } } catch (SAXException e) { getLogger().warn("SAX2 driver does not support property: "+ "'http://xml.org/sax/properties/lexical-handler'"); 1.2 +2 -2 jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/Parser.java Index: Parser.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/Parser.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Parser.java 2001/11/13 11:03:58 1.1 +++ Parser.java 2001/11/13 12:34:56 1.2 @@ -19,13 +19,13 @@ /** * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> - * @version CVS $Revision: 1.1 $ $Date: 2001/11/13 11:03:58 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/13 12:34:56 $ */ public interface Parser extends Component { String ROLE = "org.apache.avalon.excalibur.xml.Parser"; - void parse(InputSource in, XMLConsumer consumer) + void parse(InputSource in, ContentHandler consumer) throws SAXException, IOException; Document parseDocument(InputSource in) 1.2 +9 -5 jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/XercesParser.java Index: XercesParser.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/XercesParser.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- XercesParser.java 2001/11/13 11:03:58 1.1 +++ XercesParser.java 2001/11/13 12:34:56 1.2 @@ -12,18 +12,19 @@ import org.apache.xerces.parsers.DOMParser; import org.apache.xerces.parsers.SAXParser; import org.w3c.dom.Document; +import org.xml.sax.ContentHandler; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; - +import org.xml.sax.ext.LexicalHandler; import java.io.IOException; /** * * @author <a href="mailto:[EMAIL PROTECTED]">Pierpaolo Fumagalli</a> * (Apache Software Foundation, Exoffice Technologies) - * @version CVS $Revision: 1.1 $ $Date: 2001/11/13 11:03:58 $ + * @version CVS $Revision: 1.2 $ $Date: 2001/11/13 12:34:56 $ */ public class XercesParser extends AbstractLoggable @@ -42,10 +43,13 @@ true); } - public void parse(InputSource in, XMLConsumer consumer) + public void parse(InputSource in, ContentHandler consumer) throws SAXException, IOException { - this.parser.setProperty("http://xml.org/sax/properties/lexical-handler", - consumer); + if (consumer instanceof XMLConsumer + || consumer instanceof LexicalHandler) { + this.parser.setProperty("http://xml.org/sax/properties/lexical-handler", + (LexicalHandler)consumer); + } this.parser.setErrorHandler(this); this.parser.setContentHandler(consumer); this.parser.parse(in);
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>