/*
* 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.
*
* You should have received a copy of the GNU General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.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 General Public License for more details.
*
*
* Copyright 2006 - 2013 Pentaho Corporation. All rights reserved.
*/
package org.pentaho.platform.engine.core.output;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.platform.api.engine.IContentOutputHandler;
import org.pentaho.platform.api.engine.IMimeTypeListener;
import org.pentaho.platform.api.engine.IOutputHandler;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.api.repository.IContentItem;
import org.pentaho.platform.engine.core.messages.Messages;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* @author aaron
*
*/
public class SimpleOutputHandler implements IOutputHandler {
private IContentItem feedbackContent;
boolean allowFeedback;
private String mimeType;
private int outputType = IOutputHandler.OUTPUT_TYPE_DEFAULT;
private boolean contentGenerated;
private Map<String, IContentItem> outputs;
private IPentahoSession session;
private IMimeTypeListener mimeTypeListener;
private boolean responseExpected;
private static final Log logger = LogFactory.getLog( SimpleOutputHandler.class );
/**
* Creates a {@link SimpleContentItem} copy of an {@link IContentItem}
*
* @param contentItem
* provides the underlying outputStream this outputhandler manages. Feedback will also be written to
* this contentItem's output stream if allowFeedback is true
* @param allowFeedback
*/
public SimpleOutputHandler( final IContentItem contentItem, final boolean allowFeedback ) {
contentGenerated = false;
outputs = new HashMap<String, IContentItem>();
try {
String key = IOutputHandler.RESPONSE + "." + IOutputHandler.CONTENT; //$NON-NLS-1$
outputs.put( key, contentItem );
this.allowFeedback = allowFeedback;
if ( allowFeedback ) {
feedbackContent = new SimpleContentItem( contentItem.getOutputStream( null ) );
}
} catch ( IOException ioe ) {
SimpleOutputHandler.logger.error( null, ioe );
}
}
/**
* Creates a SimpleContentItem from an OutputStream.
*
* @param outputStream
* the underlying outputStream this outputhandler manages. Feedback will be written to this output
* stream if allowFeedback is true
* @param allowFeedback
*/
public SimpleOutputHandler( final OutputStream outputStream, final boolean allowFeedback ) {
this.allowFeedback = allowFeedback;
if ( allowFeedback ) {
feedbackContent = new SimpleContentItem( outputStream );
}
contentGenerated = false;
outputs = new HashMap<String, IContentItem>();
setOutputStream( outputStream, IOutputHandler.RESPONSE, IOutputHandler.CONTENT );
}
/*
* (non-Javadoc)
*
* @see
* org.pentaho.platform.api.engine.IOutputHandler#setSession(org.pentaho.platform.api.engine.IPentahoSession)
*/
public void setSession( final IPentahoSession session ) {
this.session = session;
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#getSession()
*/
public IPentahoSession getSession() {
return session;
}
public void setOutputStream( final OutputStream outputStream, final String outputName, final String contentName ) {
String key = outputName + "." + contentName; //$NON-NLS-1$
SimpleContentItem item = new SimpleContentItem( outputStream );
outputs.put( key, item );
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#setOutputPreference(int)
*/
public void setOutputPreference( final int outputType ) {
this.outputType = outputType;
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#contentDone()
*/
public boolean contentDone() {
return contentGenerated;
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#getOutputPreference()
*/
public int getOutputPreference() {
return outputType;
}
public void setMimeType( final String mimeType ) {
this.mimeType = mimeType;
}
public String getMimeType() {
return mimeType;
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#allowFeedback()
*/
public boolean allowFeedback() {
return allowFeedback;
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#getFeedbackContentItem()
*/
public IContentItem getFeedbackContentItem() {
if ( allowFeedback ) {
contentGenerated = true;
/*
* if someone is requesting a feedbackContentItem, we can assume they tend to write feedback back to the
* client, so we set the flag here
*/
responseExpected = true;
return feedbackContent;
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#getOutputContentItem(java.lang.String, java.lang.String,
* java.lang.String, java.lang.String, java.lang.String)
*/
public IContentItem getOutputContentItem( final String outputName, final String contentName, final String instanceId,
final String localMimeType ) {
if ( outputName.equals( IOutputHandler.RESPONSE ) && contentName.equals( IOutputHandler.CONTENT ) ) {
responseExpected = true;
}
String key = outputName + "." + contentName; //$NON-NLS-1$
if ( outputs.get( key ) != null ) {
return outputs.get( key );
} else {
IContentOutputHandler output = PentahoSystem.getOutputDestinationFromContentRef( contentName, session );
// If the output handler wasn't found with just the content name. Try to look it up with the output name as
// well.
// (This mirrors HttpOutputHandler's lookup logic)
if ( output == null ) {
output = PentahoSystem.getOutputDestinationFromContentRef( outputName + ":" + contentName, session ); //$NON-NLS-1$
}
if ( output != null ) {
output.setInstanceId( instanceId );
output.setMimeType( localMimeType );
output.setContentRef( contentName );
if ( contentName.indexOf( ":" ) != -1 ) {
output.setSolutionPath( contentName.substring( contentName.indexOf( ":" ) + 1 ) );
} else {
output.setSolutionPath( null );
}
return output.getFileOutputContentItem();
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.pentaho.platform.api.engine.IOutputHandler#setContentItem(org.pentaho.platform.api.repository.IContentItem
* , java.lang.String, java.lang.String)
*/
public void setContentItem( final IContentItem content, final String objectName, final String contentName ) {
mimeType = content.getMimeType();
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#setOutput(java.lang.String, java.lang.Object)
*
* This implementation tries to write the data in "value" to the response outputstream managed by this output
* handler, or if "value" is null, adds it to a responseAttributes map for later retrieval.
*/
public void setOutput( final String name, final Object value ) throws IOException {
if ( value == null ) {
SimpleOutputHandler.logger.info( Messages.getInstance().getString( "SimpleOutputHandler.INFO_VALUE_IS_NULL" ) ); //$NON-NLS-1$
return;
}
if ( IOutputHandler.CONTENT.equalsIgnoreCase( name ) ) {
IContentItem response = getOutputContentItem( "response", IOutputHandler.CONTENT, null, null ); //$NON-NLS-1$
if ( response != null ) {
// If "value" to set is an IContentItem, then write it to the outputstream
// of the response IContentItem managed by this output handler.
if ( value instanceof IContentItem ) {
IContentItem content = (IContentItem) value;
// See if we should process the input stream. If it's from
// the content repository, then there's an input stream.
// SimpleContentItem and HttpContentItem both return null from
// getInputStream().
InputStream inStr = content.getInputStream();
if ( inStr != null ) {
if ( ( response.getMimeType() == null )
|| ( !response.getMimeType().equalsIgnoreCase( content.getMimeType() ) ) ) {
response.setMimeType( content.getMimeType() );
}
try {
OutputStream outStr = response.getOutputStream( null );
int inCnt = 0;
byte[] buf = new byte[4096];
while ( -1 != ( inCnt = inStr.read( buf ) ) ) {
outStr.write( buf, 0, inCnt );
}
} finally {
try {
inStr.close();
} catch ( Exception ignored ) {
//ignore
}
}
contentGenerated = true;
}
} else {
// if "value" is not an IContentItem, assume it is a string and write it out
if ( response.getMimeType() == null ) {
response.setMimeType( "text/html" ); //$NON-NLS-1$
}
response.getOutputStream( null ).write( value.toString().getBytes() );
contentGenerated = true;
}
}
}
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#getMimeTypeListener()
*/
public IMimeTypeListener getMimeTypeListener() {
return mimeTypeListener;
}
/*
* (non-Javadoc)
*
* @see org.pentaho.platform.api.engine.IOutputHandler#setMimeTypeListener(org.pentaho.platform.api.engine.
* IMimeTypeListener )
*/
public void setMimeTypeListener( final IMimeTypeListener mimeTypeListener ) {
this.mimeTypeListener = mimeTypeListener;
}
public boolean isResponseExpected() {
return responseExpected;
}
}