svn commit: r1356609 - in /cocoon/cocoon3/trunk: cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/jaxb/ cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ cocoon-pipeline/src/main/java/org/apache/cocoon/pi...

[email protected]
Newsgroups gmane.text.xml.cocoon.cvs
Message-ID <[email protected]>
Author: ilgrosso
Date: Tue Jul  3 08:30:31 2012
New Revision: 1356609

URL: http://svn.apache.org/viewvc?rev=1356609&view=rev
Log:
[COCOON3-102] Applying (and reworking a bit) the proposed patch for COCOON3-100, replacing URLCacheKey with URLConnectionUtils.getLastModified()

Added:
    cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheKey.java   (with props)
    cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheValue.java   (with props)
    cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ObjectCacheKey.java   (with props)
    cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/URLListCacheKey.java   (with props)
Removed:
    cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/jaxb/ObjectCacheKey.java
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/util/URLUtils.java
Modified:
    cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/jaxb/JAXBGenerator.java
    cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CompoundCacheKey.java
    cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/TimestampCacheKey.java
    cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/util/URLConnectionUtils.java
    cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XIncludeTransformer.java
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XMLGenerator.java
    cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java
    cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/component/FileReaderComponent.java
    cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateGenerator.java
    cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateReader.java

Modified: cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/jaxb/JAXBGenerator.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/jaxb/JAXBGenerator.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/jaxb/JAXBGenerator.java (original)
+++ cocoon/cocoon3/trunk/cocoon-optional/src/main/java/org/apache/cocoon/optional/pipeline/components/sax/jaxb/JAXBGenerator.java Tue Jul  3 08:30:31 2012
@@ -21,9 +21,9 @@ package org.apache.cocoon.optional.pipel
 import javax.xml.bind.Marshaller;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
-
 import org.apache.cocoon.pipeline.ProcessingException;
 import org.apache.cocoon.pipeline.caching.CacheKey;
+import org.apache.cocoon.pipeline.caching.ObjectCacheKey;
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
 import org.apache.cocoon.pipeline.util.StringRepresentation;
 import org.apache.cocoon.sax.AbstractSAXGenerator;
@@ -164,6 +164,7 @@ public class JAXBGenerator extends Abstr
         }
     }
 
+    @Override
     public CacheKey constructCacheKey() {
         return new ObjectCacheKey(this.toBeMarshalled);
     }

Added: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheKey.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheKey.java?rev=1356609&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheKey.java (added)
+++ cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheKey.java Tue Jul  3 08:30:31 2012
@@ -0,0 +1,126 @@
+
+/*
+ * 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.pipeline.caching;
+
+import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This {@link CacheKey} will store the keys in a {@link SimpleCache} using an {@link ObjectCacheKey} to identify the
+ * cache entry.
+ *
+ * This object is for components that need to be executed to be able to create a valid {@link CacheKey} entry.
+ */
+public class CachedCacheKey extends AbstractCacheKey {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(CachedCacheKey.class);
+
+    /**
+     * Simple cache to store the {@link CacheKey}
+     */
+    private static final Cache CACHED_CACHE = new SimpleCache();
+
+    /**
+     * {@link CacheKey} that will be used as key of the cache store.
+     */
+    private CacheKey internalCacheKey;
+
+    /**
+     * {@link CacheKey} to query for real cache info.
+     */
+    private CacheKey cachedCacheKey;
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof CachedCacheKey)) {
+            return false;
+        }
+
+        CachedCacheKey other = (CachedCacheKey) obj;
+        return this.internalCacheKey.equals(other.internalCacheKey);
+    }
+
+    /**
+     * Set internal key to store the real component {@link CacheKey}.
+     *
+     * @param key Simple {@link CacheKey} that can be easily generated for the component
+     */
+    public void setKey(String key) {
+        this.internalCacheKey = new ObjectCacheKey(key);
+        if (CACHED_CACHE.get(internalCacheKey, true) != null) {
+            this.cachedCacheKey = (URLListCacheKey) CACHED_CACHE.get(internalCacheKey, true).getValue();
+        } else {
+            // First time processed. Return invalid to update with real one.
+            this.cachedCacheKey = new InvalidCacheKey(getClass().getName());
+            LOG.debug("{} first time processed. Returning InvalidCacheKey.", key);
+        }
+    }
+
+    /**
+     * Set the real {@link CacheKey}.
+     *
+     * @param value {@link CacheKey}
+     */
+    public void setValue(URLListCacheKey value) {
+        this.cachedCacheKey = value;
+        CACHED_CACHE.put(this.internalCacheKey, new CachedCacheValue(this.cachedCacheKey));
+    }
+
+    /**
+     * Delegates on cached key.
+     */
+    @Override
+    public int hashCode() {
+        return cachedCacheKey != null ? cachedCacheKey.hashCode() : super.hashCode();
+    }
+
+    /**
+     * Delegates on cached key.
+     */
+    @Override
+    public boolean isValid(CacheKey cacheKey) {
+        if (cacheKey == null || !this.equals(cacheKey)) {
+            return false;
+        }
+
+        CachedCacheKey otherCachedCacheKey = (CachedCacheKey) cacheKey;
+        return cachedCacheKey != null && cachedCacheKey.isValid(otherCachedCacheKey.cachedCacheKey);
+    }
+
+    /**
+     * Delegates on cached key.
+     */
+    @Override
+    public long getLastModified() {
+        return cachedCacheKey != null ? cachedCacheKey.getLastModified() : -1;
+    }
+
+    @Override
+    public String toString() {
+        return StringRepresentation.buildString(this, "internalCacheKey=" + this.internalCacheKey,
+                "cachedCacheKey=" + this.cachedCacheKey);
+    }
+}

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheKey.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheKey.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheValue.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheValue.java?rev=1356609&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheValue.java (added)
+++ cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheValue.java Tue Jul  3 08:30:31 2012
@@ -0,0 +1,76 @@
+/*
+ * 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.pipeline.caching;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CachedCacheValue extends AbstractCacheValue {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(CachedCacheValue.class);
+
+    public CachedCacheValue(CacheKey cacheKey) {
+        super(cacheKey);
+    }
+
+    @Override
+    public void writeTo(OutputStream outputStream) throws IOException {
+        throw new UnsupportedOperationException("Cannot write the content of CachedCacheValue to OutputStream.");
+    }
+
+    @Override
+    public Object getValue() {
+        return getCacheKey();
+    }
+
+    @Override
+    public void setValue(Object value) {
+        throw new UnsupportedOperationException("Cannot set the content of CachedCacheValue to OutputStream.");
+    }
+
+    @Override
+    public double size() {
+        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+        try {
+            ObjectOutputStream objectOut = new ObjectOutputStream(byteOut);
+            objectOut.writeObject(getValue());
+            objectOut.flush();
+            objectOut.close();
+        } catch (IOException e) {
+            LOG.error("Some thing goes wrong during calculating size of: " + getCacheKey(), e);
+            return -1;
+        }
+        return byteOut.toByteArray().length;
+    }
+
+    @Override
+    public String toString() {
+        return StringRepresentation.buildString(this, "cacheKey=" + getCacheKey());
+    }
+}

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheValue.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheValue.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CachedCacheValue.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CompoundCacheKey.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CompoundCacheKey.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CompoundCacheKey.java (original)
+++ cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/CompoundCacheKey.java Tue Jul  3 08:30:31 2012
@@ -33,9 +33,8 @@ public class CompoundCacheKey extends Ab
     /**
      * Logger.
      */
-    private static final Logger LOG =
-            LoggerFactory.getLogger(CompoundCacheKey.class);
-    
+    private static final Logger LOG = LoggerFactory.getLogger(CompoundCacheKey.class);
+
     private final List<CacheKey> cacheKeys = new LinkedList<CacheKey>();
 
     public void addCacheKey(final CacheKey cacheKey) {
@@ -95,6 +94,7 @@ public class CompoundCacheKey extends Ab
      *
      * @see org.apache.cocoon.pipeline.caching.CacheKey#isValid(org.apache.cocoon.pipeline.caching.CacheKey)
      */
+    @Override
     public boolean isValid(final CacheKey cacheKey) {
         if (!(cacheKey instanceof CompoundCacheKey) || !this.equals(cacheKey)) {
             return false;
@@ -104,11 +104,9 @@ public class CompoundCacheKey extends Ab
         final Iterator<CacheKey> myIterator = this.cacheKeys.iterator();
         final Iterator<CacheKey> otherIterator = other.cacheKeys.iterator();
 
-        CacheKey myCacheKey;
-        CacheKey otherCacheKey;
         while (myIterator.hasNext()) {
-            myCacheKey = myIterator.next();
-            otherCacheKey = otherIterator.next();
+            CacheKey myCacheKey = myIterator.next();
+            CacheKey otherCacheKey = otherIterator.next();
 
             if (!myCacheKey.isValid(otherCacheKey)) {
                 if (LOG.isDebugEnabled()) {
@@ -124,6 +122,7 @@ public class CompoundCacheKey extends Ab
         return true;
     }
 
+    @Override
     public long getLastModified() {
         long lastModified = 0;
         long eachLastModified;

Added: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ObjectCacheKey.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ObjectCacheKey.java?rev=1356609&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ObjectCacheKey.java (added)
+++ cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ObjectCacheKey.java Tue Jul  3 08:30:31 2012
@@ -0,0 +1,80 @@
+/*
+ * 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.pipeline.caching;
+
+import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.apache.cocoon.util.murmurhash.MurmurHashCodeBuilder;
+
+/**
+ * @version $Id$
+ */
+public class ObjectCacheKey extends AbstractCacheKey {
+
+    private static final long serialVersionUID = 1L;
+
+    private final Object obj;
+
+    public ObjectCacheKey(Object obj) {
+        this.obj = obj;
+    }
+
+    public Object getObj() {
+        return this.obj;
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof ObjectCacheKey)) {
+            return false;
+        }
+
+        ObjectCacheKey otherCacheKey = (ObjectCacheKey) other;
+        return this.obj.equals(otherCacheKey.getObj());
+    }
+
+    @Override
+    public int hashCode() {
+        return new MurmurHashCodeBuilder().append(this.getClass().getName()).append(this.obj.toString()).toHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.cocoon.pipeline.caching.CacheKey#isValid(org.apache.cocoon.pipeline.caching.CacheKey)
+     */
+    @Override
+    public long getLastModified() {
+        return 0;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.cocoon.pipeline.caching.CacheKey#isValid(org.apache.cocoon.pipeline.caching.CacheKey)
+     */
+    @Override
+    public boolean isValid(CacheKey other) {
+        return this.equals(other);
+    }
+
+    @Override
+    public String toString() {
+        return StringRepresentation.buildString(this, "obj=" + this.obj);
+    }
+}

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ObjectCacheKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ObjectCacheKey.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/ObjectCacheKey.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/TimestampCacheKey.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/TimestampCacheKey.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/TimestampCacheKey.java (original)
+++ cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/TimestampCacheKey.java Tue Jul  3 08:30:31 2012
@@ -21,7 +21,6 @@ package org.apache.cocoon.pipeline.cachi
 import java.net.URL;
 import java.text.SimpleDateFormat;
 import java.util.Date;
-
 import org.apache.cocoon.pipeline.util.StringRepresentation;
 import org.apache.cocoon.util.murmurhash.MurmurHashCodeBuilder;
 
@@ -29,7 +28,7 @@ public class TimestampCacheKey extends A
 
     private static final long serialVersionUID = 1L;
 
-    private final long timestamp;
+    private long timestamp;
 
     private final URL url;
 
@@ -50,10 +49,19 @@ public class TimestampCacheKey extends A
         return this.url.toExternalForm().equals(other.url.toExternalForm());
     }
 
+    public URL getUrl() {
+        return url;
+    }
+
     public long getTimestamp() {
         return this.timestamp;
     }
 
+    public void setTimestamp(long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    @Override
     public long getLastModified() {
         return this.getTimestamp();
     }
@@ -64,10 +72,9 @@ public class TimestampCacheKey extends A
                 append(this.timestamp).toHashCode();
     }
 
+    @Override
     public boolean isValid(final CacheKey cacheKey) {
-        if (!(cacheKey instanceof TimestampCacheKey)
-                || !this.equals(cacheKey)) {
-
+        if (!(cacheKey instanceof TimestampCacheKey) || !this.equals(cacheKey)) {
             return false;
         }
 

Added: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/URLListCacheKey.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/URLListCacheKey.java?rev=1356609&view=auto
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/URLListCacheKey.java (added)
+++ cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/URLListCacheKey.java Tue Jul  3 08:30:31 2012
@@ -0,0 +1,158 @@
+/*
+ * 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.pipeline.caching;
+
+import java.net.URL;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.apache.cocoon.pipeline.util.URLConnectionUtils;
+import org.apache.cocoon.util.murmurhash.MurmurHashCodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A
+ * <code>CacheKey</code> holding a list of URLs.
+ * Similar to CompoundCacheKey, this class will update URL timestamps before going into getLastModified().
+ *
+ * @see CompoundCacheKey
+ */
+public class URLListCacheKey extends AbstractCacheKey {
+
+    /**
+     * Logger.
+     */
+    private static final Logger LOG = LoggerFactory.getLogger(URLListCacheKey.class);
+
+    private final List<TimestampCacheKey> cacheKeys = new LinkedList<TimestampCacheKey>();
+
+    public void addURL(final URL url) {
+        this.cacheKeys.add(new TimestampCacheKey(url, URLConnectionUtils.getLastModified(url)));
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Comparing two cache keys: ");
+            LOG.debug("  this=" + this);
+            LOG.debug("  other=" + obj);
+        }
+
+        if (!(obj instanceof URLListCacheKey)) {
+            return false;
+        }
+
+        final URLListCacheKey other = (URLListCacheKey) obj;
+        if (this.cacheKeys.size() != other.cacheKeys.size()) {
+            return false;
+        }
+
+        final Iterator<TimestampCacheKey> myIterator = this.cacheKeys.iterator();
+        final Iterator<TimestampCacheKey> otherIterator = other.cacheKeys.iterator();
+
+        while (myIterator.hasNext()) {
+            final TimestampCacheKey myCacheKey = myIterator.next();
+            final TimestampCacheKey otherCacheKey = otherIterator.next();
+
+            if (myCacheKey == null || !myCacheKey.equals(otherCacheKey)) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Cache keys are not equal: ");
+                    LOG.debug("  myCacheKey=" + myCacheKey);
+                    LOG.debug("  otherCacheKey=" + otherCacheKey);
+                }
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        final MurmurHashCodeBuilder hashCodeBuild = new MurmurHashCodeBuilder();
+
+        for (CacheKey cacheKey : this.cacheKeys) {
+            hashCodeBuild.append(cacheKey.hashCode());
+        }
+
+        return hashCodeBuild.toHashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see org.apache.cocoon.pipeline.caching.CacheKey#isValid(org.apache.cocoon.pipeline.caching.CacheKey)
+     */
+    @Override
+    public boolean isValid(final CacheKey cacheKey) {
+        if (!(cacheKey instanceof URLListCacheKey) || !this.equals(cacheKey)) {
+            return false;
+        }
+
+        final URLListCacheKey other = (URLListCacheKey) cacheKey;
+        final Iterator<TimestampCacheKey> myIterator = this.cacheKeys.iterator();
+        final Iterator<TimestampCacheKey> otherIterator = other.cacheKeys.iterator();
+
+        while (myIterator.hasNext()) {
+            TimestampCacheKey myCacheKey = myIterator.next();
+            TimestampCacheKey otherCacheKey = otherIterator.next();
+
+            if (!myCacheKey.isValid(otherCacheKey)) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Cache key is not valid: ");
+                    LOG.debug("  myCacheKey=" + myCacheKey);
+                    LOG.debug("  otherCacheKey=" + otherCacheKey);
+                }
+
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public long getLastModified() {
+        // update last-modificatied for each URL
+        for (TimestampCacheKey tCacheKey : this.cacheKeys) {
+            tCacheKey.setTimestamp(URLConnectionUtils.getLastModified(tCacheKey.getUrl()));
+        }
+
+        long lastModified = 0;
+        long eachLastModified;
+        for (CacheKey eachKey : this.cacheKeys) {
+            eachLastModified = eachKey.getLastModified();
+            if (eachLastModified == -1) {
+                return -1;
+            }
+            if (eachLastModified > lastModified) {
+                lastModified = eachLastModified;
+                continue;
+            }
+        }
+        return lastModified;
+    }
+
+    @Override
+    public String toString() {
+        return StringRepresentation.buildString(this, "urls=" + this.cacheKeys);
+    }
+}

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/URLListCacheKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/URLListCacheKey.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/caching/URLListCacheKey.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/util/URLConnectionUtils.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/util/URLConnectionUtils.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/util/URLConnectionUtils.java (original)
+++ cocoon/cocoon3/trunk/cocoon-pipeline/src/main/java/org/apache/cocoon/pipeline/util/URLConnectionUtils.java Tue Jul  3 08:30:31 2012
@@ -17,9 +17,12 @@
 package org.apache.cocoon.pipeline.util;
 
 import java.io.Closeable;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
 import java.net.URLConnection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,6 +34,7 @@ public abstract class URLConnectionUtils
      */
     private static final Logger LOG =
             LoggerFactory.getLogger(URLConnectionUtils.class);
+
     /**
      * Close a {@link URLConnection} quietly and take care of all the exception handling.
      *
@@ -69,8 +73,46 @@ public abstract class URLConnectionUtils
             try {
                 closeable.close();
             } catch (IOException e) {
-                LOG.warn("Can't close stream (" + closeable.getClass().getSimpleName() + "): " + urlConnection.getURL(), e);
+                LOG.warn("Can't close stream (" + closeable.getClass().getSimpleName() + "): " 
+                        + urlConnection.getURL(), e);
             }
         }
     }
+
+    /**
+     * Find the actual last modification timestamp for the given URL, reverting to java.io.File#lastModified() when
+     * applicable.
+     *
+     * @param url URL to be examined for last modified
+     * @return File.lastModified() when applicable or URLconnection.getLastModified()
+     */
+    public static long getLastModified(final URL url) {
+        if (url == null) {
+            throw new IllegalArgumentException("URL source cannot be null");
+        }
+
+        long lastModified = -1;
+
+        if ("file".equals(url.getProtocol())) {
+            try {
+                lastModified = new File(url.toURI()).lastModified();
+            } catch (URISyntaxException e) {
+                LOG.error("Error while opening {} as file", url, e);
+            }
+        } else {
+            URLConnection connection = null;
+            try {
+                connection = url.openConnection();
+                lastModified = connection.getLastModified();
+            } catch (IOException e) {
+                LOG.error("Error while connecting to {}", url, e);
+            } finally {
+                if (connection != null) {
+                    URLConnectionUtils.closeQuietly(connection);
+                }
+            }
+        }
+
+        return lastModified;
+    }
 }

Modified: cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap (original)
+++ cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap Tue Jul  3 08:30:31 2012
@@ -386,7 +386,9 @@
       </map:match>
       <map:match equals="aggregation/xinclude-transformer">
         <map:generate src="aggregation/xinclude.xml" />
-        <map:transform type="xinclude" />
+        <map:transform type="xinclude">
+            <map:parameter name="cacheKey" value="{map:0}"/>
+        </map:transform>
         <map:serialize type="xml" />
       </map:match>
       <map:match equals="aggregation/sub-request">

Modified: cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java (original)
+++ cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/SchemaProcessorTransformer.java Tue Jul  3 08:30:31 2012
@@ -29,11 +29,11 @@ import org.apache.cocoon.pipeline.cachin
 import org.apache.cocoon.pipeline.caching.TimestampCacheKey;
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
 import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.apache.cocoon.pipeline.util.URLConnectionUtils;
 import org.apache.cocoon.sax.AbstractSAXTransformer;
 import org.apache.cocoon.sax.SAXConsumer;
 import org.apache.cocoon.sax.util.InMemoryLRUResourceCache;
 import org.apache.cocoon.sax.util.SAXConsumerAdapter;
-import org.apache.cocoon.sax.util.URLUtils;
 import org.apache.cocoon.sax.util.ValidityValue;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -93,7 +93,7 @@ public final class SchemaProcessorTransf
 
         this.source = source;
 
-        Long lastModified = URLUtils.getLastModified(this.source);
+        Long lastModified = URLConnectionUtils.getLastModified(this.source);
 
         if (SCHEMA_CACHE.containsKey(source.toExternalForm())) {
             ValidityValue<Schema> cacheEntry = SCHEMA_CACHE.get(source.toExternalForm());
@@ -125,6 +125,6 @@ public final class SchemaProcessorTransf
             throw new SetupException(this.getClass().getSimpleName() + " has no source.");
         }
 
-        return new TimestampCacheKey(this.source, URLUtils.getLastModified(this.source));
+        return new TimestampCacheKey(this.source, URLConnectionUtils.getLastModified(this.source));
     }
 }

Modified: cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XIncludeTransformer.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XIncludeTransformer.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XIncludeTransformer.java (original)
+++ cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XIncludeTransformer.java Tue Jul  3 08:30:31 2012
@@ -26,18 +26,19 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 import org.apache.cocoon.pipeline.ProcessingException;
 import org.apache.cocoon.pipeline.caching.CacheKey;
+import org.apache.cocoon.pipeline.caching.CachedCacheKey;
 import org.apache.cocoon.pipeline.caching.CompoundCacheKey;
 import org.apache.cocoon.pipeline.caching.TimestampCacheKey;
+import org.apache.cocoon.pipeline.caching.URLListCacheKey;
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
+import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.apache.cocoon.pipeline.util.URLConnectionUtils;
 import org.apache.cocoon.sax.AbstractSAXTransformer;
 import org.apache.cocoon.sax.SAXConsumer;
-import org.apache.cocoon.sax.util.URLUtils;
 import org.apache.cocoon.sax.util.XMLUtils;
 import org.apache.cocoon.sax.xpointer.ParseException;
 import org.apache.cocoon.sax.xpointer.XPointer;
@@ -86,7 +87,9 @@ public final class XIncludeTransformer e
 
     private static final String CHARSET = "charset=";
 
-    private static final String BASE_URL = "baseUrl";
+    private static final String BASE_PARAMETER = "baseUrl";
+
+    private static final String KEY_PARAMETER = "cacheKey";
 
     private static final String EMPTY = "";
 
@@ -132,10 +135,13 @@ public final class XIncludeTransformer e
      */
     private final Map<String, String> namespaces = new HashMap<String, String>();
 
-    /**
-     * Keep the set of URLs for <xi:include>.
-     */
-    private final Set<URL> xincludeURLs = new HashSet<URL>();
+    private CachedCacheKey key;
+
+    private URLListCacheKey value;
+
+    private String cacheKey;
+
+    private boolean cacheable = false;
 
     public XIncludeTransformer() {
         // default empty constructor - used in the sitemap
@@ -151,8 +157,8 @@ public final class XIncludeTransformer e
 
     @Override
     public void setConfiguration(final Map<String, ? extends Object> configuration) {
-        this.setBaseUrl((URL) configuration.get(BASE_URL));
-        this.xincludeURLs.clear();
+        this.setBaseUrl((URL) configuration.get(BASE_PARAMETER));
+        this.cacheKey = (String) configuration.get(KEY_PARAMETER);
     }
 
     /**
@@ -217,6 +223,9 @@ public final class XIncludeTransformer e
      */
     @Override
     public void endDocument() throws SAXException {
+        if (cacheable) {
+            this.key.setValue(this.value);
+        }
         if (--this.documentLevel == 0) {
             this.getSAXConsumer().endDocument();
         }
@@ -312,10 +321,13 @@ public final class XIncludeTransformer e
             throw new SAXException(
                     "XIncludeTransformer: encountered empty href (= href pointing to the current document).");
         }
+
         URL source = this.createSource(href);
-        this.xincludeURLs.add(source);
-        URLConnection urlConnection = null;
+        if (cacheable) {
+            this.value.addURL(source);
+        }
 
+        URLConnection urlConnection = null;
         try {
             urlConnection = source.openConnection();
         } catch (IOException ioe) {
@@ -647,17 +659,15 @@ public final class XIncludeTransformer e
 
     @Override
     public CacheKey constructCacheKey() {
-        CompoundCacheKey cacheKey = new CompoundCacheKey();
-
-        if (this.baseUrl != null) {
-            cacheKey.addCacheKey(new TimestampCacheKey(this.baseUrl,
-                    URLUtils.getLastModified(this.baseUrl)));
-        }
-        for (URL xincludeURL : this.xincludeURLs) {
-            cacheKey.addCacheKey(new TimestampCacheKey(xincludeURL,
-                    URLUtils.getLastModified(xincludeURL)));
-        }
+        this.key = new CachedCacheKey();
+        this.value = new URLListCacheKey();
+        this.key.setKey(this.cacheKey);
+        this.cacheable = true;
+        return this.key;
+    }
 
-        return cacheKey;
+    @Override
+    public String toString() {
+        return StringRepresentation.buildString(this, "baseUrl=" + this.baseUrl);
     }
 }

Modified: cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XMLGenerator.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XMLGenerator.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XMLGenerator.java (original)
+++ cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XMLGenerator.java Tue Jul  3 08:30:31 2012
@@ -36,9 +36,9 @@ import org.apache.cocoon.pipeline.cachin
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
 import org.apache.cocoon.pipeline.component.Starter;
 import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.apache.cocoon.pipeline.util.URLConnectionUtils;
 import org.apache.cocoon.sax.AbstractSAXGenerator;
 import org.apache.cocoon.sax.AbstractSAXProducer;
-import org.apache.cocoon.sax.util.URLUtils;
 import org.apache.cocoon.sax.util.XMLUtils;
 import org.apache.cocoon.xml.dom.DOMStreamer;
 import org.apache.cocoon.xml.sax.SAXBuffer;
@@ -383,7 +383,7 @@ public class XMLGenerator extends Abstra
          */
         @Override
         public CacheKey constructCacheKey() {
-            return new TimestampCacheKey(this.source, URLUtils.getLastModified(this.source));
+            return new TimestampCacheKey(this.source, URLConnectionUtils.getLastModified(this.source));
         }
 
         /**

Modified: cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java (original)
+++ cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/XSLTTransformer.java Tue Jul  3 08:30:31 2012
@@ -36,11 +36,11 @@ import org.apache.cocoon.pipeline.cachin
 import org.apache.cocoon.pipeline.caching.TimestampCacheKey;
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
 import org.apache.cocoon.pipeline.util.StringRepresentation;
+import org.apache.cocoon.pipeline.util.URLConnectionUtils;
 import org.apache.cocoon.sax.AbstractSAXTransformer;
 import org.apache.cocoon.sax.SAXConsumer;
 import org.apache.cocoon.sax.util.InMemoryLRUResourceCache;
 import org.apache.cocoon.sax.util.SAXConsumerAdapter;
-import org.apache.cocoon.sax.util.URLUtils;
 import org.apache.cocoon.sax.util.ValidityValue;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -129,7 +129,7 @@ public class XSLTTransformer extends Abs
 
         this.source = source;
 
-        Long lastModified = URLUtils.getLastModified(this.source);
+        Long lastModified = URLConnectionUtils.getLastModified(this.source);
 
         this.templates = null;
         // check the XSLT is in the cache first
@@ -263,7 +263,7 @@ public class XSLTTransformer extends Abs
         }
 
         final CompoundCacheKey cacheKey = new CompoundCacheKey();
-        cacheKey.addCacheKey(new TimestampCacheKey(this.source, URLUtils.getLastModified(this.source)));
+        cacheKey.addCacheKey(new TimestampCacheKey(this.source, URLConnectionUtils.getLastModified(this.source)));
         cacheKey.addCacheKey(ParameterCacheKey.getSitemapSafeInstance(this.parameters));
 
         return cacheKey;

Modified: cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/component/FileReaderComponent.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/component/FileReaderComponent.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/component/FileReaderComponent.java (original)
+++ cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/component/FileReaderComponent.java Tue Jul  3 08:30:31 2012
@@ -27,7 +27,6 @@ import org.apache.cocoon.pipeline.cachin
 import org.apache.cocoon.pipeline.caching.TimestampCacheKey;
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
 import org.apache.cocoon.pipeline.util.URLConnectionUtils;
-import org.apache.cocoon.sax.util.URLUtils;
 
 public class FileReaderComponent extends AbstractReader implements CachingPipelineComponent {
 
@@ -46,7 +45,7 @@ public class FileReaderComponent extends
      */
     @Override
     public CacheKey constructCacheKey() {
-        return new TimestampCacheKey(this.source, URLUtils.getLastModified(this.source));
+        return new TimestampCacheKey(this.source, URLConnectionUtils.getLastModified(this.source));
     }
 
     /**

Modified: cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateGenerator.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateGenerator.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateGenerator.java (original)
+++ cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateGenerator.java Tue Jul  3 08:30:31 2012
@@ -31,8 +31,8 @@ import org.apache.cocoon.pipeline.cachin
 import org.apache.cocoon.pipeline.caching.TimestampCacheKey;
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
 import org.apache.cocoon.pipeline.component.Starter;
+import org.apache.cocoon.pipeline.util.URLConnectionUtils;
 import org.apache.cocoon.sax.AbstractSAXProducer;
-import org.apache.cocoon.sax.util.URLUtils;
 import org.apache.cocoon.sax.util.XMLUtils;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
@@ -96,7 +96,7 @@ public class StringTemplateGenerator ext
         }
 
         final CompoundCacheKey cacheKey = new CompoundCacheKey();
-        cacheKey.addCacheKey(new TimestampCacheKey(this.url, URLUtils.getLastModified(this.url)));
+        cacheKey.addCacheKey(new TimestampCacheKey(this.url, URLConnectionUtils.getLastModified(this.url)));
         cacheKey.addCacheKey(ParameterCacheKey.getSitemapSafeInstance(this.parameters));
 
         return cacheKey;

Modified: cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateReader.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateReader.java?rev=1356609&r1=1356608&r2=1356609&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateReader.java (original)
+++ cocoon/cocoon3/trunk/cocoon-stringtemplate/src/main/java/org/apache/cocoon/stringtemplate/StringTemplateReader.java Tue Jul  3 08:30:31 2012
@@ -33,7 +33,7 @@ import org.apache.cocoon.pipeline.compon
 import org.apache.cocoon.pipeline.component.CachingPipelineComponent;
 import org.apache.cocoon.pipeline.component.Finisher;
 import org.apache.cocoon.pipeline.component.Starter;
-import org.apache.cocoon.sax.util.URLUtils;
+import org.apache.cocoon.pipeline.util.URLConnectionUtils;
 import org.apache.cocoon.servlet.controller.ControllerContextHelper;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringEscapeUtils;
@@ -72,7 +72,7 @@ public class StringTemplateReader extend
         }
 
         final CompoundCacheKey cacheKey = new CompoundCacheKey();
-        cacheKey.addCacheKey(new TimestampCacheKey(this.source, URLUtils.getLastModified(this.source)));
+        cacheKey.addCacheKey(new TimestampCacheKey(this.source, URLConnectionUtils.getLastModified(this.source)));
         cacheKey.addCacheKey(new ParameterCacheKey("contextParameters", this.parameters));
 
         return cacheKey;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.