/*!
* 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.plugin.action.builtin;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.actionsequence.dom.ActionInputConstant;
import org.pentaho.actionsequence.dom.actions.SubActionAction;
import org.pentaho.platform.api.engine.IActionParameter;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.api.engine.IRuntimeContext;
import org.pentaho.platform.api.engine.ISolutionEngine;
import org.pentaho.platform.engine.core.solution.PentahoSessionParameterProvider;
import org.pentaho.platform.engine.core.system.UserSession;
import org.pentaho.platform.engine.services.solution.ComponentBase;
import org.pentaho.platform.engine.services.solution.SolutionHelper;
import org.pentaho.platform.engine.services.solution.StandardSettings;
import org.pentaho.platform.plugin.action.messages.Messages;
import org.pentaho.platform.util.messages.LocaleHelper;
public class SubActionComponent extends ComponentBase {
private static final long serialVersionUID = 3557732430102823611L;
private static final String PATH_SEPARATOR = "/"; //$NON-NLS-1$
@Override
public Log getLogger() {
return LogFactory.getLog( SubActionComponent.class );
}
@Override
protected boolean validateAction() {
boolean value = false;
SubActionAction subAction = null;
if ( getActionDefinition() instanceof SubActionAction ) {
subAction = (SubActionAction) getActionDefinition();
if ( ( subAction.getAction() != ActionInputConstant.NULL_INPUT )
&& ( subAction.getPath() != ActionInputConstant.NULL_INPUT )
&& ( subAction.getSolution() != ActionInputConstant.NULL_INPUT ) ) {
value = true;
} else if ( subAction.getPath() != ActionInputConstant.NULL_INPUT ) {
// for backwards compatibility we will retain action/path/solution
// however, in 5.0 and beyond we only need the path element, eg /home/user/folder/file.xaction
value = true;
}
} else {
error( Messages.getInstance().getErrorString(
"ComponentBase.ERROR_0001_UNKNOWN_ACTION_TYPE", getActionDefinition().getElement().asXML() ) ); //$NON-NLS-1$
}
return value;
}
@Override
protected boolean validateSystemSettings() {
return true;
}
@Override
public void done() {
}
public String buildActionPath( final String solution, final String path, final String action ) {
String actionPath = "";
if ( StringUtils.isEmpty( solution ) == false ) {
actionPath = solution;
}
if ( StringUtils.isEmpty( path ) == false ) {
if ( StringUtils.isEmpty( actionPath ) ) {
actionPath = path;
} else {
actionPath += PATH_SEPARATOR + path;
}
}
if ( StringUtils.isEmpty( action ) == false ) {
if ( StringUtils.isEmpty( actionPath ) ) {
actionPath = action;
} else {
actionPath += PATH_SEPARATOR + action;
}
}
// in the unlikely event that the xaction is referencing the path to the subaction using
// Windows separators (back-slash), we will now convert them to JCR separator (forward slash)
actionPath = actionPath.replace( '\\', '/' );
// remove any double // that may have been introduced by the xaction providing extra leading
// or trailing slashes which get mixed with the PATH_SEPARATOR that we are adding
while ( actionPath.contains( "//" ) ) {
actionPath = actionPath.replaceAll( "//", "/" );
}
// when using JCR (5.0 and up) we need to make sure the path starts with / (PATH_SEPARATOR)
if ( StringUtils.isEmpty( actionPath ) == false
&& actionPath.startsWith( PATH_SEPARATOR ) == false ) {
actionPath = PATH_SEPARATOR + actionPath;
}
return actionPath;
}
@SuppressWarnings ( "deprecation" )
@Override
protected boolean executeAction() throws Throwable {
SubActionAction subAction = (SubActionAction) getActionDefinition();
List<Object> ignoreParameters = new ArrayList<Object>();
String actionPath = buildActionPath( subAction.getSolution().getStringValue(),
subAction.getPath().getStringValue(),
subAction.getAction().getStringValue() );
// see if we are supposed to proxy the session
IPentahoSession session = getSession();
if ( subAction.getSessionProxy() != ActionInputConstant.NULL_INPUT ) {
String sessionName = subAction.getSessionProxy().getStringValue();
// TODO support user-by-user locales
PentahoSessionParameterProvider params = new PentahoSessionParameterProvider( session );
session = new UserSession( sessionName, LocaleHelper.getLocale(), params );
}
// create a parameter provider
HashMap<String, Object> parameters = new HashMap<String, Object>();
Iterator<?> iterator = getInputNames().iterator();
while ( iterator.hasNext() ) {
String inputName = (String) iterator.next();
if ( !StandardSettings.SOLUTION.equals( inputName ) && !StandardSettings.PATH.equals( inputName )
&& !StandardSettings.ACTION.equals( inputName ) ) {
Object value = getInputValue( inputName );
ignoreParameters.add( value );
parameters.put( inputName, value );
}
}
parameters
.put( StandardSettings.ACTION_URL_COMPONENT, getInputStringValue( StandardSettings.ACTION_URL_COMPONENT ) );
// get the ouptut stream
// TODO verify this with MB and JD
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // getDefaultOutputStream();
ISolutionEngine solutionEngine = null;
try {
solutionEngine =
SolutionHelper.execute( getProcessId(), session, actionPath, parameters, outputStream, null, true, false );
if ( outputStream.size() > 0 ) {
getDefaultOutputStream( null ).write( outputStream.toByteArray() );
}
int status = solutionEngine.getStatus();
if ( status == IRuntimeContext.RUNTIME_STATUS_SUCCESS ) {
// now pass any outputs back
Iterator<?> it = this.getOutputNames().iterator();
while ( it.hasNext() ) {
String outputName = (String) it.next();
IActionParameter param = solutionEngine.getExecutionContext().getOutputParameter( outputName );
if ( param != null ) {
setOutputValue( outputName, param.getValue() );
ignoreParameters.add( param.getValue() );
}
}
return true;
} else {
return false;
}
} finally {
if ( solutionEngine != null ) {
solutionEngine.getExecutionContext().dispose( ignoreParameters );
}
}
}
@Override
public boolean init() {
return true;
}
}