ZipProductHandler.java
- /*
- * ZipProductHandler
- */
- package gov.usgs.earthquake.product.io;
- import gov.usgs.earthquake.product.Content;
- import gov.usgs.earthquake.product.Product;
- import gov.usgs.earthquake.product.ProductId;
- import gov.usgs.util.StreamUtils;
- import java.io.OutputStream;
- import java.util.Map;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.zip.ZipOutputStream;
- import java.util.zip.ZipEntry;
- /**
- * Store a product to an OutputStream using ZIP.
- *
- * Accumulates entire product the same as ObjectProductOutput, then onEndProduct
- * outputs a zip file containing "product.xml" as the first entry and all
- * product content as other entries.
- *
- * Because the zip file is not written until after all content has been
- * "received", all product content may result in in-memory buffering. This is
- * not the case when dealing with File-backed products. If this is a concern,
- * users are encouraged to use the Xml Input and Output classes, which always
- * use streams and never buffer content.
- */
- public class ZipProductHandler extends ObjectProductHandler {
- /** The entry filename used for product metadata. */
- public static final String PRODUCT_XML_ZIP_ENTRYNAME = "product.xml";
- /** The output stream where zip content is written. */
- private OutputStream out;
- /**
- * Construct a new ZipProductHandler object.
- *
- * @param out
- * the output stream where zip content is written.
- */
- public ZipProductHandler(final OutputStream out) {
- this.out = out;
- }
- /**
- * Creates and outputs the zip stream.
- */
- public void onEndProduct(ProductId id) throws Exception {
- super.onEndProduct(id);
- Product product = getProduct();
- // separate all contents that will be zip entries from product
- Map<String, Content> contents = new HashMap<String, Content>(
- product.getContents());
- product.getContents().clear();
- // check for inline content that won't have a zip entry
- Content inlineContent = contents.get("");
- if (inlineContent != null) {
- product.getContents().put("", inlineContent);
- }
- // write zip stream
- ZipOutputStream zos = null;
- try {
- zos = new ZipOutputStream(out);
- // product xml entry
- ZipEntry entry = new ZipEntry(PRODUCT_XML_ZIP_ENTRYNAME);
- entry.setTime(product.getId().getUpdateTime().getTime());
- zos.putNextEntry(entry);
- new ObjectProductSource(product).streamTo(new XmlProductHandler(
- new StreamUtils.UnclosableOutputStream(zos)));
- // zos.closeEntry();
- // all other content entries
- Iterator<String> paths = contents.keySet().iterator();
- while (paths.hasNext()) {
- String path = paths.next();
- if ("".equals(path)) {
- // inline content doesn't get separate entry
- continue;
- }
- Content content = contents.get(path);
- entry = new ZipEntry(path);
- entry.setTime(content.getLastModified().getTime());
- entry.setComment(content.getContentType());
- Long length = content.getLength();
- if (length != null && length > 0) {
- entry.setSize(content.getLength());
- }
- zos.putNextEntry(entry);
- StreamUtils.transferStream(content.getInputStream(),
- new StreamUtils.UnclosableOutputStream(zos));
- // zos.closeEntry();
- }
- } finally {
- // done
- zos.finish();
- zos.flush();
- StreamUtils.closeStream(zos);
- }
- }
- /**
- * Free any resources associated with this handler.
- */
- @Override
- public void close() {
- StreamUtils.closeStream(out);
- }
- }