You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by vg...@apache.org on 2005/10/04 16:39:07 UTC
svn commit: r293608 - in /cocoon/blocks/scratchpad/trunk:
java/org/apache/cocoon/components/source/impl/ZipSource.java
java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java
samples/sources/sitemap.xmap
Author: vgritsenko
Date: Tue Oct 4 07:38:53 2005
New Revision: 293608
URL: http://svn.apache.org/viewcvs?rev=293608&view=rev
Log:
changed zip: source url syntax to be same as for jar:
fixed memory leak
Modified:
cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSource.java
cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java
cocoon/blocks/scratchpad/trunk/samples/sources/sitemap.xmap
Modified: cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSource.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSource.java?rev=293608&r1=293607&r2=293608&view=diff
==============================================================================
--- cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSource.java (original)
+++ cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSource.java Tue Oct 4 07:38:53 2005
@@ -1,12 +1,12 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
+ * 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.
@@ -27,104 +27,108 @@
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceNotFoundException;
import org.apache.excalibur.source.SourceValidity;
+import org.apache.excalibur.source.SourceResolver;
/**
- * @author <a href="http://apache.org/~reinhard">Reinhard Poetz</a>
- * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
- * @version CVS $Id: ZipSource.java,v 1.2 2004/03/05 10:07:25 bdelacretaz Exp $
- * @since 2.1.4
- */
-public class ZipSource extends AbstractLogEnabled implements Source {
+ * @author <a href="http://apache.org/~reinhard">Reinhard Poetz</a>
+ * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
+ * @version CVS $Id$
+ * @since 2.1.8
+ */
+public class ZipSource extends AbstractLogEnabled
+ implements Source {
+
+ private String protocol;
+ private Source archive;
+ private String filePath;
- Source archive;
- String documentName;
- public ZipSource(Source archive, String fileName) {
+ public ZipSource(String protocol, Source archive, String filePath) {
+ this.protocol = protocol;
this.archive = archive;
- this.documentName = fileName;
+ this.filePath = filePath;
+ }
+
+ private ZipEntry findEntry(ZipInputStream zipStream)
+ throws IOException {
+ ZipEntry entry;
+ while ((entry = zipStream.getNextEntry()) != null) {
+ if (entry.getName().equals(this.filePath)) {
+ return entry;
+ }
+ zipStream.closeEntry();
+ }
+
+ return null;
+ }
+
+ /* package access */
+ void dispose(SourceResolver resolver) {
+ resolver.release(this.archive);
+ this.archive = null;
}
public boolean exists() {
if(!this.archive.exists()) {
return false;
}
+
ZipInputStream zipStream = null;
- ZipEntry document = null;
- boolean found = false;
try {
zipStream = new ZipInputStream(this.archive.getInputStream());
- do {
- document = zipStream.getNextEntry();
- if (document != null) {
- if (document.getName().equals(this.documentName)) {
- found = true;
- } else {
- zipStream.closeEntry();
- }
- }
- } while (document != null && found == false);
- } catch(IOException ioe) {
+ return findEntry(zipStream) != null;
+ } catch (IOException e) {
return false;
} finally {
try {
- zipStream.close();
- } catch (IOException ioe) {
- this.getLogger().error("Error while closing ZipInputStream: " + this.documentName);
+ if (zipStream != null) {
+ zipStream.close();
+ }
+ } catch (IOException e) {
+ getLogger().error("IOException while closing ZipInputStream: " + this.filePath);
}
- }
- return found;
+ }
}
-
+
public InputStream getInputStream()
- throws IOException, SourceNotFoundException {
+ throws IOException, SourceNotFoundException {
- ZipInputStream zipStream =
- new ZipInputStream(this.archive.getInputStream());
- ZipEntry document = null;
- boolean found = false;
- do {
- document = zipStream.getNextEntry();
- if (document != null) {
- if (document.getName().equals(this.documentName)) {
- found = true;
- } else {
- // go to next entry
- zipStream.closeEntry();
- }
+ ZipInputStream zipStream = new ZipInputStream(this.archive.getInputStream());
+ try {
+ ZipEntry entry = findEntry(zipStream);
+ if (entry == null) {
+ throw new SourceNotFoundException("File " + filePath + " is not found in the archive " +
+ this.archive.getURI());
}
- } while (document != null && found == false);
- if (document == null) {
- throw new SourceNotFoundException(
- "The document "
- + documentName
- + " is not in the archive "
- + this.archive.getURI());
- }
+ // Now we will extract the document and write it into a byte array
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buffer = new byte[8192];
+ int length;
+ while (zipStream.available() > 0) {
+ length = zipStream.read(buffer, 0, 8192);
+ if (length > 0) {
+ baos.write(buffer, 0, length);
+ }
+ }
- // now we will extract the document and write it into a byte array
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] buffer = new byte[8192];
- int length = -1;
- while (zipStream.available() > 0) {
- length = zipStream.read(buffer, 0, 8192);
- if (length > 0) {
- baos.write(buffer, 0, length);
+ // Return an input stream
+ return new ByteArrayInputStream(baos.toByteArray());
+ } finally {
+ try {
+ zipStream.close();
+ } catch (IOException e) {
+ getLogger().error("IOException while closing ZipInputStream: " + this.filePath);
}
}
- zipStream.close();
- baos.flush();
-
- // return an input stream
- return new ByteArrayInputStream(baos.toByteArray());
}
public String getURI() {
- return this.archive.getURI() + "/" + this.documentName;
+ return this.protocol + this.archive.getURI() + "!/" + this.filePath;
}
public String getScheme() {
- return ZipSourceFactory.ZIP_SOURCE_SCHEME;
+ return this.protocol;
}
public SourceValidity getValidity() {
@@ -135,16 +139,35 @@
}
public String getMimeType() {
- String ext = this.documentName.substring( this.documentName.lastIndexOf(".") );
- return MIMEUtils.getMIMEType( ext );
+ String ext = this.filePath.substring(this.filePath.lastIndexOf("."));
+ return MIMEUtils.getMIMEType(ext);
}
public long getContentLength() {
+ ZipInputStream zipStream = null;
+ try {
+ zipStream = new ZipInputStream(this.archive.getInputStream());
+ ZipEntry entry = findEntry(zipStream);
+ if (entry != null) {
+ return entry.getSize();
+ }
+
+ } catch (IOException e) {
+ // Ignored
+ } finally {
+ try {
+ if (zipStream != null) {
+ zipStream.close();
+ }
+ } catch (IOException e) {
+ getLogger().error("IOException while closing ZipInputStream: " + this.filePath);
+ }
+ }
+
return -1;
}
public long getLastModified() {
return this.archive.getLastModified();
}
-
}
Modified: cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java?rev=293608&r1=293607&r2=293608&view=diff
==============================================================================
--- cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java (original)
+++ cocoon/blocks/scratchpad/trunk/java/org/apache/cocoon/components/source/impl/ZipSourceFactory.java Tue Oct 4 07:38:53 2005
@@ -1,12 +1,12 @@
/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
+ * 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.
@@ -29,63 +29,82 @@
import org.apache.excalibur.source.SourceFactory;
import org.apache.excalibur.source.SourceResolver;
-
-/** Implementation of a {@link Source} that gets its content from
- * and ZIP archive.
- *
- * A ZIP source can be reached using the zip:// pseudo-protocol. The syntax is
- * zip://myFile.xml@myZip.zip (zip://[file]@[archive])
- *
- * @author <a href="http://apache.org/~reinhard">Reinhard Poetz</a>
- * @version CVS $Id$
- * @since 2.1.4
- */
+/**
+ * Implementation of a {@link Source} that gets its content from
+ * a ZIP archive.
+ *
+ * <p>
+ * A ZIP source can be obtained using the <code>zip:</code> pseudo-protocol.
+ * The syntax for protocol is
+ * <pre>
+ * zip:[archive-url]!/[file-path]
+ * </pre>
+ *
+ * Where, <code>archive-url</code> can be any supported Cocoon URL, and
+ * <code>file-path</code> is the path to the file within archive.
+ *
+ * @author <a href="http://apache.org/~reinhard">Reinhard Poetz</a>
+ * @version CVS $Id$
+ * @since 2.1.8
+ */
public class ZipSourceFactory extends AbstractLogEnabled
- implements SourceFactory, ThreadSafe, Serviceable {
+ implements SourceFactory, ThreadSafe, Serviceable {
+
+ private ServiceManager manager;
+
+
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ }
- protected ServiceManager manager;
- public final static String ZIP_SOURCE_SCHEME = "zip:";
public Source getSource(String location, Map parameters)
- throws IOException, MalformedURLException {
-
- if ( this.getLogger().isDebugEnabled() ) {
- this.getLogger().debug("Processing " + location);
- }
-
- // syntax checks
- int separatorPos = location.indexOf('@');
- if (separatorPos == -1) {
- throw new MalformedURLException("@ required in URI: " + location);
- }
- int protocolEnd = location.indexOf("://");
+ throws IOException, MalformedURLException {
+ // Checks URL syntax
+ int protocolEnd = location.indexOf(":");
if (protocolEnd == -1) {
- throw new MalformedURLException("URI does not contain '://' : " + location);
+ throw new MalformedURLException("Protocol ':' separator is missing in URL: " + location);
}
- // get the source of the archive and return the ZipSource passing
- // a source retrieved from the SourceResolver
- String documentName = location.substring(protocolEnd + 3, separatorPos);
+ int archiveEnd = location.lastIndexOf("!/");
+ if (archiveEnd == -1) {
+ throw new MalformedURLException("File path '!/' separator is missing in URL: " + location);
+ }
+
+ // Get protocol. Protocol is configurable via cocoon.xconf
+ final String protocol = location.substring(0, protocolEnd - 1);
+
+ // Get archive URL
+ final String archiveURL = location.substring(protocolEnd + 1, archiveEnd);
+
+ // Get file path
+ final String filePath = location.substring(archiveEnd + 2);
+
+ // Resolve archive source
Source archive;
SourceResolver resolver = null;
try {
- resolver = (SourceResolver)this.manager.lookup( SourceResolver.ROLE );
- archive = resolver.resolveURI(location.substring(separatorPos + 1));
+ resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+ archive = resolver.resolveURI(archiveURL);
} catch (ServiceException se) {
throw new SourceException("SourceResolver is not available.", se);
} finally {
this.manager.release(resolver);
}
- return new ZipSource(archive, documentName);
- }
-
- public void release(Source source) {
- // not necessary here
+ return new ZipSource(protocol, archive, filePath);
}
- public void service(ServiceManager manager) throws ServiceException {
- this.manager = manager;
+ public void release(Source source) {
+ SourceResolver resolver = null;
+ try {
+ resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
+ ((ZipSource) source).dispose(resolver);
+ } catch (ServiceException e) {
+ // Ignored
+ getLogger().error("ServiceException while looking up SourceResolver in release()", e);
+ } finally {
+ this.manager.release(resolver);
+ }
}
-
}
Modified: cocoon/blocks/scratchpad/trunk/samples/sources/sitemap.xmap
URL: http://svn.apache.org/viewcvs/cocoon/blocks/scratchpad/trunk/samples/sources/sitemap.xmap?rev=293608&r1=293607&r2=293608&view=diff
==============================================================================
--- cocoon/blocks/scratchpad/trunk/samples/sources/sitemap.xmap (original)
+++ cocoon/blocks/scratchpad/trunk/samples/sources/sitemap.xmap Tue Oct 4 07:38:53 2005
@@ -26,14 +26,14 @@
<map:pipelines>
<map:pipeline>
<map:match pattern="simple-zip.xml">
- <map:generate src="zip://test.xml@test.zip"/>
+ <map:generate src="zip:test.zip!/test.xml"/>
<map:serialize type="xml"/>
</map:match>
<map:match pattern="simple-swx.xml">
- <map:generate src="zip://content.xml@test.sxw"/>
+ <map:generate src="zip:test.sxw!/content.xml"/>
<map:serialize type="xml"/>
- </map:match>
+ </map:match>
</map:pipeline>
</map:pipelines>
-
+
</map:sitemap>