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: * @created Jul 18, 2005
014: * @author James Dixon
015: *
016: */
017:
018: package org.pentaho.core.solution;
019:
020: import java.math.BigDecimal;
021: import java.util.HashMap;
022: import java.util.List;
023: import java.util.Map;
024:
025: import org.apache.commons.logging.Log;
026: import org.apache.commons.logging.LogFactory;
027: import org.dom4j.Document;
028: import org.pentaho.core.audit.AuditHelper;
029: import org.pentaho.core.audit.MessageTypes;
030: import org.pentaho.core.repository.IRuntimeElement;
031: import org.pentaho.core.repository.IRuntimeRepository;
032: import org.pentaho.core.repository.ISolutionRepository;
033: import org.pentaho.core.runtime.IRuntimeContext;
034: import org.pentaho.core.runtime.RuntimeContext;
035: import org.pentaho.core.session.IPentahoSession;
036: import org.pentaho.core.system.IPentahoInitializer;
037: import org.pentaho.core.system.JVMParameterProvider;
038: import org.pentaho.core.system.PentahoMessenger;
039: import org.pentaho.core.system.PentahoSystem;
040: import org.pentaho.core.ui.IPentahoUrlFactory;
041: import org.pentaho.core.util.XmlHelper;
042: import org.pentaho.messages.Messages;
043: import org.pentaho.ui.component.charting.FlashChartRequestMapper;
044:
045: import com.pentaho.security.SecurityParameterProvider;
046:
047: public class SolutionEngine extends PentahoMessenger implements
048: ISolutionEngine, IPentahoInitializer {
049:
050: /**
051: *
052: */
053: private static final long serialVersionUID = -8957434833691831700L;
054:
055: private boolean debug = PentahoSystem.debug;
056:
057: private Map parameterProviders;
058:
059: private boolean persisted;
060:
061: private IActionCompleteListener listener;
062:
063: private IPentahoSession session;
064:
065: private IRuntimeContext runtime = null;
066:
067: private int status;
068:
069: private boolean forcePrompt = false;
070:
071: private static String LOG_NAME = "SOLUTION-ENGINE"; //$NON-NLS-1$
072:
073: private static final String JVM_PARAMETER_PROVIDER = "jvm"; //$NON-NLS-1$
074:
075: private static final Log logger = LogFactory
076: .getLog(SolutionEngine.class);
077:
078: private String parameterXsl = null;
079:
080: public Log getLogger() {
081: return logger;
082: }
083:
084: public SolutionEngine() {
085: status = IRuntimeContext.RUNTIME_STATUS_NOT_STARTED;
086: }
087:
088: public void init(IPentahoSession pSession) {
089: parameterProviders = new HashMap();
090: this .session = pSession;
091: this .setParameterProvider(JVM_PARAMETER_PROVIDER,
092: new JVMParameterProvider());
093: setForcePrompt(false);
094: // Provide the security parameter provider to the parameter provider map in the super class
095: SecurityParameterProvider provider = new SecurityParameterProvider(
096: pSession);
097: this .setParameterProvider(
098: SecurityParameterProvider.SCOPE_SECURITY, provider);
099:
100: }
101:
102: public void setParameterProvider(String name,
103: IParameterProvider parameterProvider) {
104: parameterProviders.put(name, parameterProvider);
105: }
106:
107: protected Map getParameterProviders() {
108: return parameterProviders;
109: }
110:
111: public void setlistener(IActionCompleteListener listener) {
112: this .listener = listener;
113: }
114:
115: public void setSession(IPentahoSession session) {
116: this .session = session;
117: }
118:
119: protected boolean checkParameters(String solutionName,
120: String sequencePath, String sequenceName, String processId) {
121: if (processId == null) {
122: // cannot allow this
123: error(Messages
124: .getErrorString("SolutionEngine.ERROR_0001_PROCESS_NOT_SPECIFIED")); //$NON-NLS-1$
125: return false;
126: }
127: if (solutionName == null) {
128: // cannot allow this
129: error(Messages
130: .getErrorString("SolutionEngine.ERROR_0002_SOLUTION_NOT_SPECIFIED")); //$NON-NLS-1$
131: return false;
132: }
133: if (sequencePath == null) {
134: // cannot allow this
135: error(Messages
136: .getErrorString("SolutionEngine.ERROR_0003_PATH_NOT_SPECIFIED")); //$NON-NLS-1$
137: return false;
138: }
139: if (sequenceName == null) {
140: // cannot allow this
141: error(Messages
142: .getErrorString("SolutionEngine.ERROR_0004_ACTION_NOT_SPECIFIED")); //$NON-NLS-1$
143: return false;
144: }
145: return true;
146:
147: }
148:
149: public int getStatus() {
150: return status;
151: }
152:
153: public IRuntimeContext getExecutionContext() {
154: return runtime;
155: }
156:
157: protected IPentahoSession getSession() {
158: return session;
159: }
160:
161: protected IRuntimeContext getRuntime() {
162: return runtime;
163: }
164:
165: protected void setRuntime(IRuntimeContext runtime) {
166: this .runtime = runtime;
167: }
168:
169: protected void auditStart(String solutionName, String sequencePath,
170: String sequenceName, String instanceId) {
171: if (debug) {
172: debug(Messages
173: .getString(
174: "SolutionEngine.DEBUG_STARTING_EXECUTION", solutionName, sequencePath, sequenceName)); //$NON-NLS-1$
175: }
176: genLogIdFromInfo(instanceId, LOG_NAME, sequenceName);
177: }
178:
179: public IRuntimeContext execute(String solutionName,
180: String sequencePath, String sequenceName, String processId,
181: boolean async, boolean instanceEnds, String instanceId,
182: boolean isPersisted, Map parameterProviderMap,
183: IOutputHandler outputHandler,
184: IActionCompleteListener pListener,
185: IPentahoUrlFactory urlFactory, List messages) {
186: applyParameterMappers(parameterProviderMap);
187: return execute(solutionName, sequencePath, sequenceName,
188: processId, async, instanceEnds, instanceId,
189: isPersisted, parameterProviderMap, outputHandler,
190: pListener, urlFactory, messages, null);
191: }
192:
193: public IRuntimeContext execute(String actionSequenceXML,
194: String sequenceName, String processId, boolean async,
195: boolean instanceEnds, String instanceId,
196: boolean isPersisted, Map parameterProviderMap,
197: IOutputHandler outputHandler,
198: IActionCompleteListener pListener,
199: IPentahoUrlFactory urlFactory, List messages) {
200:
201: return execute(
202: "InMemorySolution", "", sequenceName, processId, async, instanceEnds, instanceId, //$NON-NLS-1$ //$NON-NLS-2$
203: isPersisted, parameterProviderMap, outputHandler,
204: pListener, urlFactory, messages, actionSequenceXML);
205: }
206:
207: protected IRuntimeContext execute(String solutionName,
208: String sequencePath, String sequenceName, String processId,
209: boolean async, boolean instanceEnds, String instanceId,
210: boolean isPersisted, Map parameterProviderMap,
211: IOutputHandler outputHandler,
212: IActionCompleteListener pListener,
213: IPentahoUrlFactory urlFactory, List messages,
214: String actionSequenceXML) {
215:
216: this .persisted = isPersisted;
217: setlistener(pListener);
218: setSession(session);
219:
220: setMessages(messages);
221:
222: auditStart(solutionName, sequencePath, sequenceName, instanceId);
223:
224: if (!checkParameters(solutionName, sequencePath, sequenceName,
225: processId)) {
226: return null;
227: }
228:
229: session.setProcessId(processId);
230: session.setActionName(sequenceName);
231:
232: // create the runtime context object for this operation
233: if (debug)
234: debug(Messages
235: .getString("SolutionEngine.DEBUG_GETTING_RUNTIME_CONTEXT")); //$NON-NLS-1$
236: IRuntimeElement runtimeData;
237: IRuntimeRepository runtimeRepository = PentahoSystem
238: .getRuntimeRepository(session);
239: if (instanceId == null) {
240: // we need to create runtime data for this execution
241: try {
242: runtimeRepository.setLoggingLevel(loggingLevel);
243: runtimeData = runtimeRepository.newRuntimeElement(
244: session.getId(),
245: HttpSessionParameterProvider.SCOPE_SESSION,
246: !persisted);
247: createRuntime(runtimeData, solutionName, outputHandler,
248: processId, urlFactory);
249: runtime.setLoggingLevel(loggingLevel);
250: instanceId = runtime.getInstanceId();
251: genLogIdFromInfo(instanceId, LOG_NAME, sequenceName);
252: // audit the creation of this against the session
253: AuditHelper.audit(session.getId(), session.getName(),
254: sequenceName, getObjectName(), processId,
255: MessageTypes.INSTANCE_START, instanceId,
256: "", null, this ); //$NON-NLS-1$
257: } catch (Throwable t) {
258: error(
259: Messages
260: .getErrorString(
261: "SolutionEngine.ERROR_0008_INVALID_INSTANCE", instanceId), t); //$NON-NLS-1$
262: status = IRuntimeContext.RUNTIME_STATUS_SETUP_FAIL;
263: return null;
264: }
265: } else {
266: try {
267: runtimeRepository.setLoggingLevel(loggingLevel);
268: runtimeData = runtimeRepository.loadElementById(
269: instanceId, null);
270: createRuntime(runtimeData, solutionName, outputHandler,
271: processId, urlFactory);
272: runtime.setLoggingLevel(loggingLevel);
273: instanceId = runtime.getInstanceId();
274: genLogIdFromInfo(instanceId, LOG_NAME, sequenceName);
275: } catch (Throwable t) {
276: error(
277: Messages
278: .getErrorString(
279: "SolutionEngine.ERROR_0008_INVALID_INSTANCE", instanceId), t); //$NON-NLS-1$
280: status = IRuntimeContext.RUNTIME_STATUS_SETUP_FAIL;
281: return null;
282: }
283: }
284: if (outputHandler != null) {
285: outputHandler.setRuntimeContext(runtime);
286: }
287: return executeInternal(solutionName, sequencePath,
288: sequenceName, processId, async, instanceEnds,
289: parameterProviderMap, actionSequenceXML);
290: }
291:
292: public IRuntimeContext execute(IRuntimeContext pRuntime,
293: String solutionName, String sequencePath,
294: String sequenceName, String processId, boolean async,
295: boolean instanceEnds, Map parameterProviderMap,
296: IOutputHandler outputHandler) {
297: applyParameterMappers(parameterProviderMap);
298:
299: runtime = pRuntime;
300: runtime.setOutputHandler(outputHandler);
301: auditStart(solutionName, sequencePath, sequenceName, runtime
302: .getInstanceId());
303:
304: if (!checkParameters(solutionName, sequencePath, sequenceName,
305: processId)) {
306: status = IRuntimeContext.RUNTIME_STATUS_FAILURE;
307: return null;
308: }
309: return executeInternal(solutionName, sequencePath,
310: sequenceName, processId, async, instanceEnds,
311: parameterProviderMap);
312:
313: }
314:
315: protected IRuntimeContext executeInternal(String solutionName,
316: String sequencePath, String sequenceName, String processId,
317: boolean async, boolean instanceEnds,
318: Map parameterProviderMap) {
319: return executeInternal(solutionName, sequencePath,
320: sequenceName, processId, async, instanceEnds,
321: parameterProviderMap, null);
322: }
323:
324: protected IRuntimeContext executeInternal(String solutionName,
325: String sequencePath, String sequenceName, String processId,
326: boolean async, boolean instanceEnds,
327: Map parameterProviderMap, String actionSequenceXML) {
328:
329: long start = System.currentTimeMillis();
330:
331: parameterProviders.putAll(parameterProviderMap);
332: parameterProviders.put(PentahoSystem.SCOPE_GLOBAL,
333: PentahoSystem.getGlobalParameters());
334:
335: // load the solution action document
336: if (debug)
337: debug(Messages
338: .getString("SolutionEngine.DEBUG_LOADING_ACTION_DEFINITION")); //$NON-NLS-1$
339:
340: IActionSequence actionSequence = null;
341: if (actionSequenceXML != null) {
342: actionSequence = createActionSequence(actionSequenceXML,
343: solutionName);
344: } else {
345: actionSequence = createActionSequence(sequenceName,
346: sequencePath, solutionName);
347: }
348: if (actionSequence == null) {
349: error(Messages
350: .getErrorString("SolutionEngine.ERROR_0005_ACTION_SEQUENCE_NOT_FOUND")); //$NON-NLS-1$
351: status = IRuntimeContext.RUNTIME_STATUS_FAILURE;
352: long end = System.currentTimeMillis();
353: AuditHelper
354: .audit(
355: session.getId(),
356: session.getName(),
357: sequenceName,
358: getObjectName(),
359: processId,
360: MessageTypes.INSTANCE_FAILED,
361: runtime.getInstanceId(),
362: Messages
363: .getErrorString("SolutionEngine.ERROR_0005_ACTION_SEQUENCE_NOT_FOUND"), new BigDecimal(((double) (end - start) / 1000)), this ); //$NON-NLS-1$
364: return runtime;
365: }
366:
367: runtime.setActionSequence(actionSequence);
368: if (parameterXsl != null) {
369: runtime.setParameterXsl(parameterXsl);
370: }
371:
372: if (forcePrompt) {
373: runtime.setPromptStatus(IRuntimeContext.PROMPT_WAITING);
374: } else {
375: runtime.setPromptStatus(IRuntimeContext.PROMPT_NO);
376: }
377:
378: if (runtime.validateSequence(sequenceName) != IRuntimeContext.RUNTIME_CONTEXT_VALIDATE_OK) {
379: error(Messages
380: .getErrorString("SolutionEngine.ERROR_0006_ACTION_SEQUENCE_INVALID")); //$NON-NLS-1$
381: status = IRuntimeContext.RUNTIME_CONTEXT_VALIDATE_FAIL;
382: long end = System.currentTimeMillis();
383: AuditHelper
384: .audit(
385: session.getId(),
386: session.getName(),
387: sequenceName,
388: getObjectName(),
389: processId,
390: MessageTypes.INSTANCE_FAILED,
391: runtime.getInstanceId(),
392: Messages
393: .getErrorString("SolutionEngine.ERROR_0006_ACTION_SEQUENCE_INVALID"), new BigDecimal(((double) (end - start) / 1000)), this ); //$NON-NLS-1$
394: return runtime;
395: }
396:
397: try {
398: if (runtime.executeSequence(listener, async) != IRuntimeContext.RUNTIME_STATUS_SUCCESS) {
399: error(Messages
400: .getErrorString("SolutionEngine.ERROR_0007_ACTION_EXECUTION_FAILED")); //$NON-NLS-1$
401: status = IRuntimeContext.RUNTIME_STATUS_FAILURE;
402: long end = System.currentTimeMillis();
403: AuditHelper
404: .audit(
405: session.getId(),
406: session.getName(),
407: sequenceName,
408: getObjectName(),
409: processId,
410: MessageTypes.INSTANCE_FAILED,
411: runtime.getInstanceId(),
412: Messages
413: .getErrorString("SolutionEngine.ERROR_0007_ACTION_EXECUTION_FAILED"), new BigDecimal(((double) (end - start) / 1000)), this ); //$NON-NLS-1$
414: return runtime;
415: }
416: } finally {
417: if (persisted) {
418: // HibernateUtil.commitTransaction();
419: // HibernateUtil.closeSession();
420: }
421: }
422: // return the runtime context for the action
423: if (instanceEnds) {
424: long end = System.currentTimeMillis();
425: AuditHelper
426: .audit(
427: session.getId(),
428: session.getName(),
429: sequenceName,
430: getObjectName(),
431: processId,
432: MessageTypes.INSTANCE_END,
433: runtime.getInstanceId(),
434: "", new BigDecimal(((double) (end - start) / 1000)), this ); //$NON-NLS-1$
435: }
436: status = runtime.getStatus();
437: return runtime;
438:
439: }
440:
441: protected void createRuntime(IRuntimeElement runtimeData,
442: String solutionName, IOutputHandler outputHandler,
443: String processId, IPentahoUrlFactory urlFactory) {
444: runtime = new RuntimeContext(runtimeData.getInstanceId(), this ,
445: solutionName, runtimeData, session, outputHandler,
446: processId, urlFactory, parameterProviders,
447: getMessages());
448: }
449:
450: private IActionSequence createActionSequence(String actionName,
451: String actionPath, String solutionName) {
452: ISolutionRepository solutionRepository = PentahoSystem
453: .getSolutionRepository(session);
454: solutionRepository.setMessages(getMessages());
455: return solutionRepository.getActionSequence(solutionName,
456: actionPath, actionName, loggingLevel,
457: ISolutionRepository.ACTION_EXECUTE);
458: }
459:
460: private IActionSequence createActionSequence(String actionDef,
461: String actionName) {
462: Document actionSequenceDocument = XmlHelper
463: .getDocFromString(actionDef);
464: if (actionSequenceDocument == null) {
465: return null;
466: }
467:
468: IActionSequence actionSequence = SequenceDefinition
469: .ActionSequenceFactory(
470: actionSequenceDocument,
471: actionName,
472: "", ISolutionEngine.RUNTIME_SOLUTION_NAME, this , PentahoSystem.getApplicationContext(), loggingLevel); //$NON-NLS-1$
473: return (actionSequence);
474:
475: }
476:
477: public void setForcePrompt(boolean forcePrompt) {
478: this .forcePrompt = forcePrompt;
479: }
480:
481: public void setParameterXsl(String xsl) {
482: this .parameterXsl = xsl;
483: }
484:
485: /**
486: * FIXME: This is in dire need of fixing
487: * @param parameterProviderMap
488: */
489: protected void applyParameterMappers(Map parameterProviderMap) {
490: IParameterProvider request = (IParameterProvider) parameterProviderMap
491: .get(HttpRequestParameterProvider.SCOPE_REQUEST);
492: if (request != null) {
493: IParameterProvider chartRequest = new FlashChartRequestMapper(
494: request);
495: parameterProviderMap
496: .remove(HttpRequestParameterProvider.SCOPE_REQUEST);
497: parameterProviderMap.put(
498: HttpRequestParameterProvider.SCOPE_REQUEST,
499: chartRequest);
500: }
501: }
502:
503: }
|