Package org.apache.cocoon.components.source.impl

Source Code of org.apache.cocoon.components.source.impl.TraversableCachingSource$TraversableSourceMeta

/*
* 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.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
import org.apache.excalibur.source.TraversableSource;

/**
* Traversable version of {@link org.apache.cocoon.components.source.impl.CachingSource}.
*/
public class TraversableCachingSource extends CachingSource implements TraversableSource {

    private CachingSourceFactory factory;

    public TraversableCachingSource(final CachingSourceFactory factory,
                                    final String protocol,
                                    final String uri,
                                    final String sourceUri,
                                    TraversableSource source,
                                    int expires,
                                    String cacheName,
                                    boolean async,
                                    CachingSourceValidityStrategy validityStrategy,
                                    boolean fail) {
        super(protocol, uri, sourceUri, source, expires, cacheName, async, validityStrategy, fail);
        this.factory = factory;
    }

    private TraversableSource getTraversableSource() {
        return (TraversableSource) super.source;
    }

    private TraversableSourceMeta getTraversableResponseMeta() throws IOException {
        return (TraversableSourceMeta) getResponseMeta();
    }

    // ---------------------------------------------------- TraversableSource implementation

    public String getName() {
        try {
            return getTraversableResponseMeta().getName();
        } catch (IOException e) {
            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Failure initializing traversable response", e);
            }
            return null;
        }
    }

    public boolean isCollection() {
        try {
            return getTraversableResponseMeta().isCollection();
        } catch (IOException e) {
            if (getLogger().isDebugEnabled()) {
                getLogger().debug("Failure initializing traversable response", e);
            }
            return false;
        }
    }

    public Source getChild(String name) throws SourceException {
        if (!isCollection()) {
            throw new SourceException("Source is not a collection");
        }

        Source child;
        try {
            getResponseMeta();
            child = getTraversableSource().getChild(name);
        } catch (SourceException e) {
            throw e;
        } catch (IOException e) {
            throw new SourceException("Failure getting child", e);
        }

        boolean isCollection = false;
        if (child instanceof TraversableSource) {
            isCollection = ((TraversableSource) child).isCollection();
        }

        return createSource(getChildURI(super.uri, isCollection, name), getChildURI(super.sourceUri, isCollection, name), child);
    }

    public Collection getChildren() throws SourceException {
        final TraversableSourceMeta meta;
        try {
            meta = getTraversableResponseMeta();
        } catch (SourceException e) {
            throw e;
        } catch (IOException e) {
            throw new SourceException("Failure getting child", e);
        }

        if (!isCollection()) {
            throw new SourceException("Source is not a collection");
        }

        final Collection result = new ArrayList();
        final String[] children = meta.getChildren();
        for (int i = 0; i < children.length; i++) {
            Source child;
            try {
                child = getTraversableSource().getChild(children[i]);
            } catch (IOException e) {
                throw new SourceException("Failure getting child", e);
            }

            boolean isCollection = false;
            if (child instanceof TraversableSource) {
                isCollection = ((TraversableSource) child).isCollection();
            }

            result.add(createSource(getChildURI(super.uri, isCollection, children[i]), getChildURI(super.sourceUri, isCollection, children[i]), child));
        }

        return result;
    }

    public Source getParent() throws SourceException {
        Source parent;
        try {
            getResponseMeta();
            parent = getTraversableSource().getParent();
        } catch (SourceException e) {
            throw e;
        } catch (IOException e) {
            throw new SourceException("Failure getting parent", e);
        }

        return createSource(getParentURI(super.uri), getParentURI(super.sourceUri), parent);
    }


    // ---------------------------------------------------- helper methods

    protected final TraversableCachingSource createSource(String uri, String wrappedUri, Source wrapped)
    throws SourceException {
        return (TraversableCachingSource) this.factory.createCachingSource(uri, wrappedUri, wrapped, expires, cacheName, fail);
    }

    protected SourceMeta readMeta(Source source) throws SourceException {
        return new TraversableSourceMeta(source);
    }

    /**
     * Calculate the cached child URI based on a parent URI
     * and a child name.
     */
    private static String getChildURI(String parentURI, boolean isCollection, String childName) {
        // separate query string from rest of parentURI
        String rest, qs;
        int index = parentURI.indexOf('?');
        if (index != -1) {
            rest = parentURI.substring(0,index);
            qs = parentURI.substring(index);
        } else {
            rest = parentURI;
            qs = "";
        }

        // calculate child uri
        StringBuffer childURI = new StringBuffer(rest);
        if (rest.charAt(rest.length()-1) != '/') {
            childURI.append('/');
        }
        childURI.append(childName);
        if (isCollection) {
            childURI.append('/');
        }
        childURI.append(qs);
        return childURI.toString();
    }

    /**
     * Calculate the cached parent URI based on a child URI.
     */
    private static String getParentURI(String childURI) {
        // separate query string from rest of uri
        String rest, qs;
        int index = childURI.indexOf('?');
        if (index != -1) {
            rest = childURI.substring(0, index);
            qs = childURI.substring(index);
        } else {
            rest = childURI;
            qs = "";
        }

        // calculate qs-less parent uri
        String parentUri;
        index = rest.lastIndexOf('/', rest.length() - 2);
        if (index != -1) {
            parentUri = rest.substring(0, index + 1);
        } else {
            parentUri = rest;
        }

        return parentUri + qs;
    }

    protected static class TraversableSourceMeta extends SourceMeta {
        private String   m_name;
        private boolean  m_isCollection;
        private String[] m_children;

        public TraversableSourceMeta() {
            super();
        }

        public TraversableSourceMeta(Source source) throws SourceException {
            super(source);

            final TraversableSource tsource = (TraversableSource) source;

            setName(tsource.getName());
            setIsCollection(tsource.isCollection());

            if (isCollection()) {
                final Collection children = tsource.getChildren();
                if (children != null) {
                    final String[] names = new String[children.size()];
                    final Iterator iter = children.iterator();
                    int count = 0;
                    while(iter.hasNext()) {
                        TraversableSource child = (TraversableSource) iter.next();
                        names[count] = child.getName();
                        count++;
                    }
                    setChildren(names);
                }
            }
        }

        protected String getName() {
            return m_name;
        }

        protected void setName(String name) {
            m_name = name;
        }

        protected boolean isCollection() {
            return m_isCollection;
        }

        protected void setIsCollection(boolean isCollection) {
            m_isCollection = isCollection;
        }

        protected String[] getChildren() {
            return m_children;
        }

        protected void setChildren(String[] children) {
            m_children = children;
        }
    }

}
TOP

Related Classes of org.apache.cocoon.components.source.impl.TraversableCachingSource$TraversableSourceMeta

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.