You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by da...@apache.org on 2006/12/27 22:10:11 UTC
svn commit: r490567 [2/2] - in /cocoon/trunk/core:
cocoon-common/src/main/java/org/apache/cocoon/ cocoon-core/
cocoon-core/src/main/java/org/apache/cocoon/
cocoon-core/src/main/java/org/apache/cocoon/components/source/
cocoon-core/src/main/java/org/apa...
Added: cocoon/trunk/core/cocoon-pipeline/cocoon-pipeline-impl/src/main/java/org/apache/cocoon/components/source/util/SourceUtil.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-pipeline/cocoon-pipeline-impl/src/main/java/org/apache/cocoon/components/source/util/SourceUtil.java?view=auto&rev=490567
==============================================================================
--- cocoon/trunk/core/cocoon-pipeline/cocoon-pipeline-impl/src/main/java/org/apache/cocoon/components/source/util/SourceUtil.java (added)
+++ cocoon/trunk/core/cocoon-pipeline/cocoon-pipeline-impl/src/main/java/org/apache/cocoon/components/source/util/SourceUtil.java Wed Dec 27 13:10:05 2006
@@ -0,0 +1,582 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.cocoon.components.source.util;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.ResourceNotFoundException;
+import org.apache.cocoon.components.source.URLRewriter;
+import org.apache.cocoon.util.NetUtils;
+import org.apache.cocoon.xml.IncludeXMLConsumer;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.apache.excalibur.source.SourceNotFoundException;
+import org.apache.excalibur.source.SourceParameters;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.excalibur.xml.sax.SAXParser;
+import org.apache.excalibur.xml.sax.XMLizable;
+import org.apache.excalibur.xmlizer.XMLizer;
+import org.apache.regexp.RE;
+import org.apache.regexp.RECompiler;
+import org.apache.regexp.REProgram;
+import org.apache.regexp.RESyntaxException;
+import org.w3c.dom.Document;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This class contains some utility methods for the source resolving.
+ *
+ * @version $Id$
+ */
+public abstract class SourceUtil {
+
+ protected static REProgram uripattern;
+
+ static {
+ try {
+ uripattern = new RECompiler().compile("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$");
+ } catch (RESyntaxException e) {
+ // Should not happen
+ throw new RuntimeException("Error parsing regular expression.", e);
+ }
+ }
+
+ /**
+ * Generates SAX events from the given source with possible URL rewriting.
+ *
+ * <p><b>NOTE</b>: If the implementation can produce lexical events,
+ * care should be taken that <code>handler</code> can actually
+ * directly implement the LexicalHandler interface!</p>
+ *
+ * @param source the data
+ * @throws ProcessingException if no suitable converter is found
+ */
+ static public void toSAX(ServiceManager manager,
+ Source source,
+ ContentHandler handler,
+ Parameters typeParameters,
+ boolean filterDocumentEvent)
+ throws SAXException, IOException, ProcessingException {
+ // Test for url rewriting
+ if (typeParameters != null
+ && typeParameters.getParameter(URLRewriter.PARAMETER_MODE, null) != null) {
+ handler = new URLRewriter(typeParameters, handler);
+ }
+
+ String mimeTypeHint = null;
+ if (typeParameters != null) {
+ mimeTypeHint = typeParameters.getParameter("mime-type", mimeTypeHint);
+ }
+ if (filterDocumentEvent) {
+ IncludeXMLConsumer filter = new IncludeXMLConsumer(handler);
+ toSAX(manager, source, mimeTypeHint, filter);
+ } else {
+ toSAX(manager, source, mimeTypeHint, handler);
+ }
+ }
+
+ /**
+ * Generates SAX events from the XMLizable and handle SAXException.
+ *
+ * @param source the data
+ */
+ public static void toSAX(XMLizable source, ContentHandler handler) throws SAXException, IOException, ProcessingException {
+ try {
+ source.toSAX(handler);
+ } catch (SAXException e) {
+ // Unwrap ProcessingException, IOException, and extreme cases of SAXExceptions.
+ // Handle SourceException.
+ // See also handleSAXException
+ final Exception cause = e.getException();
+ if (cause != null) {
+ if (cause instanceof SourceException) {
+ throw handle((SourceException) cause);
+ }
+ if (cause instanceof ProcessingException) {
+ throw (ProcessingException) cause;
+ }
+ if (cause instanceof IOException) {
+ throw (IOException) cause;
+ }
+ if (cause instanceof SAXException) {
+ throw (SAXException) cause;
+ }
+ }
+
+ // Throw original SAX exception
+ throw e;
+ }
+ }
+
+ /**
+ * Generates SAX events from the given source.
+ *
+ * <p><b>NOTE</b>: If the implementation can produce lexical events,
+ * care should be taken that <code>handler</code> can actually
+ * directly implement the LexicalHandler interface!</p>
+ *
+ * @param source the data
+ * @throws ProcessingException if no suitable converter is found
+ */
+ static public void toSAX(ServiceManager manager,
+ Source source,
+ ContentHandler handler)
+ throws SAXException, IOException, ProcessingException {
+ toSAX(manager, source, null, handler);
+ }
+
+ /**
+ * Generates SAX events from the given source by using XMLizer.
+ *
+ * <p><b>NOTE</b>: If the implementation can produce lexical events,
+ * care should be taken that <code>handler</code> can actually
+ * directly implement the LexicalHandler interface!</p>
+ *
+ * @param source the data
+ * @throws ProcessingException if no suitable converter is found
+ */
+ public static void toSAX(ServiceManager manager,
+ Source source,
+ String mimeTypeHint,
+ ContentHandler handler)
+ throws SAXException, IOException, ProcessingException {
+ if (source instanceof XMLizable) {
+ toSAX((XMLizable) source, handler);
+ } else {
+ String mimeType = source.getMimeType();
+ if (null == mimeType) {
+ mimeType = mimeTypeHint;
+ }
+
+ XMLizer xmlizer = null;
+ try {
+ xmlizer = (XMLizer) manager.lookup(XMLizer.ROLE);
+ xmlizer.toSAX(source.getInputStream(),
+ mimeType,
+ source.getURI(),
+ handler);
+ } catch (SourceException e) {
+ throw SourceUtil.handle(e);
+ } catch (ServiceException e) {
+ throw new ProcessingException("Exception during streaming source.", e);
+ } finally {
+ manager.release(xmlizer);
+ }
+ }
+ }
+
+ /**
+ * Generates character SAX events from the given source.
+ *
+ * @param source The data
+ * @param encoding The character encoding of the data
+ */
+ public static void toCharacters(Source source, String encoding, ContentHandler handler) throws SAXException, IOException, ProcessingException {
+ try {
+ Reader r = encoding == null?
+ new InputStreamReader(source.getInputStream()):
+ new InputStreamReader(source.getInputStream(), encoding);
+
+ int len;
+ char[] chr = new char[4096];
+ try {
+ while ((len = r.read(chr)) > 0) {
+ handler.characters(chr, 0, len);
+ }
+ } finally {
+ r.close();
+ }
+ } catch (SAXException e) {
+ handleSAXException(source.getURI(), e);
+ }
+ }
+
+ /**
+ * Generates SAX events from the given source by parsing it.
+ *
+ * <p><b>NOTE</b>: If the implementation can produce lexical events,
+ * care should be taken that <code>handler</code> can actually
+ * directly implement the LexicalHandler interface!</p>
+ *
+ * @param source the data
+ * @throws ProcessingException if no suitable converter is found
+ */
+ public static void parse(ServiceManager manager, Source source, ContentHandler handler) throws SAXException, IOException, ProcessingException {
+ if (source instanceof XMLizable) {
+ toSAX((XMLizable) source, handler);
+ } else {
+ SAXParser parser = null;
+ try {
+ parser = (SAXParser) manager.lookup(SAXParser.ROLE);
+ parser.parse(getInputSource(source), handler);
+ } catch (SourceException e) {
+ throw SourceUtil.handle(e);
+ } catch (ServiceException e) {
+ throw new ProcessingException("Exception during parsing source.", e);
+ } finally {
+ manager.release(parser);
+ }
+ }
+ }
+
+ /**
+ * Generates a DOM from the given source
+ * @param source The data
+ *
+ * @return Created DOM document.
+ *
+ * @throws IOException If a io exception occurs.
+ * @throws ProcessingException if no suitable converter is found
+ * @throws SAXException If a SAX exception occurs.
+ */
+ public static Document toDOM(ServiceManager manager, Source source) throws SAXException, IOException, ProcessingException {
+ DOMBuilder builder = new DOMBuilder();
+
+ toSAX(manager, source, null, builder);
+
+ Document document = builder.getDocument();
+ if (document == null) {
+ throw new ProcessingException("Could not build DOM for '" +
+ source.getURI() + "'");
+ }
+
+ return document;
+ }
+
+ /**
+ * Generates a DOM from the given source
+ * @param source The data
+ *
+ * @return Created DOM document.
+ *
+ * @throws IOException If a io exception occurs.
+ * @throws ProcessingException if no suitable converter is found
+ * @throws SAXException If a SAX exception occurs.
+ */
+ public static Document toDOM(ServiceManager manager, String mimeTypeHint, Source source) throws SAXException, IOException, ProcessingException {
+ DOMBuilder builder = new DOMBuilder();
+
+ toSAX(manager, source, mimeTypeHint, builder);
+
+ Document document = builder.getDocument();
+ if (document == null) {
+ throw new ProcessingException("Could not build DOM for '" +
+ source.getURI() + "'");
+ }
+
+ return document;
+ }
+
+ /**
+ * Make a ProcessingException from a SourceException.
+ * If the exception is a SourceNotFoundException then a
+ * ResourceNotFoundException is thrown.
+ *
+ * @param se Source exception
+ * @return Created processing exception.
+ */
+ public static ProcessingException handle(SourceException se) {
+ if (se instanceof SourceNotFoundException) {
+ return new ResourceNotFoundException("Resource not found.", se);
+ }
+ return new ProcessingException("Exception during source resolving.",
+ se);
+ }
+
+ /**
+ * Make a ProcessingException from a SourceException.
+ * If the exception is a SourceNotFoundException then a
+ * ResourceNotFoundException is thrown.
+ *
+ * @param message Additional exception message.
+ * @param se Source exception.
+ * @return Created processing exception.
+ */
+ public static ProcessingException handle(String message, SourceException se) {
+ if (se instanceof SourceNotFoundException) {
+ return new ResourceNotFoundException(message, se);
+ }
+ return new ProcessingException(message, se);
+ }
+
+ /**
+ * Handle SAXException catched in Generator's generate method.
+ *
+ * @param source Generator's source
+ * @param e SAXException happened in the generator's generate method.
+ */
+ public static void handleSAXException(String source, SAXException e) throws ProcessingException, IOException, SAXException {
+ final Exception cause = e.getException();
+ if (cause != null) {
+ // Unwrap ProcessingException, IOException, and extreme cases of SAXExceptions.
+ // Handle SourceException.
+ // See also toSax(XMLizable, ContentHandler)
+ if (cause instanceof SourceException) {
+ throw handle((SourceException) cause);
+ }
+ if (cause instanceof ProcessingException) {
+ throw (ProcessingException) cause;
+ }
+ if (cause instanceof IOException) {
+ throw (IOException) cause;
+ }
+ if (cause instanceof SAXException) {
+ throw (SAXException) cause;
+ }
+ throw new ProcessingException("Could not read resource " +
+ source, cause);
+ }
+ throw e;
+ }
+
+ /**
+ * Get an InputSource object
+ *
+ * @param source Source.
+ *
+ * @return Input stream of the source.
+ *
+ * @throws IOException If a io exception occurs.
+ * @throws ProcessingException If an exception occurs during
+ * processing.
+ */
+ public static InputSource getInputSource(Source source) throws IOException, ProcessingException {
+ try {
+ final InputSource newObject = new InputSource(source.getInputStream());
+
+ newObject.setSystemId(source.getURI());
+ return newObject;
+ } catch (SourceException se) {
+ throw handle(se);
+ }
+ }
+
+ /**
+ * Get a <code>Source</code> object
+ *
+ * @param uri URI of the source.
+ * @param typeParameters Type of Source query. Currently, only
+ * <code>method</code> parameter (value typically <code>GET</code> or
+ * <code>POST</code>) is recognized. May be <code>null</code>.
+ * @param resourceParameters Parameters of the source. May be <code>null</code>
+ * @param resolver Resolver for the source.
+ *
+ * @return The resolved source.
+ *
+ * @throws IOException If a io exception occurs.
+ * @throws SAXException If a SAX exception occurs.
+ * @throws SourceException If the source an exception throws.
+ */
+ public static Source getSource(String uri, Parameters typeParameters, SourceParameters resourceParameters, SourceResolver resolver) throws IOException, SAXException, SourceException {
+
+ // first step: encode parameters which are already appended to the url
+ int queryPos = uri.indexOf('?');
+ if (queryPos != -1) {
+ String queryString = uri.substring(queryPos+1);
+ SourceParameters queries = new SourceParameters(queryString);
+
+ if (queries.hasParameters()) {
+ StringBuffer buffer = new StringBuffer(uri.substring(0, queryPos));
+ char separator = '?';
+
+ Iterator i = queries.getParameterNames();
+ while (i.hasNext()) {
+ String current = (String) i.next();
+ Iterator values = queries.getParameterValues(current);
+ while (values.hasNext()) {
+ buffer.append(separator)
+ .append(current)
+ .append('=')
+ .append(NetUtils.encode((String) values.next(), "utf-8"));
+ separator = '&';
+ }
+ }
+ uri = buffer.toString();
+ }
+ }
+
+ String method = ((typeParameters!=null)
+ ? typeParameters.getParameter("method", "GET")
+ : "GET");
+ if (method.equalsIgnoreCase("POST") &&
+ (resourceParameters == null ||
+ !resourceParameters.hasParameters())) {
+ method = "GET";
+ }
+
+ if (uri.startsWith("cocoon:") && resourceParameters != null &&
+ resourceParameters.hasParameters()) {
+ int pos = uri.indexOf(";jsessionid=");
+
+ StringBuffer buf;
+ if (pos == -1) {
+ buf = new StringBuffer(uri);
+ } else {
+ buf = new StringBuffer(uri.substring(0, pos));
+ }
+ buf.append(((uri.indexOf('?') == -1) ? '?' : '&'));
+ buf.append(resourceParameters.getEncodedQueryString());
+ uri = buf.toString();
+ }
+
+ Map resolverParameters = new HashMap();
+ resolverParameters.put(SourceResolver.METHOD, method);
+ if (typeParameters != null) {
+ String encoding = typeParameters.getParameter("encoding",
+ System.getProperty("file.encoding", "ISO-8859-1"));
+ if (encoding != null && !"".equals(encoding)) {
+ resolverParameters.put(SourceResolver.URI_ENCODING, encoding);
+ }
+ }
+ resolverParameters.put(SourceResolver.URI_PARAMETERS,
+ resourceParameters);
+
+ return resolver.resolveURI(uri, null, resolverParameters);
+ }
+
+ /**
+ * Return the scheme of a URI. Just as there are many different methods
+ * of access to resources, there are a variety of schemes for identifying
+ * such resources.
+ * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+ *
+ * @param uri Uniform resource identifier.
+ *
+ * @return Scheme of the URI.
+ */
+ public static String getScheme(String uri) {
+ RE re = new RE(uripattern);
+ if (re.match(uri)) {
+ return re.getParen(2);
+ } else {
+ throw new IllegalArgumentException("'" + uri +
+ "' is not a correct URI");
+ }
+ }
+
+ /**
+ * Return the authority of a URI. This authority is
+ * typically defined by an Internet-based server or a scheme-specific
+ * registry of naming authorities
+ * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+ *
+ * @param uri Uniform resource identifier.
+ *
+ * @return Scheme of the URI.
+ */
+ public static String getAuthority(String uri) {
+ RE re = new RE(uripattern);
+ if (re.match(uri)) {
+ return re.getParen(4);
+ } else {
+ throw new IllegalArgumentException("'" + uri +
+ "' is not a correct URI");
+ }
+ }
+
+ /**
+ * Return the path of a URI. The path contains data, specific to the
+ * authority (or the scheme if there is no authority component),
+ * identifying the resource within the scope of that scheme and authority
+ * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+ *
+ * @param uri Uniform resource identifier.
+ *
+ * @return Path of the URI.
+ */
+ public static String getPath(String uri) {
+ RE re = new RE(uripattern);
+ if (re.match(uri)) {
+ return re.getParen(5);
+ } else {
+ throw new IllegalArgumentException("'" + uri +
+ "' is not a correct URI");
+ }
+ }
+
+ /**
+ * Return the path of a URI, if the URI can't contains a authority.
+ * This implementation differ to the RFC 2396.
+ *
+ * @param uri Uniform resource identifier.
+ *
+ * @return Path of the URI.
+ */
+ public static String getPathWithoutAuthority(String uri) {
+ RE re = new RE(uripattern);
+ if (re.match(uri)) {
+ return re.getParen(4) + re.getParen(5);
+ } else {
+ throw new IllegalArgumentException("'" + uri +
+ "' is not a correct URI");
+ }
+ }
+
+ /**
+ * Return the query of a URI. The query is a string of information to
+ * be interpreted by the resource
+ * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+ *
+ * @param uri Uniform resource identifier.
+ *
+ * @return Query of the URI.
+ */
+ public static String getQuery(String uri) {
+ RE re = new RE(uripattern);
+ if (re.match(uri)) {
+ return re.getParen(7);
+ } else {
+ throw new IllegalArgumentException("'" + uri +
+ "' is not a correct URI");
+ }
+ }
+
+ /**
+ * Return the fragment of a URI. When a URI reference is used to perform
+ * a retrieval action on the identified resource, the optional fragment
+ * identifier, consists of additional reference information to be
+ * interpreted by the user agent after the retrieval action has been
+ * successfully completed
+ * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+ *
+ * @param uri Uniform resource identifier.
+ *
+ * @return Fragment of the URI.
+ */
+ public static String getFragment(String uri) {
+ RE re = new RE(uripattern);
+ if (re.match(uri)) {
+ return re.getParen(9);
+ } else {
+ throw new IllegalArgumentException("'" + uri +
+ "' is not a correct URI");
+ }
+ }
+
+}
Modified: cocoon/trunk/core/cocoon-pipeline/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-pipeline/pom.xml?view=diff&rev=490567&r1=490566&r2=490567
==============================================================================
--- cocoon/trunk/core/cocoon-pipeline/pom.xml (original)
+++ cocoon/trunk/core/cocoon-pipeline/pom.xml Wed Dec 27 13:10:05 2006
@@ -35,5 +35,6 @@
<modules>
<module>cocoon-pipeline-api</module>
<module>cocoon-pipeline-impl</module>
+ <module>cocoon-pipeline-components</module>
</modules>
</project>