/** * Copyright (C) 2007 - 2016 52°North Initiative for Geospatial Open Source * Software GmbH * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * If the program is linked with libraries which are licensed under one of * the following licenses, the combination of the program with the linked * library is not considered a "derivative work" of the program: * * • Apache License, version 2.0 * • Apache Software License, version 1.0 * • GNU Lesser General Public License, version 3 * • Mozilla Public License, versions 1.0, 1.1 and 2.0 * • Common Development and Distribution License (CDDL), version 1.0 * * Therefore the distribution of the program linked with libraries licensed * under the aforementioned licenses, is permitted by the copyright holders * if the distribution is compliant with both the GNU General Public * License version 2 and the aforementioned licenses. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. */ package org.n52.wps.io.data; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Matthias Mueller, TU Dresden; Bastian Schaeffer, IFGI, Benjamin Pross * */ public class GenericFileData { private static Logger LOGGER = LoggerFactory.getLogger(GenericFileData.class); protected final InputStream dataStream; protected String fileExtension; protected final String mimeType; protected File primaryFile; public GenericFileData(InputStream stream, String mimeType) { this.dataStream = stream; this.mimeType = mimeType; this.fileExtension = GenericFileDataConstants.mimeTypeFileTypeLUT() .get(mimeType); if(fileExtension == null){ this.fileExtension = "dat"; } } public GenericFileData(File primaryTempFile, String mimeType) throws IOException { primaryFile = primaryTempFile; this.mimeType = mimeType; this.fileExtension = GenericFileDataConstants.mimeTypeFileTypeLUT() .get(mimeType); InputStream is = null; if (GenericFileDataConstants.getIncludeFilesByMimeType(mimeType) != null) { String baseFile = primaryFile.getName(); baseFile = baseFile.substring(0, baseFile.lastIndexOf(".")); File temp = new File(primaryFile.getAbsolutePath()); File directory = new File(temp.getParent()); String[] extensions = GenericFileDataConstants .getIncludeFilesByMimeType(mimeType); File[] allFiles = new File[extensions.length + 1]; for (int i = 0; i < extensions.length; i++) allFiles[i] = new File(directory, baseFile + "." + extensions[i]); allFiles[extensions.length] = primaryFile; // Handling the case if the files don't exist // (Can occur if ArcGIS backend has an error and returns no files, // but only filenames). int numberOfFiles = allFiles.length; int numberOfMissing = 0; for (int i = 0; i < numberOfFiles; i++){ if (!allFiles[i].exists()){ LOGGER.info("File " + (i+1) + " of " + numberOfFiles + " missing (" + allFiles[i].getName() + ")."); numberOfMissing ++; } } if ((numberOfFiles - numberOfMissing) == 0){ String message = "There is no files to generate data from!"; LOGGER.error(message); throw new FileNotFoundException(message); } else if ((numberOfMissing > 0)){ LOGGER.info("Not all files are available, but the available ones are zipped."); } is = new FileInputStream(org.n52.wps.io.IOUtils.zip(allFiles)); } else { is = new FileInputStream(primaryFile); } this.dataStream = is; } public String writeData(File workspaceDir) { String fileName = null; if (GenericFileDataConstants.getIncludeFilesByMimeType(mimeType) != null) { try { fileName = unzipData(dataStream, fileExtension, workspaceDir); } catch (IOException e) { LOGGER.error("Could not unzip the archive to " + workspaceDir); } } else { try { fileName = justWriteData(dataStream, fileExtension, workspaceDir); } catch (IOException e) { LOGGER.error("Could not write the input to " + workspaceDir); } } return fileName; } private String unzipData(InputStream is, String extension, File writeDirectory) throws IOException { String baseFileName = UUID.randomUUID().toString(); ZipInputStream zipInputStream = new ZipInputStream(is); ZipEntry entry; String returnFile = null; while ((entry = zipInputStream.getNextEntry()) != null) { String currentExtension = entry.getName(); int beginIndex = currentExtension.lastIndexOf(".") + 1; currentExtension = currentExtension.substring(beginIndex); String fileName = baseFileName + "." + currentExtension; File currentFile = new File(writeDirectory, fileName); if (!writeDirectory.exists()){ writeDirectory.mkdir(); } currentFile.createNewFile(); FileOutputStream fos = new FileOutputStream(currentFile); IOUtils.copy(zipInputStream, fos); if (currentExtension.equalsIgnoreCase(extension)) { returnFile = currentFile.getAbsolutePath(); } fos.close(); } zipInputStream.close(); return returnFile; } private String justWriteData(InputStream is, String extension, File writeDirectory) throws IOException { String fileName = null; String baseFileName = UUID.randomUUID().toString(); fileName = baseFileName + "." + extension; File currentFile = new File(writeDirectory, fileName); if (!writeDirectory.exists()){ writeDirectory.mkdir(); } currentFile.createNewFile(); // alter FileName for return fileName = currentFile.getAbsolutePath(); FileOutputStream fos = new FileOutputStream(currentFile); IOUtils.copy(is, fos); fos.close(); is.close(); System.gc(); return fileName; } public File getBaseFile(boolean unzipIfPossible) { String extension = fileExtension; if(primaryFile==null && dataStream!=null){ try{ if(fileExtension.equals("shp")){ extension = "zip"; } primaryFile = File.createTempFile(UUID.randomUUID().toString(), "."+extension); OutputStream out = new FileOutputStream(primaryFile); byte buf[]=new byte[1024]; int len; while((len=dataStream.read(buf))>0){ out.write(buf,0,len); } out.close(); }catch(Exception e){ LOGGER.error(e.getMessage(), e); throw new RuntimeException( "Something went wrong while writing the input stream to the file system", e); } } if(unzipIfPossible && extension.contains("zip")){ try{ File tempFile1 = File.createTempFile(UUID.randomUUID().toString(),""); File dir = new File(tempFile1.getParentFile()+"/"+UUID.randomUUID().toString()); dir.mkdir(); FileInputStream fis = new FileInputStream(primaryFile); ZipInputStream zis = new ZipInputStream(fis); ZipEntry entry; while((entry = zis.getNextEntry()) != null) { LOGGER.debug("Extracting: " +entry); // write the files to the disk FileOutputStream fos = new FileOutputStream(dir.getAbsoluteFile()+"/"+entry.getName()); IOUtils.copy(zis, fos); } zis.close(); File[] files = dir.listFiles(); for(File file : files){ if(file.getName().contains(".shp") || file.getName().contains(".SHP")){ primaryFile = file; } } }catch(Exception e){ LOGGER.error(e.getMessage(), e); throw new RuntimeException("Error while unzipping input data", e); } } return primaryFile; } @Override protected void finalize(){ try{ if (primaryFile != null) { primaryFile.delete(); } }catch(Exception e){ LOGGER.error(e.getMessage(), e); } } public String getMimeType(){ return mimeType; } public String getFileExtension(){ return fileExtension; } public InputStream getDataStream() { return dataStream; } }