/* * 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 - 2008 Pentaho Corporation. All rights reserved. * */ package org.pentaho.platform.engine.services.runtime; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.collections.map.ListOrderedMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.engine.IActionParameter; import org.pentaho.platform.api.engine.IActionSequence; import org.pentaho.platform.api.engine.IActionSequenceResource; import org.pentaho.platform.api.engine.IParameterManager; import org.pentaho.platform.api.engine.IParameterProvider; import org.pentaho.platform.api.engine.ISolutionActionDefinition; import org.pentaho.platform.engine.services.actionsequence.ActionParameter; import org.pentaho.platform.engine.services.actionsequence.ActionParameterSource; import org.pentaho.platform.engine.services.messages.Messages; public class ParameterManager implements IParameterManager { private static final String[] EMPTY_ARRAY = new String[0]; private ListOrderedMap allParams; private ListOrderedMap allResources; private List<IActionParameter> waitingToDieParams; private ListOrderedMap currentInputs; private ListOrderedMap currentOutputs; private ListOrderedMap currentResources; private String[] sequenceInputNames; private String[] sequenceResourceNames; private static final Log logger = LogFactory.getLog(ParameterManager.class); private Map sequenceOutputDefs; ParameterManager() { allParams = new ListOrderedMap(); allResources = new ListOrderedMap(); waitingToDieParams = new ArrayList<IActionParameter>(); currentInputs = new ListOrderedMap(); currentResources = new ListOrderedMap(); currentOutputs = new ListOrderedMap(); sequenceOutputDefs = new ListOrderedMap(); sequenceInputNames = ParameterManager.EMPTY_ARRAY; } @SuppressWarnings({"all"}) ParameterManager(final IActionSequence actionSequence) { this(); allParams.putAll(actionSequence.getInputDefinitions()); sequenceInputNames = (String[]) actionSequence.getInputDefinitions().keySet().toArray(ParameterManager.EMPTY_ARRAY); allResources.putAll(actionSequence.getResourceDefinitions()); sequenceResourceNames = (String[]) actionSequence.getResourceDefinitions().keySet().toArray( ParameterManager.EMPTY_ARRAY); sequenceOutputDefs.putAll(actionSequence.getOutputDefinitions()); } public Map getAllParameters() { return (allParams); } public IActionParameter getCurrentInput(final String inputName) { return ((IActionParameter) currentInputs.get(inputName)); } public IActionParameter getCurrentOutput(final String outputName) { return ((IActionParameter) currentOutputs.get(outputName)); } public IActionSequenceResource getCurrentResource(final String resourceName) { return ((IActionSequenceResource) currentResources.get(resourceName)); } public Set getCurrentInputNames() { return currentInputs.keySet(); } public IActionParameter getLoopParameter(final String inputName) { return ((IActionParameter) allParams.get(inputName)); } public Set getCurrentOutputNames() { return currentOutputs.keySet(); } public Set getCurrentResourceNames() { return (currentResources.keySet()); } protected boolean disposeParameter(final ActionParameter param) { try { if (param != null) { param.dispose(); return true; } } catch (Throwable th) { // Do something here ParameterManager.logger.error(Messages.getInstance().getErrorString( "ParameterManager.ERROR_0001_DISPOSE_ERROR", param.getName()), th); //$NON-NLS-1$ } return false; } public void dispose() { dispose(null); } public void dispose(final List exceptParameters) { if (allParams != null) { for (Iterator it = allParams.values().iterator(); it.hasNext();) { ActionParameter param = (ActionParameter) it.next(); if ((exceptParameters == null) || !exceptParameters.contains(param.getValue())) { disposeParameter(param); } } for (Iterator it = waitingToDieParams.iterator(); it.hasNext();) { ActionParameter param = (ActionParameter) it.next(); if ((exceptParameters == null) || !exceptParameters.contains(param.getValue())) { disposeParameter(param); } } } } public void resetParameters() { dispose(); currentInputs.clear(); currentOutputs.clear(); currentResources.clear(); allParams = resetMap(sequenceInputNames, allParams); allResources = resetMap(sequenceResourceNames, allResources); } private ListOrderedMap resetMap(final String[] names, final ListOrderedMap oldMap) { ListOrderedMap newMap = new ListOrderedMap(); for (String element : names) { newMap.put(element, oldMap.get(element)); } return (newMap); } public void setCurrentParameters(final ISolutionActionDefinition actionDefinition) { currentInputs.clear(); currentOutputs.clear(); currentResources.clear(); if (actionDefinition == null) { currentInputs = resetMap(sequenceInputNames, allParams); currentResources = resetMap(sequenceResourceNames, allParams); for (Iterator it = sequenceOutputDefs.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String outputName = (String) entry.getKey(); IActionParameter param = (IActionParameter) allParams.get(outputName); if (param == null) { currentOutputs.put(outputName, entry.getValue()); } else { currentOutputs.put(outputName, param); } } return; } String key; Object value; for (Iterator it = actionDefinition.getActionInputDefinitions().keySet().iterator(); it.hasNext();) { key = (String) it.next(); value = allParams.get(actionDefinition.getMappedInputName(key)); if (value == null) { value = actionDefinition.getActionInputDefinitions().get(key); if (!((ActionParameter) value).hasDefaultValue()) { value = null; // Only use if there is a default value; } } if (value != null) { currentInputs.put(key, value); } } currentOutputs.putAll(actionDefinition.getActionOutputDefinitions()); // This enables the old behavior - It should eventually be removed if (!actionDefinition.hasActionResources()) { currentResources.putAll(allResources); } else { for (Iterator it = actionDefinition.getActionResourceDefinitionNames().iterator(); it.hasNext();) { key = (String) it.next(); String key2 = actionDefinition.getMappedResourceName(key); value = allResources.get(key2); currentResources.put(key, value); } } } public void addToAllInputs(final String key, final IActionParameter param) { IActionParameter old = (IActionParameter) allParams.put(key, param); if ((old != null) && !allParams.containsValue(old)) { waitingToDieParams.add(old); // Just in case a parameter gets over written delete it at the final dispose } } public void addToCurrentInputs(final String key, final IActionParameter param) { if (currentInputs.containsKey(key)) { currentInputs.remove(key); } currentInputs.put(key, param); } public boolean addOutputParameters(final ISolutionActionDefinition actionDefinition) { String key; for (Iterator it = actionDefinition.getActionOutputDefinitions().keySet().iterator(); it.hasNext();) { key = (String) it.next(); IActionParameter outputParam = (IActionParameter) currentOutputs.get(key); key = actionDefinition.getMappedOutputName(key); // If we already have a parameter with this name, set the value and reuse the definition. IActionParameter param = (IActionParameter) allParams.get(key); if (param != null) { if (param != outputParam) { // This is a trap for catching temp params that didn't get deleted at the end of the last loop param.dispose(); param.setValue(outputParam.getValue()); } } else { addToAllInputs(key, outputParam); } } return (true); } /** * Returns a mapping of output parameters and the value and destination. * * @param actionSequence The Action Sequence definition to use * * @return a map with the param name as the key and a ReturnParameter containing the data. */ public Map getReturnParameters() { ListOrderedMap returnMap = new ListOrderedMap(); // Iterate for each output defined for (Iterator it = sequenceOutputDefs.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String outputName = (String) entry.getKey(); IActionParameter outputParam = (IActionParameter) entry.getValue(); // The output Action Parameter objects do not have values - they are just the definition // Pull the value from allParams IActionParameter inputParam = (IActionParameter) allParams.get(outputName); if (inputParam == null) { returnMap.put(outputParam.getName(), null); } else { for (Iterator varIt = outputParam.getVariables().iterator(); varIt.hasNext();) { ActionParameterSource src = (ActionParameterSource) varIt.next(); returnMap.put(outputParam.getName(), new ReturnParameter(src.getSourceName(), src.getValue(), inputParam .getValue())); } } } return (returnMap); } public class ReturnParameter { public String destinationName; public String destinationParameter; public Object value; public ReturnParameter(final String destinationName, final String destinationParameter, final Object value) { this.destinationName = destinationName; this.destinationParameter = destinationParameter; this.value = value; } } public String getActualRequestParameterName(final String fieldName) { /* * This method solves the problem that exists when generating an xForm * based on the parameter definition. The parameter definition looks * like this: * * <REGION type="string"> <default-value></default-value> <sources> * <request>regn</request> </sources> </REGION> * * In the above definition, the parameter name is REGION, but we'll be * looking for the variable regn in the request. Before this fix, the * XForm would generate code that puts REGION on the request, not regn. * * MB */ // TODO - figure out the actual name used - this is just a guess - maybe store in the ActionParam IActionParameter actionParameter = getCurrentInput(fieldName); if (actionParameter != null) { List vars = actionParameter.getVariables(); for (int i = 0; i < vars.size(); i++) { ActionParameterSource source = (ActionParameterSource) (vars.get(i)); if (source.getSourceName().equals(IParameterProvider.SCOPE_REQUEST)) { return source.getValue(); } } } return fieldName; } public IActionParameter getInput(final String inputName) { return ((IActionParameter) allParams.get(inputName)); } }