/* Copyright (c) 2001 - 2013 OpenPlans - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wps.ppio; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.Collections; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.servlet.ServletContext; import org.apache.commons.io.FileUtils; import org.geoserver.data.util.IOUtils; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.wfs.response.ShapeZipOutputFormat; import org.geoserver.wps.resource.ShapefileResource; import org.geoserver.wps.resource.WPSResourceManager; import org.geotools.data.DataUtilities; import org.geotools.data.shapefile.ShapefileDataStore; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.feature.FeatureCollection; /** * Handles input and output of feature collections as zipped shapefiles * * @author Andrea Aime - OpenGeo */ public class ShapeZipPPIO extends BinaryPPIO { WPSResourceManager resources; protected ShapeZipPPIO(WPSResourceManager resources) { super(FeatureCollection.class, FeatureCollection.class, "application/zip"); this.resources = resources; } @Override public void encode(Object value, OutputStream os) throws Exception { SimpleFeatureCollection fc = (SimpleFeatureCollection) value; ShapeZipOutputFormat of = new ShapeZipOutputFormat(); of.write(Collections.singletonList(fc), getCharset(), os, null); } private Charset getCharset() { final String charsetName = GeoServerExtensions.getProperty( ShapeZipOutputFormat.GS_SHAPEFILE_CHARSET, (ServletContext) null); if (charsetName != null) { return Charset.forName(charsetName); } else { // if not specified let's use the shapefile default one return Charset.forName("ISO-8859-1"); } } @Override public Object decode(InputStream input) throws Exception { // create the temp directory and register it as a temporary resource File tempDir = IOUtils.createTempDirectory("shpziptemp"); // unzip to the temporary directory ZipInputStream zis = null; File shapeFile = null; try { zis = new ZipInputStream(input); ZipEntry entry = null; while ((entry = zis.getNextEntry()) != null) { String name = entry.getName(); File file = new File(tempDir, entry.getName()); if (entry.isDirectory()) { file.mkdir(); } else { if (file.getName().toLowerCase().endsWith(".shp")) { shapeFile = file; } int count; byte data[] = new byte[4096]; // write the files to the disk FileOutputStream fos = null; try { fos = new FileOutputStream(file); while ((count = zis.read(data)) != -1) { fos.write(data, 0, count); } fos.flush(); } finally { if (fos != null) { fos.close(); } } } zis.closeEntry(); } } finally { if (zis != null) { zis.close(); } } if (shapeFile == null) { FileUtils.deleteDirectory(tempDir); throw new IOException("Could not find any file with .shp extension in the zip file"); } else { ShapefileDataStore store = new ShapefileDataStore(DataUtilities.fileToURL(shapeFile)); resources.addResource(new ShapefileResource(store, tempDir)); return store.getFeatureSource().getFeatures(); } } @Override public String getFileExtension() { return "zip"; } }