blob: f7ba22fd3b587751e19819e9388018af7df5d114 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.components.source.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.cocoon.util.MIMEUtils;
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$
* @since 2.1.8
*/
public class ZipSource extends AbstractLogEnabled
implements Source {
private String protocol;
private Source archive;
private String filePath;
public ZipSource(String protocol, Source archive, String filePath) {
this.protocol = protocol;
this.archive = archive;
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;
try {
zipStream = new ZipInputStream(this.archive.getInputStream());
return findEntry(zipStream) != null;
} catch (IOException e) {
return false;
} finally {
try {
if (zipStream != null) {
zipStream.close();
}
} catch (IOException e) {
getLogger().error("IOException while closing ZipInputStream: " + this.filePath);
}
}
}
public InputStream getInputStream() throws IOException, SourceNotFoundException {
ZipInputStream zipStream = new ZipInputStream(this.archive.getInputStream());
try {
ZipEntry entry = findEntry(zipStream);
if (entry == null) {
throw new SourceNotFoundException("File " + this.filePath + " is not found 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);
}
}
// Return an input stream
return new ByteArrayInputStream(baos.toByteArray());
} finally {
try {
zipStream.close();
} catch (IOException e) {
getLogger().error("IOException while closing ZipInputStream: " + this.filePath);
}
}
}
public String getURI() {
return this.protocol + ":" + this.archive.getURI() + "!/" + this.filePath;
}
public String getScheme() {
return this.protocol;
}
public SourceValidity getValidity() {
return this.archive.getValidity();
}
public void refresh() {
}
public String getMimeType() {
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();
}
}