Author: cziegeler Date: Tue Jan 18 07:15:05 2005 New Revision: 125512 URL: http://svn.apache.org/viewcvs?view=rev&rev=125512 Log: Add first hacky implementation for traversable context source - NOT TESTED Added: cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/TraversableContextSource.java (contents, props changed) Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java
Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java?view=diff&rev=125512&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java&r1=125511&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java&r2=125512 ============================================================================== --- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java (original) +++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CoreServiceManager.java Tue Jan 18 07:15:05 2005 @@ -69,6 +69,9 @@ */ public static final Configuration EMPTY_CONFIGURATION = new DefaultConfiguration("-", "unknown location"); + /** Parameter map for the context protocol */ + protected static final Map CONTEXT_PARAMETERS = Collections.singletonMap("force-traversable", Boolean.TRUE); + /** The application context for components */ protected Context context; @@ -674,7 +677,7 @@ final String ending = includeStatement.getAttribute("postfix", null); Source directory = null; try { - directory = this.cachedSourceResolver.resolveURI(directoryURI, contextURI, null); + directory = this.cachedSourceResolver.resolveURI(directoryURI, contextURI, CONTEXT_PARAMETERS); if ( directory instanceof TraversableSource ) { final Iterator children = ((TraversableSource)directory).getChildren().iterator(); while ( children.hasNext() ) { Modified: cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java?view=diff&rev=125512&p1=cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java&r1=125511&p2=cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java&r2=125512 ============================================================================== --- cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java (original) +++ cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/ContextSourceFactory.java Tue Jan 18 07:15:05 2005 @@ -20,6 +20,10 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.Contextualizable; @@ -30,11 +34,14 @@ import org.apache.avalon.framework.thread.ThreadSafe; import org.apache.cocoon.Constants; import org.apache.cocoon.environment.Context; +import org.apache.cocoon.servlet.CocoonServlet; +import org.apache.commons.lang.BooleanUtils; import org.apache.excalibur.source.Source; import org.apache.excalibur.source.SourceException; import org.apache.excalibur.source.SourceFactory; import org.apache.excalibur.source.SourceResolver; import org.apache.excalibur.source.SourceUtil; +import org.apache.excalibur.source.TraversableSource; import org.apache.excalibur.source.URIAbsolutizer; /** @@ -45,7 +52,7 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @author <a href="http://www.apache.org/~sylvain">Sylvain Wallez</a> - * @version CVS $Id: ContextSourceFactory.java,v 1.8 2004/06/16 14:29:31 vgritsenko Exp $ + * @version CVS $Id$ */ public class ContextSourceFactory extends AbstractLogEnabled @@ -61,6 +68,9 @@ /** The ServiceManager */ protected ServiceManager manager; + /** Http servlet context - if available */ + protected ServletContext servletContext; + /* (non-Javadoc) * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager) */ @@ -74,6 +84,11 @@ public void contextualize(org.apache.avalon.framework.context.Context context) throws ContextException { this.envContext = (Context)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); + try { + this.servletContext = ((ServletConfig) context.get(CocoonServlet.CONTEXT_SERVLET_CONFIG)).getServletContext(); + } catch (ContextException ignore) { + // in other environments (CLI etc.), we don't have a servlet context + } } /* (non-Javadoc) @@ -110,13 +125,21 @@ } if (u != null) { - return resolver.resolveURI(u.toExternalForm()); - - } else { - String message = location + " could not be found. (possible context problem)"; - getLogger().info(message); - throw new MalformedURLException(message); - } + Source source = resolver.resolveURI(u.toExternalForm()); + if ( parameters != null + && BooleanUtils.toBoolean("force-traversable") + && this.servletContext != null + && !(source instanceof TraversableSource) ) { + final Set children = this.servletContext.getResourcePaths(path + '/'); + if ( children != null ) { + source = new TraversableContextSource(source, children, this, path); + } + } + return source; + } + final String message = location + " could not be found. (possible context problem)"; + this.getLogger().info(message); + throw new MalformedURLException(message); } catch (ServiceException se) { throw new SourceException("Unable to lookup source resolver.", se); } finally { @@ -139,8 +162,13 @@ SourceResolver resolver = null; try { resolver = (SourceResolver)this.manager.lookup( SourceResolver.ROLE ); - resolver.release( source ); + if ( source instanceof TraversableContextSource ) { + resolver.release(((TraversableContextSource)source).wrappedSource); + } else { + resolver.release( source ); + } } catch (ServiceException ingore) { + // we ignore this } finally { this.manager.release( resolver ); } Added: cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/TraversableContextSource.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/TraversableContextSource.java?view=auto&rev=125512 ============================================================================== --- (empty file) +++ cocoon/trunk/src/java/org/apache/cocoon/components/source/impl/TraversableContextSource.java Tue Jan 18 07:15:05 2005 @@ -0,0 +1,196 @@ +/* + * Copyright 1999-2005 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.cocoon.components.source.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.excalibur.source.Source; +import org.apache.excalibur.source.SourceException; +import org.apache.excalibur.source.SourceNotFoundException; +import org.apache.excalibur.source.SourceValidity; +import org.apache.excalibur.source.TraversableSource; + +/** + * @version SVN $Id: ContextSourceFactory.java 30941 2004-07-29 19:56:58Z vgritsenko $ + */ +public class TraversableContextSource +implements Source, TraversableSource { + + final protected Source wrappedSource; + final protected Set children; + final protected ContextSourceFactory factory; + final protected String path; + + public TraversableContextSource(Source source, + Set children, + ContextSourceFactory factory, + String path) { + this.wrappedSource = source; + this.children = children; + this.factory = factory; + this.path = path; + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#exists() + */ + public boolean exists() { + return this.wrappedSource.exists(); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#getContentLength() + */ + public long getContentLength() { + return this.wrappedSource.getContentLength(); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#getInputStream() + */ + public InputStream getInputStream() + throws IOException, SourceNotFoundException { + return this.wrappedSource.getInputStream(); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#getLastModified() + */ + public long getLastModified() { + return this.wrappedSource.getLastModified(); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#getMimeType() + */ + public String getMimeType() { + return this.wrappedSource.getMimeType(); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#getScheme() + */ + public String getScheme() { + return this.wrappedSource.getScheme(); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#getURI() + */ + public String getURI() { + return this.wrappedSource.getURI(); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#getValidity() + */ + public SourceValidity getValidity() { + return this.wrappedSource.getValidity(); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.Source#refresh() + */ + public void refresh() { + this.wrappedSource.refresh(); + } + + + /* (non-Javadoc) + * @see org.apache.excalibur.source.TraversableSource#getChild(java.lang.String) + */ + public Source getChild(String name) throws SourceException { + final String postfixOne = '/' + name + '/'; + final String postfixTwo = '/' + name; + final Iterator i = this.children.iterator(); + while ( i.hasNext() ) { + String uri = (String)i.next(); + if ( uri.endsWith(postfixOne ) ){ + uri = "context:/" + uri; + uri = uri.substring(0, uri.length()-1); + try { + return this.factory.getSource(uri, null); + } catch (IOException ioe) { + throw new SourceException("Unable to get source for: " + uri); + } + } else if ( uri.endsWith(postfixTwo) ) { + uri = "context:/" + uri; + try { + return this.factory.getSource(uri, null); + } catch (IOException ioe) { + throw new SourceException("Unable to get source for: " + uri); + } + } + } + return null; + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.TraversableSource#getChildren() + */ + public Collection getChildren() throws SourceException { + final List l = new ArrayList(); + final Iterator i = this.children.iterator(); + while ( i.hasNext() ) { + String uri = (String)i.next(); + uri = "context:/" + uri; + try { + l.add(this.factory.getSource(uri, null)); + } catch (IOException ioe) { + final Iterator ci = l.iterator(); + while ( ci.hasNext() ) { + this.factory.release((Source)ci.next()); + } + throw new SourceException("Unable to get source for: " + uri); + } + } + return l; + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.TraversableSource#getName() + */ + public String getName() { + final String uri = this.wrappedSource.getURI(); + return uri.substring(uri.lastIndexOf('/')+1); + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.TraversableSource#getParent() + */ + public Source getParent() throws SourceException { + String uri = "context:/" + this.path; + uri = uri.substring(0, uri.lastIndexOf('/')); + try { + return this.factory.getSource(uri, null); + } catch (IOException ioe) { + throw new SourceException("Unable to get source for: " + uri); + } + } + + /* (non-Javadoc) + * @see org.apache.excalibur.source.TraversableSource#isCollection() + */ + public boolean isCollection() { + return true; + } +}