cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jheym...@apache.org
Subject svn commit: r330548 [11/132] - in /cocoon/whiteboard/maven2/cocoon-flat-layout: ./ cocoon-ajax-block/ cocoon-ajax-block/api/ cocoon-ajax-block/api/src/ cocoon-ajax-block/api/src/main/ cocoon-ajax-block/api/src/main/java/ cocoon-ajax-block/api/src/main/...
Date Thu, 03 Nov 2005 14:00:48 GMT
Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/BeanConfigurator.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/BeanConfigurator.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/BeanConfigurator.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/BeanConfigurator.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,484 @@
+/*
+ * Copyright 1999-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.cocoon.bean.helpers;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cocoon.bean.CocoonBean;
+import org.apache.cocoon.bean.helpers.OutputStreamListener;
+import org.apache.commons.lang.BooleanUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Static class for configuring a CocoonBean from a DOM Document object
+ *
+ * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
+ * @version CVS $Id: BeanConfigurator.java 179055 2005-05-30 14:08:23Z cziegeler $
+ */
+public class BeanConfigurator {
+
+    private static final String NODE_ROOT = "cocoon";
+
+    private static final String NODE_LOGGING = "logging";
+    private static final String ATTR_LOG_KIT = "log-kit";
+    private static final String ATTR_LOG_LEVEL = "level";
+    private static final String ATTR_LOGGER = "logger";
+
+    private static final String NODE_CONTEXT_DIR = "context-dir";
+    private static final String NODE_DEST_DIR = "dest-dir";
+    private static final String NODE_WORK_DIR = "work-dir";
+    private static final String NODE_CONFIG_FILE = "config-file";
+    private static final String NODE_URI_FILE = "uri-file";
+    private static final String NODE_CHECKSUMS_URI = "checksums-uri";
+ 
+    private static final String ATTR_CONTEXT_DIR = "context-dir";
+    private static final String ATTR_DEST_DIR = "dest-dir";
+    private static final String ATTR_WORK_DIR = "work-dir";
+    private static final String ATTR_CONFIG_FILE = "config-file";
+    private static final String ATTR_URI_FILE = "uri-file";
+    private static final String ATTR_CHECKSUMS_URI = "checksums-uri";
+    private static final String ATTR_AGENT = "user-agent";
+    private static final String ATTR_ACCEPT = "accept";
+    private static final String ATTR_DEFAULT_FILENAME = "default-filename";
+     
+    private static final String NODE_BROKEN_LINKS = "broken-links";
+    private static final String ATTR_BROKEN_LINK_REPORT_TYPE = "type";
+    private static final String ATTR_BROKEN_LINK_REPORT_FILE = "file";
+    private static final String ATTR_BROKEN_LINK_GENERATE = "generate";
+    private static final String ATTR_BROKEN_LINK_EXTENSION = "extension";
+    private static final String ATTR_BROKEN_LINK_SHOW_REFERRERS="show-referrers";
+
+    private static final String NODE_AGENT = "user-agent";
+    private static final String NODE_ACCEPT = "accept";
+
+    private static final String ATTR_FOLLOW_LINKS = "follow-links";
+    private static final String ATTR_PRECOMPILE_ONLY = "precompile-only";
+    private static final String ATTR_CONFIRM_EXTENSIONS = "confirm-extensions";
+    private static final String NODE_LOAD_CLASS = "load-class";
+    private static final String NODE_DEFAULT_FILENAME = "default-filename";
+
+    private static final String NODE_INCLUDE = "include";
+    private static final String NODE_EXCLUDE = "exclude";
+    private static final String ATTR_INCLUDE_EXCLUDE_PATTERN = "pattern";
+    
+    private static final String NODE_INCLUDE_LINKS = "include-links";
+    private static final String ATTR_LINK_EXTENSION = "extension";
+    
+    private static final String NODE_URI = "uri";
+    private static final String ATTR_URI_TYPE = "type";
+    private static final String ATTR_URI_SOURCEPREFIX = "src-prefix";
+    private static final String ATTR_URI_SOURCEURI = "src";
+    private static final String ATTR_URI_DESTURI = "dest";
+
+    private static final String NODE_URIS = "uris";
+    private static final String ATTR_NAME = "name";
+    
+    public static String configure(Document xconf, CocoonBean cocoon, String destDir, String uriGroup, OutputStreamListener listener) 
+        throws IllegalArgumentException {
+
+        Node root = xconf.getDocumentElement();
+        if (!NODE_ROOT.equals(root.getNodeName())) {
+            throw new IllegalArgumentException("Expected root node of "+ NODE_ROOT);
+        }
+
+        if (hasAttribute(root, ATTR_FOLLOW_LINKS)) {
+            cocoon.setFollowLinks(getBooleanAttributeValue(root, ATTR_FOLLOW_LINKS));
+        }
+        if (hasAttribute(root, ATTR_PRECOMPILE_ONLY)) {
+            cocoon.setPrecompileOnly(getBooleanAttributeValue(root, ATTR_PRECOMPILE_ONLY));
+        }
+        if (hasAttribute(root, ATTR_CONFIRM_EXTENSIONS)) {
+            cocoon.setConfirmExtensions(getBooleanAttributeValue(root, ATTR_CONFIRM_EXTENSIONS));
+        }
+        if (hasAttribute(root, ATTR_CONTEXT_DIR)) {
+            cocoon.setContextDir(getAttributeValue(root, ATTR_CONTEXT_DIR));
+        }
+        if (hasAttribute(root, ATTR_DEST_DIR)) {
+            destDir = getAttributeValue(root, ATTR_DEST_DIR);
+        }
+        if (hasAttribute(root, ATTR_WORK_DIR)) {
+            cocoon.setWorkDir(getAttributeValue(root, ATTR_WORK_DIR));
+        }
+        if (hasAttribute(root, ATTR_CONFIG_FILE)) {
+            cocoon.setConfigFile(getAttributeValue(root, ATTR_CONFIG_FILE));
+        }
+        if (hasAttribute(root, ATTR_URI_FILE)) {
+            cocoon.addTargets(processURIFile(getAttributeValue(root, ATTR_URI_FILE)), destDir);
+        }
+        if (hasAttribute(root, ATTR_CHECKSUMS_URI)) {
+            cocoon.setChecksumURI(getAttributeValue(root, ATTR_CHECKSUMS_URI));
+        }
+        if (hasAttribute(root, ATTR_AGENT)) {
+            cocoon.setAgentOptions(getAttributeValue(root, ATTR_AGENT));
+        }
+        if (hasAttribute(root, ATTR_ACCEPT)) {
+            cocoon.setAcceptOptions(getAttributeValue(root, ATTR_ACCEPT));
+        }
+        if (hasAttribute(root, ATTR_DEFAULT_FILENAME)) {
+            cocoon.setDefaultFilename(getAttributeValue(root, ATTR_DEFAULT_FILENAME));
+        }
+
+        if (destDir == null || destDir.length() == 0) {
+            destDir = getNodeValue(root, NODE_DEST_DIR);
+        }
+ 
+        NodeList nodes = root.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeType()== Node.ELEMENT_NODE) {
+                String nodeName = node.getNodeName();
+                if (nodeName.equals(NODE_BROKEN_LINKS)) {
+                    parseBrokenLinkNode(cocoon, node, listener);
+
+                } else if (nodeName.equals(NODE_LOAD_CLASS)) {
+                    cocoon.addLoadedClass(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_LOGGING)) {
+                    parseLoggingNode(cocoon, node);
+
+                } else if (nodeName.equals(NODE_CONTEXT_DIR)) {
+                    if (hasAttribute(root, ATTR_CONTEXT_DIR)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_CONTEXT_DIR+" as both element and attribute");
+                    }
+                    cocoon.setContextDir(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_CONFIG_FILE)) {
+                    if (hasAttribute(root, ATTR_CONFIG_FILE)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_CONFIG_FILE+" as both element and attribute");
+                    }
+                    cocoon.setConfigFile(getNodeValue(node));
+                } else if (nodeName.equals(NODE_DEST_DIR)) {
+                    // Ignore
+
+                } else if (nodeName.equals(NODE_WORK_DIR)) {
+                    if (hasAttribute(root, ATTR_WORK_DIR)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_WORK_DIR+" as both element and attribute");
+                    }
+                    cocoon.setWorkDir(getNodeValue(node));
+                } else if (nodeName.equals(NODE_CHECKSUMS_URI)) {
+                    if (hasAttribute(root, ATTR_CHECKSUMS_URI)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_CHECKSUMS_URI+" as both element and attribute");
+                    }
+                    cocoon.setChecksumURI(getNodeValue(node));
+                } else if (nodeName.equals(NODE_AGENT)) {
+                    cocoon.setAgentOptions(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_ACCEPT)) {
+                    cocoon.setAcceptOptions(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_DEFAULT_FILENAME)) {
+                    cocoon.setDefaultFilename(getNodeValue(node));
+
+                } else if (nodeName.equals(NODE_INCLUDE)) {
+                    String pattern = parseIncludeExcludeNode(cocoon, node, NODE_INCLUDE);
+                    cocoon.addIncludePattern(pattern);
+
+                } else if (nodeName.equals(NODE_EXCLUDE)) {
+                    String pattern = parseIncludeExcludeNode(cocoon, node, NODE_EXCLUDE);
+                    cocoon.addExcludePattern(pattern);
+
+                } else if (nodeName.equals(NODE_INCLUDE_LINKS)) {
+                    parseIncludeLinksNode(cocoon, node);
+
+                } else if (nodeName.equals(NODE_URI)) {
+                    parseURINode(cocoon, node, destDir);
+
+                } else if (nodeName.equals(NODE_URIS)) {
+                    parseURIsNode(cocoon, node, destDir, uriGroup);
+
+                } else if (nodeName.equals(NODE_URI_FILE)) {
+                    if (hasAttribute(root, ATTR_URI_FILE)) {
+                        throw new IllegalArgumentException("Cannot have "+NODE_URI_FILE+" as both element and attribute");
+                    }
+                    cocoon.addTargets(processURIFile(getNodeValue(node)), destDir);
+                } else {
+                    throw new IllegalArgumentException("Unknown element: <" + nodeName + ">");
+                }
+            }
+        }
+        return destDir;
+    }
+
+    private static void parseLoggingNode(CocoonBean cocoon, Node node) throws IllegalArgumentException {
+        if (hasAttribute(node, ATTR_LOG_KIT)) {
+            cocoon.setLogKit(getAttributeValue(node, ATTR_LOG_KIT));
+        }
+        if (hasAttribute(node, ATTR_LOGGER)) {
+            cocoon.setLogger(getAttributeValue(node, ATTR_LOGGER));
+        }
+        if (hasAttribute(node, ATTR_LOG_LEVEL)) {
+            cocoon.setLogLevel(getAttributeValue(node, ATTR_LOG_LEVEL));
+        }
+        NodeList nodes = node.getChildNodes();
+        if (nodes.getLength()!=0) {
+            throw new IllegalArgumentException("Unexpected children of <" + NODE_LOGGING + "> node");
+        }
+    }
+
+    private static void parseIncludeLinksNode(CocoonBean cocoon, Node node) throws IllegalArgumentException {
+        if (hasAttribute(node, ATTR_LINK_EXTENSION)) {
+            cocoon.addIncludeLinkExtension(getAttributeValue(node, ATTR_LINK_EXTENSION));
+        }
+    }
+
+    private static void parseBrokenLinkNode(CocoonBean cocoon, Node node, OutputStreamListener listener) throws IllegalArgumentException {
+        if (hasAttribute(node, ATTR_BROKEN_LINK_REPORT_FILE)) {
+            listener.setReportFile(getAttributeValue(node, ATTR_BROKEN_LINK_REPORT_FILE));
+        }
+        if (hasAttribute(node, ATTR_BROKEN_LINK_REPORT_TYPE)) {
+            listener.setReportType(getAttributeValue(node, ATTR_BROKEN_LINK_REPORT_TYPE));
+        }
+        if (hasAttribute(node, ATTR_BROKEN_LINK_GENERATE)) {
+            cocoon.setBrokenLinkGenerate(getBooleanAttributeValue(node, ATTR_BROKEN_LINK_GENERATE));
+        }
+        if (hasAttribute(node, ATTR_BROKEN_LINK_EXTENSION)) {
+            cocoon.setBrokenLinkExtension(getAttributeValue(node, ATTR_BROKEN_LINK_EXTENSION));
+        }
+        if (hasAttribute(node, ATTR_BROKEN_LINK_SHOW_REFERRERS)) {
+            listener.setIsShowingReferrers(getBooleanAttributeValue(node, ATTR_BROKEN_LINK_SHOW_REFERRERS));
+        }
+        NodeList nodes = node.getChildNodes();
+        if (nodes.getLength()!=0) {
+            throw new IllegalArgumentException("Unexpected children of <" + NODE_BROKEN_LINKS + "> node");
+        }
+    }
+
+    private static String parseIncludeExcludeNode(CocoonBean cocoon, Node node, final String NODE_TYPE) throws IllegalArgumentException {
+        NodeList nodes = node.getChildNodes();
+        if (nodes.getLength() != 0) {
+            throw new IllegalArgumentException("Unexpected children of <" + NODE_INCLUDE + "> node");
+        }
+
+        if (hasAttribute(node, ATTR_INCLUDE_EXCLUDE_PATTERN)) {
+            return getAttributeValue(node, ATTR_INCLUDE_EXCLUDE_PATTERN);
+        }
+        throw new IllegalArgumentException("Expected a "+ATTR_INCLUDE_EXCLUDE_PATTERN+" attribute for <"+NODE_TYPE+"> node");
+    }
+
+    private static void parseURIsNode(CocoonBean cocoon, Node node, String destDir, String uriGroup) throws IllegalArgumentException {
+
+        boolean followLinks = cocoon.followLinks();
+        boolean confirmExtensions = cocoon.confirmExtensions();
+        String logger = cocoon.getLoggerName();
+        String destURI = destDir;
+        String root = null;
+        String type = null;
+        String name = null;
+        
+        if (hasAttribute(node, ATTR_FOLLOW_LINKS)) {
+            followLinks = getBooleanAttributeValue(node, ATTR_FOLLOW_LINKS);
+        }
+        if (hasAttribute(node, ATTR_CONFIRM_EXTENSIONS)) {
+            confirmExtensions = getBooleanAttributeValue(node, ATTR_CONFIRM_EXTENSIONS);
+        }
+        if (hasAttribute(node, ATTR_URI_TYPE)) {
+            type = getAttributeValue(node, ATTR_URI_TYPE);
+        }
+        if (hasAttribute(node, ATTR_URI_SOURCEPREFIX)) {
+            root = getAttributeValue(node, ATTR_URI_SOURCEPREFIX);
+        }
+        if (hasAttribute(node, ATTR_URI_DESTURI)) {
+            destURI = getAttributeValue(node, ATTR_URI_DESTURI);
+        }
+        if (hasAttribute(node, ATTR_LOGGER)) {
+            logger = getAttributeValue(node, ATTR_LOGGER);
+        }
+        if (hasAttribute(node, ATTR_NAME)) {
+            name = getAttributeValue(node, ATTR_NAME);
+            if (name != null && uriGroup != null && !name.equals(uriGroup)) {
+                // The user has not selected this URI group, so ignore it.
+                return;
+            }
+        }
+        NodeList nodes = node.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node child = nodes.item(i);
+            if (child.getNodeType()== Node.ELEMENT_NODE) {
+                String childName = child.getNodeName();
+                if (childName.equals(NODE_URI)) {
+                    String _sourceURI = null;
+                    String _destURI = destURI;
+                    String _root = root;
+                    String _type = type;
+                    
+                    if (child.getAttributes().getLength() == 0) {
+                        _sourceURI = getNodeValue(child);
+                        //destURI is inherited 
+                    } else {
+                        _sourceURI = getAttributeValue(child, ATTR_URI_SOURCEURI);
+
+                        if (hasAttribute(child, ATTR_URI_TYPE)) {
+                            _type = getAttributeValue(child, ATTR_URI_TYPE);
+                        }
+                        if (hasAttribute(child, ATTR_URI_SOURCEPREFIX)) {
+                            _root = getAttributeValue(child, ATTR_URI_SOURCEPREFIX);
+                        }
+                        if (hasAttribute(child, ATTR_URI_DESTURI)) {
+                            _destURI = getAttributeValue(child, ATTR_URI_DESTURI);
+                        }
+                    }
+                    cocoon.addTarget(_type, _root, _sourceURI, _destURI, followLinks, confirmExtensions, logger);
+                } else {
+                    throw new IllegalArgumentException("Unknown element: <" + childName + ">");
+                }
+            }
+        }
+    }
+        
+    private static void parseURINode(CocoonBean cocoon, Node node, String destDir) throws IllegalArgumentException {
+        NodeList nodes = node.getChildNodes();
+
+        if (node.getAttributes().getLength() == 0 && nodes.getLength() != 0) {
+            cocoon.addTarget(getNodeValue(node), destDir);
+        } else if (node.getAttributes().getLength() !=0 && nodes.getLength() ==0){
+
+            String src = getAttributeValue(node, ATTR_URI_SOURCEURI);
+
+            String type = null;
+            if (hasAttribute(node, ATTR_URI_TYPE)) {
+                type = getAttributeValue(node, ATTR_URI_TYPE);
+            }
+            String root = null;
+            if (hasAttribute(node, ATTR_URI_SOURCEPREFIX)) {
+                root = getAttributeValue(node, ATTR_URI_SOURCEPREFIX);
+            }
+            String dest = null;
+            if (hasAttribute(node, ATTR_URI_DESTURI)) {
+                dest = getAttributeValue(node, ATTR_URI_DESTURI);
+            }
+
+            if (root != null && type != null & dest != null) {
+                cocoon.addTarget(type, root, src, dest);
+            } else if (root != null & dest != null) {
+                cocoon.addTarget(root, src, dest);
+            } else if (dest != null) {
+                cocoon.addTarget(src, dest);
+            } else {
+                cocoon.addTarget(src, destDir);
+            }
+        } else if (node.getAttributes().getLength() !=0 && nodes.getLength() != 0) {
+            throw new IllegalArgumentException("Unexpected children of <" + NODE_URI + "> node");
+        } else {
+            throw new IllegalArgumentException("Not enough information for <"+ NODE_URI + "> node");
+        }
+    }
+
+    private static String getNodeValue(Node root, String name) throws IllegalArgumentException {
+        NodeList nodes = root.getChildNodes();
+        for (int i = 0; i < nodes.getLength(); i++) {
+            Node node = nodes.item(i);
+            if (node.getNodeType()== Node.ELEMENT_NODE) {
+                String nodeName = node.getNodeName();
+                if (nodeName.equals(name)) {
+                    return getNodeValue(node);
+                }
+            }
+        }
+        return null;
+    }
+
+    private static String getNodeValue(Node node) throws IllegalArgumentException {
+        StringBuffer s = new StringBuffer();
+        NodeList children = node.getChildNodes();
+        boolean found = false;
+
+        for (int i = 0; i < children.getLength(); i++) {
+            Node child = children.item(i);
+            if (child.getNodeType() == Node.TEXT_NODE) {
+                s.append(child.getNodeValue());
+                found = true;
+            } else {
+                throw new IllegalArgumentException("Unexpected node:" + child.getLocalName());
+            }
+        }
+        if (!found) {
+            throw new IllegalArgumentException("Expected value for " + node.getLocalName() + " node");
+        }
+        return s.toString();
+    }
+
+    private static String getAttributeValue(Node node, String attr) throws IllegalArgumentException {
+        NamedNodeMap nodes = node.getAttributes();
+        if (nodes != null) {
+            Node attribute = nodes.getNamedItem(attr);
+            if (attribute != null && attribute.getNodeValue() != null) {
+                return attribute.getNodeValue();
+            }
+        }
+        throw new IllegalArgumentException("Missing " + attr + " attribute on <" + node.getNodeName() + "> node");
+    }
+
+    private static boolean hasAttribute(Node node, String attr) {
+        NamedNodeMap nodes = node.getAttributes();
+        if (nodes != null) {
+            Node attribute = nodes.getNamedItem(attr);
+            return (attribute != null);
+        }
+        return false;
+    }
+
+    private static boolean getBooleanAttributeValue(Node node, String attr) {
+        NamedNodeMap nodes = node.getAttributes();
+        if (nodes != null) {
+            Node attribute = nodes.getNamedItem(attr);
+
+            if (attribute != null) {
+                String value = attribute.getNodeValue();
+                return BooleanUtils.toBoolean(value);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * <code>processURIFile</code> method.
+     *
+     * @param filename a <code>String</code> value
+     * @return uris a <code>List</code> of URIs
+     */
+    public static List processURIFile(String filename) {
+        List uris = new ArrayList();
+        try {
+            BufferedReader uriFile = new BufferedReader(new FileReader(filename));
+
+            while (true) {
+                String uri = uriFile.readLine();
+
+                if (null == uri) {
+                    break;
+                }
+                
+                uri = uri.trim();
+                if (!uri.equals("") && !uri.startsWith("#")){
+                    uris.add(uri.trim());
+                }
+            }
+
+            uriFile.close();
+        } catch (Exception e) {
+            // ignore errors.
+        }
+        return uris;
+    }
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/BeanConfigurator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/Crawler.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/Crawler.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/Crawler.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/Crawler.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,138 @@
+/*
+ * Copyright 1999-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.cocoon.bean.helpers;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.cocoon.bean.Target;
+
+/**
+ *   A simple Cocoon crawler
+ *
+ * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
+ * @version CVS $Id: Crawler.java 179055 2005-05-30 14:08:23Z cziegeler $
+ */
+
+public class Crawler {
+
+    private Map allTranslatedLinks;
+    private Map stillNotVisited;
+    private Map visitedAlready;
+    
+    public Crawler() {
+        visitedAlready = new HashMap();
+        stillNotVisited = new HashMap();
+        allTranslatedLinks = new HashMap();
+    }
+    
+    /**
+     * Add a target for future processing
+     */
+    public boolean addTarget(Target target) {
+        String targetString = target.toString();
+        if (!visitedAlready.containsKey(targetString)) {
+            if (!stillNotVisited.containsKey(targetString)) {
+                stillNotVisited.put(targetString, target);
+                return true;
+            }
+            Target existingTarget = (Target)stillNotVisited.get(targetString);
+            existingTarget.addReferringURI(target.getReferringURI());
+        } else {
+            Target visitedTarget = (Target)visitedAlready.get(targetString);
+            visitedTarget.addReferringURI(target.getReferringURI());
+        }
+        
+        return false;
+    }
+
+    /**
+     * Returns the number of targets for processing
+     */
+    public int getRemainingCount() {
+        return stillNotVisited.size();
+    }
+    
+    public int getProcessedCount() {
+        return visitedAlready.size();
+    }
+    
+    public int getTranslatedCount() {
+        return allTranslatedLinks.size();
+    }
+    
+    public void addTranslatedLink(Target target) {
+        allTranslatedLinks.put(target.getSourceURI(), target);
+    }
+    
+    public boolean hasTranslatedLink(Target link) {
+        return allTranslatedLinks.get(link.getSourceURI())!=null;
+    }
+    
+    public Target getTranslatedLink(Target link) {
+        return (Target) allTranslatedLinks.get(link.getSourceURI());
+    }
+    
+    /**
+     * Returns an iterator for reading targets
+     */
+    public CrawlingIterator iterator() {
+        return new CrawlingIterator(visitedAlready, stillNotVisited);
+    }
+    
+    public class CrawlingIterator implements Iterator {
+
+        private Map stillNotVisited;
+        private Map visitedAlready;
+        
+        public CrawlingIterator(Map visitedAlready, Map stillNotVisited) {
+            this.visitedAlready = visitedAlready;
+            this.stillNotVisited = stillNotVisited;
+        }
+
+        /**
+         *   Check if list of not visited URIs is empty
+         *
+         * @return    boolean true iff list of not visited URIs is not empty
+         */
+        public boolean hasNext() {
+            return !stillNotVisited.isEmpty();
+        }
+
+        /**
+         *   Removing objects is not supported, and will always throw
+         *   a <code>UnsupportedOperationException</code>.
+         */
+        public void remove(){ 
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         *   Get next not visited URIs
+         *
+         * @return    object from list of not visited URIs, move it immediatly
+         *   to set of visited URIs
+         */
+        public Object next() {
+            // could this be simpler:
+            Object nextKey = stillNotVisited.keySet().toArray()[0];
+            Object nextElement = stillNotVisited.remove(nextKey);
+            visitedAlready.put(nextKey, nextElement);
+            return nextElement;
+        }
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/Crawler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/DelayedOutputStream.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/DelayedOutputStream.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/DelayedOutputStream.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/DelayedOutputStream.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,236 @@
+/*
+ * Copyright 1999-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.cocoon.bean.helpers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ *   A output stream writing to a ByteArrayOutputStream, until an OutputStream target is defined.
+ *
+ * @author    huber@apache.org
+ * @author    uv@upaya.co.uk
+ * @version CVS $Id: DelayedOutputStream.java 179055 2005-05-30 14:08:23Z cziegeler $
+ */
+public class DelayedOutputStream extends OutputStream {
+    /**
+     * write to baos as long as fos member is still null,
+     * create a ByteArrayOutputStream only
+     */
+    private ByteArrayOutputStream baos;
+    /**
+     * If fos is defined write into fos, dump content of
+     * baos to fos first
+     */
+    private OutputStream fos;
+
+
+    /**
+     * Constructor for the DelayedFileOutputStream object,
+     * create a ByteArrayOutputStream only
+     */
+    public DelayedOutputStream() {
+        baos = new ByteArrayOutputStream();
+        fos = null;
+    }
+
+    /**
+     * Creates a file output stream to write to the file represented by the specified File object.
+     *
+     * @param  outputStream               The new fileOutputStream value
+     */
+    public void setFileOutputStream(OutputStream outputStream) {
+        if (fos == null) {
+            fos = outputStream;
+        }
+    }
+
+    /**
+     *   Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
+     *   state of this stream
+     *
+     * @param  b                Description of Parameter
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or writing
+     *   of baos, or fos fails
+     */
+    public void write(int b) throws IOException {
+        OutputStream os = getTargetOutputStream();
+        os.write(b);
+    }
+
+
+    /**
+     *   Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
+     *   state of this stream
+     *
+     * @param  b                Description of Parameter
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or writing
+     *   of baos, or fos fails
+     */
+    public void write(byte b[]) throws IOException {
+        OutputStream os = getTargetOutputStream();
+        os.write(b);
+    }
+
+
+    /**
+     *   Write into ByteArrayOutputStrem, or FileOutputStream, depending on inner
+     *   state of this stream
+     *
+     * @param  b                Description of Parameter
+     * @param  off              Description of Parameter
+     * @param  len              Description of Parameter
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or writing
+     *   of baos, or fos fails
+     */
+    public void write(byte b[], int off, int len) throws IOException {
+        OutputStream os = getTargetOutputStream();
+        os.write(b, off, len);
+    }
+
+
+    /**
+     *   Close ByteArrayOutputStrem, and FileOutputStream, depending on inner
+     *   state of this stream
+     *
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or closing
+     *   of baos, or fos fails
+     */
+    public void close() throws IOException {
+        IOException ioexception = null;
+
+        getTargetOutputStream();
+
+        // close baos
+        try {
+            if (baos != null) {
+                baos.close();
+            }
+        } catch (IOException ioe) {
+            ioexception = ioe;
+        } finally {
+            baos = null;
+        }
+
+        // close fos
+        try {
+            if (fos != null) {
+                fos.close();
+            }
+        } catch (IOException ioe) {
+            if (ioexception == null) {
+                ioexception = ioe;
+            }
+        } finally {
+            fos = null;
+        }
+
+        if (ioexception != null) {
+            throw ioexception;
+        }
+    }
+
+
+    /**
+     *   Flush ByteArrayOutputStrem, writing content to FileOutputStream,
+     *   flush FileOutputStream
+     *
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails, or flushing
+     *   of baos, or fos fails
+     */
+    public void flush() throws IOException {
+        IOException ioexception = null;
+
+        // flush baos, writing to fos, if neccessary
+        getTargetOutputStream();
+
+        // flush baos
+        try {
+            if (baos != null) {
+                baos.flush();
+            }
+        } catch (IOException ioe) {
+            ioexception = ioe;
+        }
+
+        // flush fos
+        try {
+            if (fos != null) {
+                fos.flush();
+            }
+        } catch (IOException ioe) {
+            if (ioexception == null) {
+                ioexception = ioe;
+            }
+        }
+        if (ioexception != null) {
+            throw ioexception;
+        }
+    }
+
+
+    /**
+     *   Gets the targetOutputStream attribute of the DelayedFileOutputStream object
+     *
+     * @return                  The targetOutputStream value
+     * @exception  IOException  thrown iff implicitly flush of baos to fos fails
+     */
+    private OutputStream getTargetOutputStream() throws IOException {
+        if (baos != null && fos == null) {
+
+            // no fos is defined, just write to baos in the mean time
+            return baos;
+        } else if (baos != null && fos != null) {
+            // fos is defined, flush boas to fos, and destroy baos
+            try {
+                baos.flush();
+                baos.writeTo(fos);
+                baos.close();
+            } finally {
+                baos = null;
+            }
+
+            return fos;
+        } else if (baos == null && fos != null) {
+            // no more temporary baos writing, write directly to fos
+            return fos;
+        } else {
+            // neither baos, nor fos are valid
+            throw new IOException("No outputstream available!");
+        }
+    }
+
+    /**
+     * Gets the size of the content of the current output stream
+     */
+    public int size() {
+        if (baos != null) {
+            return baos.size();
+        }
+        return 0;
+    }
+
+    /**
+     * Return the contents of the stream as a byte array
+     */
+    public byte[] getContent() {
+        if (baos != null) {
+            return baos.toByteArray();
+        }
+        return null;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/DelayedOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/OutputStreamListener.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/OutputStreamListener.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/OutputStreamListener.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/OutputStreamListener.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,222 @@
+/*
+ * Copyright 1999-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.cocoon.bean.helpers;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.cocoon.bean.BeanListener;
+import org.apache.cocoon.bean.Target;
+
+/**
+ * Command line entry point. Parses command line, create Cocoon bean and invokes it
+ * with file destination.
+ *
+ * @author <a href="mailto:uv@upaya.co.uk">Upayavira</a>
+ * @version CVS $Id: OutputStreamListener.java 54676 2004-10-12 15:57:34Z upayavira $
+ */
+public class OutputStreamListener implements BeanListener {
+
+    private final PrintWriter writer;
+    private final Map brokenLinks = new HashMap();
+    private final long startTimeMillis;
+    private String reportFile = null;
+    private String reportType = "text";
+    private long siteSize = 0L;
+    private int sitePages = 0;
+    private boolean isShowingReferrers = false;
+    
+    public OutputStreamListener(OutputStream os) {
+        writer = new PrintWriter(os);
+        startTimeMillis = System.currentTimeMillis();
+    }
+
+    public void setReportFile(String filename) {
+        reportFile = filename;
+    }
+
+    public void setReportType(String type) {
+        reportType = type;
+    }
+
+    public void setIsShowingReferrers(boolean isShowingReferrers) {
+        this.isShowingReferrers = isShowingReferrers;
+    }
+    
+    public void pageGenerated(String sourceURI,
+                              String destinationURI,
+                              int pageSize,
+                              int linksInPage,
+                              int newLinksInPage,
+                              int pagesRemaining,
+                              int pagesComplete,
+                              long timeTaken) {
+        this.siteSize += pageSize;
+        this.sitePages++;
+
+        double time = (((double)timeTaken)/1000);
+
+        String size;
+        if (pageSize < 1024) {
+            size = pageSize + "b";
+        } else {
+            size = ((float)((int)(pageSize/102.4)))/10 + "Kb";
+        }
+
+        if (linksInPage == -1) {
+            this.print("* " + sourceURI);
+        } else {
+            this.print(pad(12, "* [" + pagesComplete + "/" + pagesRemaining + "] ") +
+                       pad(10, "[" + newLinksInPage + "/" + linksInPage + "] ") +
+                       pad(7,time + "s ") +
+                       pad(7, size) + " " +
+                       sourceURI);
+        }
+
+    }
+    public void messageGenerated(String msg) {
+        this.print(msg);
+    }
+
+    public void warningGenerated(String uri, String warning) {
+        this.print("Warning: "+warning + " when generating " + uri);
+    }
+
+    /**
+     * @deprecated use brokenLinkFound(String, List, String, Throwable) instead
+     */
+    public void brokenLinkFound(String uri, String parentURI, String message, Throwable t) {
+        this.print(pad(42,"X [0] ")+uri+"\tBROKEN: "+message);
+        brokenLinks.put(uri + "\t" + message, "");
+    }
+
+    public void brokenLinkFound(Target target, Throwable t) {
+        this.print(pad(42,"X [0] ")+target.getSourceURI()+"\tBROKEN: "+t.getMessage());
+        brokenLinks.put(target.getSourceURI() + "\t" + t.getMessage(), target);
+
+    }
+
+    public void pageSkipped(String uri, String message) {
+        this.print(pad(37, "^ ") + uri);
+    }
+
+    public void complete() {
+        outputBrokenLinks();
+
+        long duration = System.currentTimeMillis() - startTimeMillis;
+        DecimalFormat df = new DecimalFormat("###,###,##0");
+
+        this.print("Total time: " +
+                   (duration / 60000) + " minutes " +
+                   (duration % 60000)/1000 + " seconds, " +
+                   " Site size: " + df.format(this.siteSize) +
+                   " Site pages: " + this.sitePages);
+        this.close();
+    }
+
+    public boolean isSuccessful() {
+        return brokenLinks.size() == 0;
+    }
+
+    private void outputBrokenLinks() {
+        if (reportFile == null) {
+            return;
+        } else if ("text".equalsIgnoreCase(reportType)) {
+            outputBrokenLinksAsText();
+        } else if ("xml".equalsIgnoreCase(reportType)) {
+            outputBrokenLinksAsXML();
+        }
+    }
+
+    private void outputBrokenLinksAsText() {
+        PrintWriter writer;
+        try {
+            writer =
+                    new PrintWriter(
+                            new FileWriter(new File(reportFile)),
+                            true);
+            for (Iterator i = brokenLinks.keySet().iterator(); i.hasNext();) {
+                writer.println((String) i.next());
+            }
+            writer.close();
+        } catch (IOException ioe) {
+            this.print("Broken link file does not exist: " + reportFile);
+        }
+    }
+    private void outputBrokenLinksAsXML() {
+        PrintWriter writer;
+        try {
+            writer =
+                    new PrintWriter(
+                            new FileWriter(new File(reportFile)),
+                            true);
+            writer.println("<broken-links>");
+            for (Iterator i = brokenLinks.keySet().iterator(); i.hasNext();) {
+                String linkMsg = (String) i.next();
+                String uri = linkMsg.substring(0,linkMsg.indexOf('\t'));
+                String msg = linkMsg.substring(linkMsg.indexOf('\t')+1);
+                if (!isShowingReferrers) {
+                    writer.println("  <link message=\"" + msg + "\">" + uri + "</link>");
+                } else {
+                    writer.println("  <link message=\"" + msg + "\" uri=\"" + uri + "\">");
+                    Object t = brokenLinks.get(linkMsg);
+                    if (t instanceof Target) {
+                        Target target = (Target)t;
+                        for (Iterator j = target.getReferringURIs().iterator(); j.hasNext();) {
+                            String referrer=(String) j.next();
+                            writer.println("    <referrer uri=\"" + referrer + "\"/>");
+                        }
+                    }
+                    writer.println("  </link>");
+                }
+            }
+            writer.println("</broken-links>");
+            writer.close();
+        } catch (IOException ioe) {
+            this.print("Could not create broken link file: " + reportFile);
+        }
+    }
+
+    private String pad(int chars, String str) {
+        int len = str.length();
+        if (len < chars) {
+            StringBuffer sb = new StringBuffer(chars > len ? chars+1 : len+1);
+            sb.append(str);
+            for (int i=len; i<chars; i++) {
+                sb.append(" ");
+            }
+            return sb.toString();
+        }
+        return str;
+    }
+
+    private void print(String message) {
+        writer.println(message);
+        writer.flush();
+    }
+
+    private void close() {
+        // Flush the writer, but don't close the underlying stream.
+        writer.flush();
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/bean/helpers/OutputStreamListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/Cache.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/Cache.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/Cache.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/Cache.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1999-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.cocoon.caching;
+
+import java.io.Serializable;
+
+import org.apache.cocoon.ProcessingException;
+
+/**
+ * This is the Cocoon cache. This component is responsible for storing
+ * and retrieving cached responses. It can be used to monitor the cache
+ * or to investigate which responses are cached etc.
+ * This interface will grow!
+ *
+ * @since 2.1
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: Cache.java 55383 2004-10-23 15:10:46Z cziegeler $
+ */
+public interface Cache {
+
+    /** The Avalon Role **/
+    String ROLE = Cache.class.getName();
+
+    /**
+     * Store a cached response
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     * @param response    the cached response
+     */
+    void store(Serializable     key,
+               CachedResponse   response)
+    throws ProcessingException;
+
+    /**
+     * Get a cached response.
+     * If it is not available <code>null</code> is returned.
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     */
+    CachedResponse get(Serializable key);
+
+    /**
+     * Remove a cached response.
+     * If it is not available no operation is performed.
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     */
+    void remove(Serializable key);
+    
+    /**
+     * clear cache of all cached responses 
+     */
+    void clear();
+
+    /**
+     * See if a response is cached under this key.
+     */
+    boolean containsKey(Serializable key);
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/Cache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CacheableProcessingComponent.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CacheableProcessingComponent.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CacheableProcessingComponent.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CacheableProcessingComponent.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1999-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.cocoon.caching;
+
+import org.apache.excalibur.source.SourceValidity;
+import java.io.Serializable;
+
+/**
+ * This interface declares a (sitemap) component as cacheable.
+ * This interface deprecates the org.apache.cocoon.caching.Cacheable interface!
+ * <p>
+ * Just about everything can be cached, so it makes sense to provide some
+ * controls to make sure that the user always gets valid results. There are
+ * two aspects to a cacheable component: the key and the validition. The key
+ * is used to determine within the component's scheme of things whether a
+ * result is unique. For example, if your generator provides dynamic
+ * information based on an ID and a user, you want to combine the two elements
+ * into one key. That way Cocoon can determine whether to use the cached
+ * information for the given ID/User combination or create it from scratch.
+ * </p>
+ * <p>
+ * The CachingPipeline will check the component's key to see if it even has
+ * the information cached to begin with. Next, it will check the validity of
+ * the cached value if there is one. If the cache has the resource and it is
+ * valid, the CachingPipeline will return the cached results. If either
+ * condition is false, then the CachingPipeline will generate the results and
+ * cache it for later use. It is important to realize that only the
+ * <code>CachingPipeline</code> will respect the contracts defined in this
+ * interface.
+ * </p>
+ *
+ * @since 2.1
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: CacheableProcessingComponent.java 279595 2005-09-08 17:52:48Z bloritsch $
+ */
+public interface CacheableProcessingComponent {
+
+    /**
+     * Generate the unique key for the resource being rendered.
+     * <p>
+     * The cache key is the single most important part of the caching
+     * implementation. If you don't get it right, you can introduce more load
+     * on the caching engine than is necessary. It is important that the cache
+     * key has the following attributes:
+     * </p>
+     * <ul>
+     * <li>It must be Serializable (part of the contract of this method).</li>
+     * <li>It must be Immutable--the key is used as a lookup value.</li>
+     * <li>It must be Unique within the space of the component (i.e. the key
+     *     "1" for MyCacheableComponent must be for the same resource every
+     *     time, but we don't have to worry about the key "1" for
+     *     YourCacheableComponent).</li>
+     * <li>The equals() and hashCode() methods must be consistent (i.e. if two
+     *     keys are equal, the hashCode must also be equal).</li>
+     * </ul>
+     * <p>
+     * Thankfully there is a perfectly suitable object that satisfies these
+     * obligations from Java's core: <code>java.lang.String</code>. You can
+     * also use your own specific key objects provided they respect the above
+     * contracts.
+     * </p>
+     * <p>
+     * <strong>Important:</strong>If the cache key is <code>null</code> then
+     * your component will not be cached at all. You can use this to your
+     * advantage to cache some things but not others.
+     * </p>
+     *
+     * @return The generated key or <code>null</code> if the component
+     *              is currently not cacheable.
+     */
+    Serializable getKey();
+
+    /**
+     * Generate the validity object.  This method is invoked after the
+     * <code>getKey()</code> method.
+     * <p>
+     * The caching contracts use the Excalibur <code>SourceValidity</code>
+     * interface to determine whether a resource is valid or not. The validity
+     * can be a compound check that incorporates time since creation, parameter
+     * values, etc. As long as the sitemap can determine whether the cached
+     * resource is valid or not. More information is available on the 
+     * <a href="http://excalibur.apache.org/sourceresolve/index.html">Apache
+     * Excalibur site</a>. Alternatively you can use the built in 
+     * <code>CacheValidity</code> objects in the
+     * <code>org.apache.cocoon.caching</code> package and then use the
+     * {@link CacheValidityToSourceValidity} adaptor object.
+     * </p>
+     *
+     * @return The generated validity object or <code>null</code> if the
+     *         component is currently not cacheable.
+     */
+    SourceValidity getValidity();
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CacheableProcessingComponent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachedResponse.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachedResponse.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachedResponse.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachedResponse.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,144 @@
+/*
+ * Copyright 1999-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.cocoon.caching;
+
+import java.io.Serializable;
+
+import org.apache.excalibur.source.SourceValidity;
+
+/**
+ * This is a cached response. This can either contain a byte array with
+ * the complete character response or a byte array with compiled SAX events.
+ *
+ * This class replaces the <code>CachedEventObject</code> and the
+ * <code>CachedStreamObject</code>.
+ *
+ * @since 2.1
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: CachedResponse.java 47091 2004-09-23 09:04:50Z cziegeler $
+ */
+public class CachedResponse
+        implements Serializable {
+
+    protected final SourceValidity[] validityObjects;
+    protected final byte[]           response;
+    protected Long                   expires;
+    protected final long             lastModified;
+    protected String                 contentType;
+    
+    /**
+     * Create a new entry for the cache.
+     *
+     * @param validityObjects The SourceValidity objects in the order
+     *                        they occured in the pipeline
+     * @param response        The cached sax stream or character stream
+     */
+    public CachedResponse(SourceValidity[] validityObjects,
+                          byte[]           response) {
+        this(validityObjects, response, null);
+    }
+
+    /**
+     * Create a new entry for the cache.
+     *
+     * @param validityObject  The SourceValidity object 
+     * @param response        The cached sax stream or character stream
+     */
+    public CachedResponse(SourceValidity   validityObject,
+                          byte[]           response) {
+        this(new SourceValidity[] {validityObject}, response, null);
+    }
+
+    /**
+     * Create a new entry for the cache.
+     *
+     * @param validityObjects The SourceValidity objects in the order
+     *                        they occured in the pipeline
+     * @param response        The cached sax stream or character stream
+     * @param expires         The configured expires, or null if no
+     *                        expires was defined.
+     */
+    public CachedResponse(SourceValidity[] validityObjects,
+                          byte[]           response,
+                          Long expires) {
+        this.validityObjects = validityObjects;
+        this.response = response;
+        this.expires = expires;
+        this.lastModified = this.setLastModified(System.currentTimeMillis());
+    }
+
+    /**
+     * Get the validity objects
+     */
+    public SourceValidity[] getValidityObjects() {
+        return this.validityObjects;
+    }
+
+    /**
+     * Get the cached response.
+     *
+     * @return The sax stream or character stream
+     */
+    public byte[] getResponse() {
+        return this.response;
+    }
+
+    /**
+     * Get the configured expires.
+     *
+     * @return The configured expires, or null if no expires was defined
+     */
+    public Long getExpires() {
+        return this.expires;
+    }
+    
+    /**
+     * Set the (newly) configured expires.
+     * 
+     */
+    public void setExpires(Long newExpires) {
+        this.expires = newExpires;    
+    }
+    
+    /**
+     * Set the (newly) configured last modified.
+     * 
+     */
+    protected long setLastModified(long lastModified) {
+        // Return the value rounded to the nearest second.
+        return lastModified - (lastModified % 1000);
+    }
+    
+    /**
+     * @return the last modified time 
+     */
+    public long getLastModified() {
+        return lastModified;
+    }
+
+    /**
+     * @return Returns the cached content type (or null).
+     */
+    public String getContentType() {
+        return this.contentType;
+    }
+    /**
+     * @param value The content type to cache.
+     */
+    public void setContentType(String value) {
+        this.contentType = value;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachedResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachingOutputStream.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachingOutputStream.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachingOutputStream.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachingOutputStream.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1999-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.cocoon.caching;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This is an {@link OutputStream} which forwards all received bytes to another
+ * output stream and in addition caches all bytes, thus acting like a
+ * TeeOutputStream.
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: CachingOutputStream.java 30941 2004-07-29 19:56:58Z vgritsenko $
+ */
+
+public final class CachingOutputStream
+extends OutputStream {
+
+    private OutputStream receiver;
+
+    /** The buffer for the compile xml byte stream. */
+    private byte buf[];
+
+    /** The number of valid bytes in the buffer. */
+    private int bufCount;
+
+    public CachingOutputStream(OutputStream os) {
+        this.receiver = os;
+        this.buf = new byte[1024];
+        this.bufCount = 0;
+    }
+
+    public byte[] getContent() {
+        byte newbuf[] = new byte[this.bufCount];
+        System.arraycopy(this.buf, 0, newbuf, 0, this.bufCount);
+        return newbuf;
+    }
+
+    public void write(int b) throws IOException {
+        this.receiver.write(b);
+        int newcount = this.bufCount + 1;
+        if (newcount > this.buf.length) {
+            byte newbuf[] = new byte[Math.max(this.buf.length << 1, newcount)];
+            System.arraycopy(this.buf, 0, newbuf, 0, this.bufCount);
+            this.buf = newbuf;
+        }
+        this.buf[this.bufCount] = (byte)b;
+        this.bufCount = newcount;
+    }
+
+    public void write( byte b[] ) throws IOException {
+        this.write(b, 0, b.length);
+    }
+
+    public void write(byte b[], int off, int len) throws IOException {
+        this.receiver.write(b, off, len);
+        if (len == 0) return;
+        int newcount = this.bufCount + (len-off);
+        if (newcount > this.buf.length) {
+            byte newbuf[] = new byte[Math.max(this.buf.length << 1, newcount)];
+            System.arraycopy(this.buf, 0, newbuf, 0, this.bufCount);
+            this.buf = newbuf;
+        }
+        System.arraycopy(b, off, this.buf, this.bufCount, len);
+        this.bufCount = newcount;
+    }
+
+    public void flush() throws IOException {
+        this.receiver.flush();
+    }
+
+    public void close() throws IOException {
+        this.receiver.close();
+    }
+
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/CachingOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/ComponentCacheKey.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/ComponentCacheKey.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/ComponentCacheKey.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/ComponentCacheKey.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,121 @@
+/*
+ * Copyright 1999-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.cocoon.caching;
+
+import java.io.Serializable;
+/**
+ * This is the cache key for one sitemap component.
+ * It consists of three parts:<br/>
+ * a.) The component type (generator, transformer etc.)<br/>
+ * b.) The component identifier - a unique handle for the sitemap
+ *      component<br/>
+ * c.) The cache key - a key, generated by the component, which
+ *      is unique inside the components space.
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: ComponentCacheKey.java 30941 2004-07-29 19:56:58Z vgritsenko $
+ */
+public final class ComponentCacheKey
+    implements Serializable {
+
+    public static final int ComponentType_Generator   = 1;
+    public static final int ComponentType_Transformer = 3;
+    public static final int ComponentType_Serializer  = 5;
+    public static final int ComponentType_Reader      = 7;
+
+    // Converts Generator / Transformer / Serializer / Reader constants above
+    // into string.
+    private static final String[] COMPONENTS = { "X", "G", "X", "T", "X", "S", "X", "R" };
+
+    /** The component type */
+    private final int type;
+    /** The component identifier */
+    private final String identifier;
+    /** The unique key */
+    private final Serializable key;
+    /** the hash code */
+    private final int hashCode;
+    /** cachePoint */
+    private final boolean cachePoint;
+
+    /**
+     * Constructor
+     */
+    public ComponentCacheKey(int          componentType,
+                             String       componentIdentifier,
+                             Serializable cacheKey) {
+        this(componentType, componentIdentifier, cacheKey, false);
+    }
+
+    /**
+     * alternate cachepoint Constructor
+     */
+    public ComponentCacheKey(int          componentType,
+                             String       componentIdentifier,
+                             Serializable cacheKey,
+			     boolean cachePoint) {
+        this.type = componentType;
+        this.identifier = componentIdentifier;
+        this.key = cacheKey;
+        /** cachePoint */
+        this.cachePoint = cachePoint;
+        this.hashCode = this.type +
+                (this.identifier.length() << 3) +
+                this.key.hashCode();
+    }
+
+    /**
+     * Compare
+     */
+    public boolean equals(Object object) {
+        if (object instanceof ComponentCacheKey) {
+            ComponentCacheKey ccp = (ComponentCacheKey)object;
+            if (this.type == ccp.type
+                && this.identifier.equals(ccp.identifier)
+                && this.key.equals(ccp.key)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * HashCode
+     */
+    public int hashCode() {
+        return this.hashCode;
+    }
+
+    private String toString;
+
+    /**
+     * toString
+     * The FilesystemStore uses toString!
+     */
+    public String toString() {
+        if (this.toString == null) {
+            toString = COMPONENTS[this.type] + '-' + this.identifier + '-' + this.key.toString();
+        }
+        return toString;
+    }
+
+    /**
+     * Check if we are a cachepoint 
+     */
+    public boolean isCachePoint() {
+        return cachePoint;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/ComponentCacheKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/IdentifierCacheKey.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/IdentifierCacheKey.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/IdentifierCacheKey.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/IdentifierCacheKey.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,94 @@
+/*
+ * 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.caching;
+
+import java.io.Serializable;
+
+/**
+ * This is a "simple" cache key that does not consider the components used in the
+ * pipeline. It simply consists of a key (unique identifier for the request) and
+ * a boolean value that defines if the key is for a complete pipeline call or
+ * for an internal pipeline call.
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: IdentifierCacheKey.java 189610 2005-06-08 17:41:59Z cziegeler $
+ * @since 2.1.1
+ */
+public class IdentifierCacheKey
+    implements Serializable {
+
+    /** The key */
+    final protected String key;
+
+    /** Is this an external pipeline call? */
+    final protected boolean external;
+
+    /** cache key */
+    final protected String cacheKey;
+    
+    /** cache toString() */
+    protected String toString;
+    
+    /**
+     * Constructor
+     */
+    public IdentifierCacheKey(String key, boolean external) {
+        this.key = key;
+        this.external = external;
+        final StringBuffer buf = new StringBuffer();
+        buf.append(this.external).append(':').append(this.key);
+        this.cacheKey = buf.toString();
+    }
+
+    /**
+     * Compare
+     */
+    public boolean equals(Object object) {
+        if (object instanceof IdentifierCacheKey) {
+            IdentifierCacheKey pck = (IdentifierCacheKey)object;
+            return this.cacheKey.equals( pck.cacheKey );
+        }
+        return false;
+    }
+
+    /**
+     * Generate a hash code
+     */
+    public int hashCode() {
+        return this.cacheKey.hashCode();
+    }
+
+    /**
+     * toString
+     * The FilesystemStore uses toString!
+     */
+    public String toString() {
+        if (this.toString == null) {
+            StringBuffer buffer = new StringBuffer();
+            buffer.append("IK:");
+            buffer.append(this.cacheKey);
+            this.toString = buffer.toString();
+        }
+        return toString;
+    }
+    
+    /**
+     * The cache key
+     */
+    public String getKey() {
+        return this.key;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/IdentifierCacheKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/PipelineCacheKey.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/PipelineCacheKey.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/PipelineCacheKey.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/PipelineCacheKey.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,159 @@
+/*
+ * Copyright 1999-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.cocoon.caching;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is the cache key for one pipeline (or the first part of a pipeline).
+ * It consists of one or more {@link ComponentCacheKey}s.
+ *
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: PipelineCacheKey.java 30941 2004-07-29 19:56:58Z vgritsenko $
+ */
+public final class PipelineCacheKey
+        implements Serializable {
+
+    /** The keys */
+    private final List keys;
+
+    /** the hash code */
+    private int hashCode;
+
+    /**
+     * Constructor
+     */
+    public PipelineCacheKey() {
+        this.keys = new ArrayList(6);
+    }
+
+    /**
+     * Constructor
+     */
+    public PipelineCacheKey(int size) {
+        this.keys = new ArrayList(size);
+    }
+
+    /**
+     * Add a key
+     */
+    public void addKey(ComponentCacheKey key) {
+        this.keys.add(key);
+        this.hashCode = 0;
+        this.toString = null;
+    }
+
+    /**
+     * Remove the last key
+     */
+    public void removeLastKey() {
+        this.keys.remove(this.keys.size()-1);
+        this.hashCode = 0;
+        this.toString = null;
+    }
+
+    /**
+     * Remove unitl cachepoint (including cachePoint) 
+     */
+    public void removeUntilCachePoint() {
+        this.hashCode = 0;
+        this.toString = null;
+        int keyCount = this.keys.size();
+
+        while (keyCount > 0) {
+            if (((ComponentCacheKey)this.keys.get(keyCount-1)).isCachePoint()) {
+                this.keys.remove(keyCount-1);
+                return;
+            }
+            this.keys.remove(keyCount-1);
+            keyCount--;
+        }
+    }
+
+    /**
+     * Return the number of keys
+     */
+    public int size() {
+        return this.keys.size();
+    }
+
+    /**
+     * Compare
+     */
+    public boolean equals(Object object) {
+        if (object instanceof PipelineCacheKey) {
+            PipelineCacheKey pck = (PipelineCacheKey)object;
+            final int len = this.keys.size();
+            if (pck.keys.size() == len) {
+                boolean cont = true;
+                int i = 0;
+                while (i < len && cont) {
+                    cont = this.keys.get(i).equals(pck.keys.get(i));
+                    i++;
+                }
+                return cont;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Generate a hash code
+     */
+    public int hashCode() {
+        if (this.hashCode == 0) {
+            final int len = this.keys.size();
+            for(int i=0; i < len; i++) {
+                this.hashCode += this.keys.get(i).hashCode();
+            }
+            if (len % 2 == 0) this.hashCode++;
+        }
+        return this.hashCode;
+    }
+
+    /**
+     * Clone the object (but not the component keys)
+     */
+    public PipelineCacheKey copy() {
+        final int len = this.keys.size();
+        PipelineCacheKey pck = new PipelineCacheKey(len);
+        for(int i=0; i < len; i++) {
+            pck.keys.add(this.keys.get(i));
+        }
+        return pck;
+    }
+
+    private String toString;
+
+    /**
+     * toString
+     * The FilesystemStore uses toString!
+     */
+    public String toString() {
+        if (this.toString == null) {
+            StringBuffer buffer = new StringBuffer();
+            buffer.append("PK");
+            final int len = this.keys.size();
+            for(int i=0; i < len; i++) {
+                buffer.append('_').append(this.keys.get(i).toString());
+            }
+            this.toString = buffer.toString();
+        }
+        return toString;
+    }
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/PipelineCacheKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/impl/CacheImpl.java
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/impl/CacheImpl.java?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/impl/CacheImpl.java (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/impl/CacheImpl.java Thu Nov  3 05:41:06 2005
@@ -0,0 +1,148 @@
+/*
+ * 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.caching.impl;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.caching.Cache;
+import org.apache.cocoon.caching.CachedResponse;
+import org.apache.excalibur.store.Store;
+
+/**
+ * This is the Cocoon cache. This component is responsible for storing
+ * and retrieving cached responses. It can be used to monitor the cache
+ * or the investigate which responses are cached etc.
+ * This component will grow!
+ *
+ * @since 2.1
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id: CacheImpl.java 209436 2005-07-06 09:23:19Z cziegeler $
+ */
+public class CacheImpl
+extends AbstractLogEnabled
+implements Cache, ThreadSafe, Serviceable, Disposable, Parameterizable {
+
+    /** The store containing the cached responses */
+    protected Store store;
+
+    /** The service manager */
+    protected ServiceManager manager;
+
+    /**
+     * Serviceable Interface
+     */
+    public void service (ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * Disposable Interface
+     */
+    public void dispose() {
+        this.manager.release(this.store);
+        this.store = null;
+        this.manager = null;
+    }
+
+    /**
+     * Store a cached response
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     * @param response    the cached response
+     */
+    public void store(Serializable     key,
+                      CachedResponse   response)
+    throws ProcessingException {
+        if ( this.getLogger().isInfoEnabled()) {
+            this.getLogger().info("Caching new response for " + key);
+        }
+        try {
+            this.store.store(key, response);
+        } catch (IOException ioe) {
+            throw new ProcessingException("Unable to cache response.", ioe);
+        }
+    }
+
+    /**
+     * Get a cached response.
+     * If it is not available <code>null</code> is returned.
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     */
+    public CachedResponse get(Serializable key) {
+        final CachedResponse r = (CachedResponse)this.store.get(key);
+        if ( this.getLogger().isInfoEnabled()) {
+            this.getLogger().info("Cached response for " + key + " : " + 
+                                   (r == null ? "not found" : "found"));
+        }
+        return r;
+    }
+
+    /**
+     * Remove a cached response.
+     * If it is not available no operation is performed.
+     * @param key         the key used by the caching algorithm to identify the
+     *                    request
+     */
+    public void remove(Serializable key) {
+        if ( this.getLogger().isInfoEnabled()) {
+            this.getLogger().info("Removing cached response for " + key); 
+        }
+        this.store.remove(key);
+    }
+
+    /**
+     * clear cache of all cached responses 
+     */
+    public void clear() {
+        if ( this.getLogger().isInfoEnabled()) {
+            this.getLogger().info("Clearing cache"); 
+        }
+        // FIXME this clears the whole store!
+        this.store.clear();
+    }
+
+	/**
+	 * See if a response is cached under this key
+	 */
+	public boolean containsKey(Serializable key) {
+		return this.store.containsKey(key);
+	}
+
+    /* (non-Javadoc)
+     * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
+     */
+    public void parameterize(Parameters parameters) throws ParameterException {
+        String storeName = parameters.getParameter("store", Store.ROLE);
+        try {
+            this.store = (Store)this.manager.lookup(storeName);
+        } catch (ServiceException e) {
+            throw new ParameterException("Unable to lookup store: " + storeName, e);
+        }
+    }
+
+}

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/caching/impl/CacheImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/cocoon.properties
URL: http://svn.apache.org/viewcvs/cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/cocoon.properties?rev=330548&view=auto
==============================================================================
--- cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/cocoon.properties (added)
+++ cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/cocoon.properties Thu Nov  3 05:41:06 2005
@@ -0,0 +1,28 @@
+# ------ System Properties -----------------------------------------------------
+
+# 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.
+
+
+# WARNING: you shouldn't need to modify anything below here since there is a
+# very high chance of breaking the build system. Do it only if you know what
+# you're doing.
+
+version=2.2.0-dev
+released.version=2.1.7
+year=1999-2005
+name=cocoon
+Name=Cocoon
+fullname=Apache Cocoon
+build.info=@date@ (TargetVM=@target.vm@, SourceVM=@source.vm@, Debug=@compiler.debug@, Optimize=@compiler.optimize@)

Propchange: cocoon/whiteboard/maven2/cocoon-flat-layout/cocoon-core/src/main/java/org/apache/cocoon/cocoon.properties
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message