/*
* 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.services.solution;
import org.pentaho.platform.api.engine.IExecutionListener;
import org.pentaho.platform.api.engine.ILogger;
import org.pentaho.platform.api.engine.IOutputHandler;
import org.pentaho.platform.api.engine.IParameterProvider;
import org.pentaho.platform.api.engine.IPentahoRequestContext;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.api.engine.IPentahoUrlFactory;
import org.pentaho.platform.api.engine.IRuntimeContext;
import org.pentaho.platform.api.engine.ISolutionEngine;
import org.pentaho.platform.engine.core.output.SimpleOutputHandler;
import org.pentaho.platform.engine.core.solution.SimpleParameterProvider;
import org.pentaho.platform.engine.core.system.PentahoRequestContextHolder;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.engine.core.system.StandaloneSession;
import org.pentaho.platform.engine.services.BaseRequestHandler;
import org.pentaho.platform.util.web.SimpleUrlFactory;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// TODO sbarkdull, ton's of opportunity here for some refactoring to get rid of european reuse
public class SolutionHelper {
/**
*
*
* Runs an action sequence. This method uses the base URL set by the Application Context
*
* @param description
* An identifier for this process. This is used for auditing and logging purposes only.
* @param userId
* The user (or user agent) that is requesting this execution. This is used for auditing and logging and
* also can be used in action sequences (for example to filter data)
* @param actionSequence
* Path to the action sequence file
* @param parameters
* Parameters to be passed to the action sequence
* @param outputStream
* The output stream for content generated by the action sequence. Can be null.
* @return
*/
public static ISolutionEngine execute( final String description, final String userId, final String actionSequence,
final Map parameters, final OutputStream outputStream ) {
StandaloneSession session = new StandaloneSession( userId );
return SolutionHelper.execute( description, session, actionSequence, parameters, outputStream, null, true );
}
/**
*
*
* Runs an action sequence. This method uses the base URL set by the Application Context
*
* @param description
* An identifier for this process. This is used for auditing and logging purposes only.
* @param session
* The user session that is requesting this execution. This is used for auditing and logging and also
* can be used in action sequences (for example to filter data)
* @param actionSequence
* Path to the action sequence file
* @param parameters
* Parameters to be passed to the action sequence
* @param outputStream
* The output stream for content generated by the action sequence. Can be null.
* @return
*/
public static ISolutionEngine execute( final String description, final IPentahoSession session,
final String actionSequence, final Map parameters, final OutputStream outputStream ) {
return SolutionHelper.execute( description, session, actionSequence, parameters, outputStream, null, true );
}
/**
*
*
* Runs an action sequence. This method uses the base URL set by the Application Context
*
* @param description
* An identifier for this process. This is used for auditing and logging purposes only.
* @param session
* The user session that is requesting this execution. This is used for auditing and logging and also
* can be used in action sequences (for example to filter data)
* @param actionSequence
* Path to the action sequence file
* @param parameters
* Parameters to be passed to the action sequence
* @param outputStream
* The output stream for content generated by the action sequence. Can be null.
* @param collateMessages
* Collate a messages list or not. Chose false for very large processes
* @return
*/
public static ISolutionEngine
execute( final String description, final IPentahoSession session, final String actionSequence,
final Map parameters, final OutputStream outputStream, final boolean collateMessages ) {
return SolutionHelper.execute( description, session, actionSequence, parameters, outputStream, null,
collateMessages );
}
private static ISolutionEngine execute( final String description, final IPentahoSession session,
final String actionSequence, final Map parameters, final OutputStream outputStream,
final IExecutionListener execListener, final boolean collateMessages ) {
return SolutionHelper.execute( description, session, actionSequence, parameters, outputStream, execListener,
collateMessages, true );
}
/**
*
*
* Runs an action sequence. This method uses the base URL set by the Application Context
*
* @param description
* An identifier for this process. This is used for auditing and logging purposes only.
* @param session
* The user session that is requesting this execution. This is used for auditing and logging and also
* can be used in action sequences (for example to filter data)
* @param actionSequence
* Path to the action sequence file
* @param parameters
* Parameters to be passed to the action sequence
* @param outputStream
* The output stream for content generated by the action sequence. Can be null.
* @param execListener
* An execution listener for feedback during execution. Can be null.
* @return
*/
public static ISolutionEngine execute( final String description, final IPentahoSession session,
final String actionSequence, final Map parameters, OutputStream outputStream,
final IExecutionListener execListener, final boolean collateMessages, final boolean manageHibernate ) {
if ( manageHibernate ) {
PentahoSystem.systemEntryPoint();
}
ISolutionEngine solutionEngine = null;
try {
solutionEngine = PentahoSystem.get( ISolutionEngine.class, session );
solutionEngine.init( session );
solutionEngine.setlistener( execListener );
SimpleParameterProvider parameterProvider = new SimpleParameterProvider( parameters );
IPentahoRequestContext requestContext = PentahoRequestContextHolder.getRequestContext();
String url = requestContext.getContextPath();
// Modifications by Ezequiel Cuellar
// Old code.
// String baseUrl = PentahoSystem.getApplicationContext().getBaseUrl();
// New code. Since the SubActionComponent is being instantiated below to return feedback
// it is necesary to configure the baseUrl to include the ViewAction.
Object actionUrlComponent = parameters.get( StandardSettings.ACTION_URL_COMPONENT );
if ( ( actionUrlComponent != null ) && ( actionUrlComponent.toString().length() > 0 ) ) {
url += actionUrlComponent.toString();
} else {
url += "ViewAction?"; //$NON-NLS-1$
}
HashMap<String, IParameterProvider> parameterProviderMap = new HashMap<String, IParameterProvider>();
parameterProviderMap.put( IParameterProvider.SCOPE_REQUEST, parameterProvider );
IPentahoUrlFactory urlFactory = new SimpleUrlFactory( url );
String processName = description;
boolean persisted = false;
// for now, the messages list needs to be untyped since we may put exceptions as well as strings in it
List<?> messages = null;
if ( collateMessages ) {
messages = new ArrayList();
}
if ( outputStream == null ) {
outputStream = new ByteArrayOutputStream( 0 );
}
SimpleOutputHandler outputHandler = null;
if ( outputStream != null ) {
// Modifications by Ezequiel Cuellar
// Old code.
// outputHandler = new SimpleOutputHandler(outputStream, false);
// New code. Without setting the allowFeedback parameter to true it is assumed that SubActionComponent
// instances
// are never capable of returning feedback which may not always be the case.
outputHandler = new SimpleOutputHandler( outputStream, true );
outputHandler.setOutputPreference( IOutputHandler.OUTPUT_TYPE_DEFAULT );
}
solutionEngine.execute( actionSequence, processName, false, true, null, persisted, parameterProviderMap,
outputHandler, null, urlFactory, messages );
} finally {
if ( manageHibernate ) {
PentahoSystem.systemExitPoint();
}
}
return solutionEngine;
}
/**
* doAction executes an action within the bi platform and returns true if successful.
*
* Snagged from ChartHelper
*
* @param solutionName
* the solution name
* @param actionPath
* the action path
* @param actionName
* the action name
* @param processId
* the process id
* @param parameterProvider
* the collection of parameters to customize the chart
* @param outputStream
* the output object
* @param userSession
* the user session object
* @param messages
* a collection to store error and logging messages
* @param logger
* logging object
*
* @return the runtime context
*/
public static boolean doAction( String actionPath, final String processId,
final IParameterProvider parameterProvider, final OutputStream outputStream, final IPentahoSession userSession,
final ArrayList messages, final ILogger logger ) {
int status = IRuntimeContext.RUNTIME_STATUS_FAILURE;
IRuntimeContext runtime = null;
try {
runtime =
SolutionHelper.doActionInternal( actionPath, processId, parameterProvider, outputStream, userSession,
messages, logger );
if ( runtime != null ) {
status = runtime.getStatus();
}
} finally {
if ( runtime != null ) {
runtime.dispose();
}
}
return status == IRuntimeContext.RUNTIME_STATUS_SUCCESS;
}
/**
* doAction executes an action within the bi platform and returns the runtime context.
*
* Snagged from ChartHelper
*
* @param solutionName
* the solution name
* @param actionPath
* the action path
* @param actionName
* the action name
* @param processId
* the process id
* @param parameterProvider
* the collection of parameters to customize the chart
* @param userSession
* the user session object
* @param messages
* a collection to store error and logging messages
* @param logger
* logging object
*
* @return the runtime context
*/
public static IRuntimeContext doAction( final String actionPath, final String processId,
final IParameterProvider parameterProvider, final IPentahoSession userSession, final ArrayList messages,
final ILogger logger ) {
return doActionInternal( actionPath, processId, parameterProvider, null, userSession, messages, logger );
}
private static IRuntimeContext doActionInternal( final String actionPath, final String processId,
final IParameterProvider parameterProvider, final OutputStream outputStream, final IPentahoSession userSession,
final ArrayList messages, final ILogger logger ) {
SimpleOutputHandler outputHandler = new SimpleOutputHandler( outputStream, false );
BaseRequestHandler requestHandler =
new BaseRequestHandler( userSession, null, outputHandler, parameterProvider, null );
requestHandler.setProcessId( processId );
requestHandler.setActionPath( actionPath );
return requestHandler.handleActionRequest( 0, 0 );
}
}