001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: */
013: package org.pentaho.core.runtime;
014:
015: import java.util.ArrayList;
016: import java.util.Iterator;
017: import java.util.List;
018: import java.util.Map;
019: import java.util.Set;
020:
021: import org.apache.commons.collections.map.ListOrderedMap;
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024: import org.pentaho.core.solution.ActionParameterSource;
025: import org.pentaho.core.solution.HttpRequestParameterProvider;
026: import org.pentaho.core.solution.IActionDefinition;
027: import org.pentaho.core.solution.IActionResource;
028: import org.pentaho.core.solution.IActionSequence;
029: import org.pentaho.messages.Messages;
030:
031: public class ParameterManager {
032:
033: private static String[] EMPTY_ARRAY = new String[0];
034:
035: private Map allParams;
036:
037: private Map allResources;
038:
039: private List waitingToDieParams;
040:
041: private Map currentInputs;
042:
043: private Map currentOutputs;
044:
045: private Map currentResources;
046:
047: private String[] sequenceInputNames;
048:
049: private String[] sequenceResourceNames;
050:
051: private static final Log logger = LogFactory
052: .getLog(ParameterManager.class);
053:
054: private Map sequenceOutputDefs;
055:
056: ParameterManager() {
057: allParams = new ListOrderedMap();
058: allResources = new ListOrderedMap();
059:
060: waitingToDieParams = new ArrayList();
061:
062: currentInputs = new ListOrderedMap();
063: currentResources = new ListOrderedMap();
064: currentOutputs = new ListOrderedMap();
065:
066: sequenceOutputDefs = new ListOrderedMap();
067: sequenceInputNames = EMPTY_ARRAY;
068: }
069:
070: ParameterManager(IActionSequence actionSequence) {
071: this ();
072: allParams.putAll(actionSequence.getInputDefinitions());
073: sequenceInputNames = (String[]) actionSequence
074: .getInputDefinitions().keySet().toArray(EMPTY_ARRAY);
075:
076: allResources.putAll(actionSequence.getResourceDefinitions());
077: sequenceResourceNames = (String[]) actionSequence
078: .getResourceDefinitions().keySet().toArray(EMPTY_ARRAY);
079:
080: sequenceOutputDefs
081: .putAll(actionSequence.getOutputDefinitions());
082: }
083:
084: public Map getAllParameters() {
085: return (allParams);
086: }
087:
088: public IActionParameter getCurrentInput(String inputName) {
089: return ((IActionParameter) currentInputs.get(inputName));
090: }
091:
092: public IActionParameter getCurrentOutput(String outputName) {
093: return ((IActionParameter) currentOutputs.get(outputName));
094: }
095:
096: public IActionResource getCurrentResource(String resourceName) {
097: return ((IActionResource) currentResources.get(resourceName));
098: }
099:
100: public Set getCurrentInputNames() {
101: return currentInputs.keySet();
102: }
103:
104: public IActionParameter getLoopParameter(String inputName) {
105: return ((IActionParameter) allParams.get(inputName));
106: }
107:
108: public Set getCurrentOutputNames() {
109: return currentOutputs.keySet();
110: }
111:
112: public Set getCurrentResourceNames() {
113: return (currentResources.keySet());
114: }
115:
116: protected boolean disposeParameter(ActionParameter param) {
117: try {
118: if (param != null) {
119: param.dispose();
120: return true;
121: }
122: } catch (Throwable th) {
123: // Do something here
124: logger
125: .error(
126: Messages
127: .getErrorString(
128: "ParameterManager.ERROR_0001_DISPOSE_ERROR", param.getName()), th); //$NON-NLS-1$
129: }
130: return false;
131: }
132:
133: public void dispose() {
134: if (allParams != null) {
135: for (Iterator it = allParams.values().iterator(); it
136: .hasNext();) {
137: disposeParameter((ActionParameter) it.next());
138: }
139: for (Iterator it = waitingToDieParams.iterator(); it
140: .hasNext();) {
141: disposeParameter((ActionParameter) it.next());
142: }
143: }
144: }
145:
146: public void resetParameters() {
147: dispose();
148: currentInputs.clear();
149: currentOutputs.clear();
150: currentResources.clear();
151:
152: allParams = resetMap(sequenceInputNames, allParams);
153: allResources = resetMap(sequenceResourceNames, allResources);
154: }
155:
156: private Map resetMap(String[] names, Map oldMap) {
157: Map newMap = new ListOrderedMap();
158: for (int i = 0; i < names.length; ++i) {
159: newMap.put(names[i], oldMap.get(names[i]));
160: }
161: return (newMap);
162: }
163:
164: public void setCurrentParameters(IActionDefinition actionDefinition) {
165: currentInputs.clear();
166: currentOutputs.clear();
167: currentResources.clear();
168:
169: if (actionDefinition == null) {
170: currentInputs = resetMap(sequenceInputNames, allParams);
171: currentResources = resetMap(sequenceResourceNames,
172: allParams);
173:
174: for (Iterator it = sequenceOutputDefs.entrySet().iterator(); it
175: .hasNext();) {
176: Map.Entry entry = (Map.Entry) it.next();
177: String outputName = (String) entry.getKey();
178: IActionParameter param = (IActionParameter) allParams
179: .get(outputName);
180: if (param == null) {
181: currentOutputs.put(outputName, entry.getValue());
182: } else {
183: currentOutputs.put(outputName, param);
184: }
185: }
186: return;
187: }
188:
189: String key;
190: Object value;
191: for (Iterator it = actionDefinition.getActionInputDefinitions()
192: .keySet().iterator(); it.hasNext();) {
193: key = (String) it.next();
194: value = allParams.get(actionDefinition
195: .getMappedInputName(key));
196: if (value == null) {
197: value = actionDefinition.getActionInputDefinitions()
198: .get(key);
199: if (!((ActionParameter) value).hasDefaultValue()) {
200: value = null; // Only use if there is a default value;
201: }
202: }
203:
204: if (value != null) {
205: currentInputs.put(key, value);
206: }
207: }
208:
209: currentOutputs.putAll(actionDefinition
210: .getActionOutputDefinitions());
211:
212: // This enables the old behavior - It should eventually be removed
213: if (!actionDefinition.hasActionResources()) {
214: currentResources.putAll(allResources);
215: } else {
216: for (Iterator it = actionDefinition
217: .getActionResourceDefinitionNames().iterator(); it
218: .hasNext();) {
219: key = (String) it.next();
220: String key2 = actionDefinition
221: .getMappedResourceName(key);
222: value = allResources.get(key2);
223: currentResources.put(key, value);
224: }
225: }
226: }
227:
228: public void addToAllInputs(String key, IActionParameter param) {
229: IActionParameter old = (IActionParameter) allParams.put(key,
230: param);
231: if ((old != null) && !allParams.containsValue(old)) {
232: waitingToDieParams.add(old); // Just in case a parameter gets over written delete it at the final dispose
233: }
234: }
235:
236: public void addToCurrentInputs(String key, IActionParameter param) {
237: currentInputs.put(key, param);
238: }
239:
240: public boolean addOutputParameters(
241: IActionDefinition actionDefinition) {
242:
243: String key;
244: for (Iterator it = actionDefinition
245: .getActionOutputDefinitions().keySet().iterator(); it
246: .hasNext();) {
247: key = (String) it.next();
248: IActionParameter outputParam = (IActionParameter) currentOutputs
249: .get(key);
250: key = actionDefinition.getMappedOutputName(key);
251:
252: // If we already have a parameter with this name, set the value and reuse the definition.
253: IActionParameter param = (IActionParameter) allParams
254: .get(key);
255: if (param != null) {
256: if (param != outputParam) { // This is a trap for catching temp params that didn't get deleted at the end of the last loop
257: param.dispose();
258: param.setValue(outputParam.getValue());
259: }
260: } else {
261: addToAllInputs(key, outputParam);
262: }
263: }
264:
265: return (true);
266: }
267:
268: /**
269: * Returns a mapping of output parameters and the value and destination.
270: *
271: * @param actionSequence The Action Sequence definition to use
272: *
273: * @return a map with the param name as the key and a ReturnParameter containing the data.
274: */
275: public Map getReturnParameters() {
276: Map returnMap = new ListOrderedMap();
277:
278: // Iterate for each output defined
279: for (Iterator it = sequenceOutputDefs.entrySet().iterator(); it
280: .hasNext();) {
281: Map.Entry entry = (Map.Entry) it.next();
282: String outputName = (String) entry.getKey();
283: IActionParameter outputParam = (IActionParameter) entry
284: .getValue();
285:
286: // The output Action Parameter objects do not have values - they are just the definition
287: // Pull the value from allParams
288: IActionParameter inputParam = (IActionParameter) allParams
289: .get(outputName);
290: if (inputParam == null) {
291: returnMap.put(outputParam.getName(), null);
292: } else {
293: for (Iterator varIt = outputParam.getVariables()
294: .iterator(); varIt.hasNext();) {
295: ActionParameterSource src = (ActionParameterSource) varIt
296: .next();
297: returnMap.put(outputParam.getName(),
298: new ReturnParameter(src.getSourceName(),
299: src.getValue(), inputParam
300: .getValue()));
301: }
302: }
303: }
304: return (returnMap);
305: }
306:
307: public class ReturnParameter {
308: public String destinationName;
309:
310: public String destinationParameter;
311:
312: public Object value;
313:
314: public ReturnParameter(String destinationName,
315: String destinationParameter, Object value) {
316: this .destinationName = destinationName;
317: this .destinationParameter = destinationParameter;
318: this .value = value;
319: }
320: }
321:
322: public String getActualRequestParameterName(String fieldName) {
323: /*
324: * This method solves the problem that exists when generating an xForm
325: * based on the parameter definition. The parameter definition looks
326: * like this:
327: *
328: * <REGION type="string"> <default-value></default-value> <sources>
329: * <request>regn</request> </sources> </REGION>
330: *
331: * In the above definition, the parameter name is REGION, but we'll be
332: * looking for the variable regn in the request. Before this fix, the
333: * XForm would generate code that puts REGION on the request, not regn.
334: *
335: * MB
336: */
337: // TODO - figure out the actual name used - this is just a guess - maybe store in the ActionParam
338: IActionParameter actionParameter = getCurrentInput(fieldName);
339: if (actionParameter != null) {
340: List vars = actionParameter.getVariables();
341:
342: for (int i = 0; i < vars.size(); i++) {
343: ActionParameterSource source = (ActionParameterSource) (vars
344: .get(i));
345: if (source.getSourceName().equals(
346: HttpRequestParameterProvider.SCOPE_REQUEST)) {
347: return source.getValue();
348: }
349: }
350: }
351: return fieldName;
352: }
353:
354: }
|