/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2014 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.platform.dataaccess.datasource.api.resources;
import static javax.ws.rs.core.Response.Status.CONFLICT;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED;
import static javax.ws.rs.core.Response.Status.UNAUTHORIZED;
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.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import org.apache.commons.io.IOUtils;
import org.pentaho.platform.repository2.unified.fileio.RepositoryFileInputStream;
public class ResourceUtil {
public static final String APPLICATION_ZIP = "application/zip"; //$NON-NLS-1$
public Response createAttachment( Map<String, InputStream> fileData, String domainId ) {
String quotedFileName = null;
final InputStream is;
if ( fileData.size() > 1 ) { // we've got more than one file so we want to zip them up and send them
File zipFile = null;
try {
zipFile = createTempFile( "datasourceExport", ".zip" );
zipFile.deleteOnExit();
ZipOutputStream zos = createZipOutputStream( zipFile );
for ( String fileName : fileData.keySet() ) {
InputStream zipEntryIs = null;
try {
ZipEntry entry = createZipEntry( fileName );
zos.putNextEntry( entry );
zipEntryIs = fileData.get( fileName );
copy( zipEntryIs, zos );
} catch ( Exception e ) {
continue;
} finally {
zos.closeEntry();
if ( zipEntryIs != null ) {
zipEntryIs.close();
}
}
}
zos.close();
is = createFileInputStream( zipFile );
} catch ( IOException ioe ) {
return buildServerErrorResponse( ioe );
}
StreamingOutput streamingOutput = createStreamingOutput( is );
final int xmiIndex = domainId.lastIndexOf( ".xmi" ); //$NON-NLS-1$
quotedFileName =
"\"" + ( xmiIndex > 0 ? domainId.substring( 0, xmiIndex ) : domainId ) + ".zip\""; //$NON-NLS-1$//$NON-NLS-2$
return buildOkResponse( streamingOutput, APPLICATION_ZIP, quotedFileName );
} else if ( fileData.size() == 1 ) { // we've got a single metadata file so we just return that.
String fileName = (String) fileData.keySet().toArray()[ 0 ];
quotedFileName = "\"" + fileName + "\""; //$NON-NLS-1$ //$NON-NLS-2$
is = fileData.get( fileName );
String mimeType = getMimeType( is );
StreamingOutput streamingOutput = getStreamingOutput( is );
return buildOkResponse( streamingOutput, mimeType, quotedFileName );
}
return buildServerErrorResponse();
}
protected StreamingOutput createStreamingOutput( final InputStream is ) {
return new StreamingOutput() {
public void write( OutputStream output ) throws IOException {
IOUtils.copy( is, output );
}
};
}
protected FileInputStream createFileInputStream( File zipFile ) throws FileNotFoundException {
return new FileInputStream( zipFile );
}
protected void copy( InputStream zipEntryIs, ZipOutputStream zos ) throws IOException {
IOUtils.copy( zipEntryIs, zos );
}
protected File createTempFile( String fileName, String extension ) throws IOException {
return File.createTempFile( fileName, extension ); //$NON-NLS-1$ //$NON-NLS-2$;
}
protected ZipEntry createZipEntry( String fileName ) {
return new ZipEntry( fileName );
}
protected ZipOutputStream createZipOutputStream( File zipFile ) throws IOException {
return new ZipOutputStream( new FileOutputStream( zipFile ) );
}
protected Response buildOkResponse( StreamingOutput streamingOutput, String mimeType, String quotedFileName ) {
return Response.ok( streamingOutput, mimeType )
.header( "Content-Disposition", "attachment; filename=" + quotedFileName ).build(); //$NON-NLS-1$ //$NON-NLS-2$
}
protected Response buildServerErrorResponse() {
return Response.serverError().build();
}
protected Response buildServerErrorResponse( Exception ioe ) {
return Response.serverError().entity( ioe.toString() ).build();
}
protected String getMimeType( InputStream is ) {
return ( is instanceof RepositoryFileInputStream ) ? ( (RepositoryFileInputStream) is ).getMimeType() : MediaType.TEXT_PLAIN;
}
protected StreamingOutput getStreamingOutput( final InputStream is ) {
return new StreamingOutput() {
public void write( OutputStream output ) throws IOException {
IOUtils.copy( is, output );
}
};
}
static class ContentAlreadyExistsException extends WebApplicationException {
public ContentAlreadyExistsException( String error ) {
super( Response.status( CONFLICT ).entity( error ).type( "text/plain" ).build() );
}
}
static class UnspecifiedErrorException extends WebApplicationException {
public UnspecifiedErrorException( String error ) {
super( Response.status( INTERNAL_SERVER_ERROR ).entity( error ).type( "text/plain" ).build() );
}
}
static class PublishProhibitedException extends WebApplicationException {
public PublishProhibitedException( String error ) {
super( Response.status( UNAUTHORIZED ).entity( error ).type( "text/plain" ).build() );
}
}
static class AccessControlException extends WebApplicationException {
public AccessControlException( String error ) {
super( Response.status( FORBIDDEN ).entity( error ).type( "text/plain" ).build() );
}
}
static class ImportFailedException extends WebApplicationException {
public ImportFailedException( String error ) {
super( Response.status( PRECONDITION_FAILED ).entity( error ).type( "text/plain" ).build() );
}
}
}