/*! * 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-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.platform.api.repository2.unified.data.simple; import org.apache.commons.lang.StringUtils; import org.pentaho.platform.api.repository2.unified.IRepositoryFileData; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import java.util.Arrays; /** * A {@link IRepositoryFileData} that has an input stream, encoding, and optional MIME type. * * @author mlowery */ public class SimpleRepositoryFileData implements IRepositoryFileData { // ~ Static fields/initializers // ====================================================================================== private static final long serialVersionUID = -1571991472814251230L; // ~ Instance fields // ================================================================================================= private InputStream stream; private String encoding; private String mimeType; // ~ Constructors // ==================================================================================================== public SimpleRepositoryFileData( final InputStream stream, final String encoding, final String mimeType ) { super(); this.stream = stream; this.encoding = encoding; this.mimeType = mimeType; } // ~ Methods // ========================================================================================================= /** * Returns a stream for reading the data in this file. * * @return stream (may be {@code null}) * @deprecated Use {@link #getInputStream()} instead. Proguard likes to obfuscate any method named getStream that * returns an InputStream, even if you tell it not to via keep rules. */ @Deprecated public InputStream getStream() { return stream; } /** * Returns a stream for reading the data in this file. * * @return stream (may be {@code null}) */ public InputStream getInputStream() { return stream; } /** * Returns the character encoding of the bytes in the data stream. May be {@code null} for non-character data. * * @return character encoding */ public String getEncoding() { return encoding; } /** * Returns the MIME type of the data in this file. * * @return MIME type */ public String getMimeType() { return mimeType; } /* * (non-Javadoc) * * @see org.pentaho.platform.api.repository2.unified.IRepositoryFileData#getDataSize() */ @Override public long getDataSize() { try { return stream.available(); } catch ( IOException e ) { return 0; } } @Override @SuppressWarnings( "nls" ) public String toString() { final int MAX_EXCERPT_LENGTH = 20; StringBuilder buf = new StringBuilder(); buf.append( "SimpleRepositoryFileData[" ); if ( stream.markSupported() ) { stream.mark( Integer.MAX_VALUE ); buf.append( "stream excerpt=" ); if ( StringUtils.isNotBlank( encoding ) ) { String text = null; try { text = toString( stream, encoding ); } catch ( IOException e ) { throw new RuntimeException( e ); } buf.append( head( text, MAX_EXCERPT_LENGTH ) ); buf.append( "," ); buf.append( "encoding=" ); buf.append( encoding ); } else { byte[] bytes = null; try { bytes = toByteArray( stream ); } catch ( IOException e ) { throw new RuntimeException( e ); } buf.append( head( bytes, MAX_EXCERPT_LENGTH ) ); } try { stream.reset(); } catch ( IOException e ) { throw new RuntimeException( e ); } } else { buf.append( "stream=<unable to show>" ); } buf.append( "," ); buf.append( "mimeType=" ); buf.append( mimeType ); buf.append( "]" ); return buf.toString(); } /** * Returns at most {@code count} characters from {@code str}. */ @SuppressWarnings( "nls" ) private String head( final String str, final int count ) { if ( str.length() > count ) { return str.substring( 0, count ) + "..."; } else { return str; } } /** * Returns {@code String} representation of array consisting of at most {@code count} bytes from {@code bytes}. */ @SuppressWarnings( "nls" ) private String head( final byte[] bytes, final int count ) { if ( bytes.length > count ) { StringBuilder buf = new StringBuilder(); buf.append( "[" ); for ( int i = 0; i < count; i++ ) { if ( i > 0 ) { buf.append( ", " ); } buf.append( bytes[i] ); } buf.append( "..." ); buf.append( "]" ); return buf.toString(); } else { return Arrays.toString( bytes ); } } /* * Copied from IOUtils. */ private static String toString( final InputStream input, final String encoding ) throws IOException { final int DEFAULT_BUFFER_SIZE = 1024 * 4; StringWriter sw = new StringWriter(); InputStreamReader in = new InputStreamReader( input, encoding ); char[] buffer = new char[DEFAULT_BUFFER_SIZE]; int n = 0; while ( -1 != ( n = in.read( buffer ) ) ) { sw.write( buffer, 0, n ); } return sw.toString(); } /* * Copied from IOUtils. */ private static byte[] toByteArray( final InputStream input ) throws IOException { final int DEFAULT_BUFFER_SIZE = 1024 * 4; ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; int n = 0; while ( -1 != ( n = input.read( buffer ) ) ) { output.write( buffer, 0, n ); } return output.toByteArray(); } }