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 Apr 19, 2005
014: * @author James Dixon
015: *
016: */
017:
018: package org.pentaho.plugin.shark;
019:
020: import java.io.IOException;
021: import java.io.OutputStream;
022: import java.net.MalformedURLException;
023: import java.util.HashMap;
024: import java.util.Iterator;
025: import org.dom4j.Document;
026: import org.dom4j.Node;
027: import org.enhydra.shark.api.SharkTransaction;
028: import org.enhydra.shark.api.internal.toolagent.AppParameter;
029: import org.enhydra.shark.api.internal.toolagent.ApplicationBusy;
030: import org.enhydra.shark.api.internal.toolagent.ApplicationNotDefined;
031: import org.enhydra.shark.api.internal.toolagent.ApplicationNotStarted;
032: import org.enhydra.shark.api.internal.toolagent.ToolAgentGeneralException;
033: import org.enhydra.shark.toolagent.AbstractToolAgent;
034: import org.enhydra.shark.xpdl.elements.ExtendedAttribute;
035: import org.enhydra.shark.xpdl.elements.ExtendedAttributes;
036: import org.pentaho.core.runtime.IRuntimeContext;
037: import org.pentaho.core.services.HttpWebServiceRequestHandler;
038: import org.pentaho.core.session.StandaloneSession;
039: import org.pentaho.core.solution.SimpleOutputHandler;
040: import org.pentaho.core.solution.SimpleParameterProvider;
041: import org.pentaho.core.util.SoapUtil;
042: import org.pentaho.core.util.XmlHelper;
043: import org.pentaho.messages.Messages;
044: import org.pentaho.util.HttpUtil;
045: import org.pentaho.util.logging.Logger;
046:
047: public class SharkToolAgent extends AbstractToolAgent {
048:
049: public void invokeApplication(SharkTransaction t, long sharkHandle,
050: String applicationName, String processInstanceId,
051: String workitemId, AppParameter[] appParameters,
052: Integer applicationMode) throws ApplicationNotStarted,
053: ApplicationNotDefined, ApplicationBusy,
054: ToolAgentGeneralException {
055:
056: super .invokeApplication(t, sharkHandle, applicationName,
057: procInstId, assId, appParameters, appMode);
058: String instanceId = null;
059: String solutionId = null;
060: String activityPath = null;
061: String actionMode = "direct"; // default action mode is by direct invokation, the XPDL activity can override and specify HTML or JMS(todo) //$NON-NLS-1$
062:
063: // Get the URL of the Pentaho server
064: String activityUrl = null;
065: try {
066: ExtendedAttributes exAttrs = readParamsFromExtAttributes(appParameters[0].the_value
067: .toString());
068: // Get the action mode
069: ExtendedAttribute attribute = exAttrs
070: .getFirstExtendedAttributeForName("Pentaho_Activity_Mode"); //$NON-NLS-1$
071: if (attribute != null) {
072: activityUrl = attribute.get("Value").toValue(); //$NON-NLS-1$
073: }
074: // Get the URL for HTTP action mode
075: attribute = exAttrs
076: .getFirstExtendedAttributeForName("Pentaho_Activity_URL"); //$NON-NLS-1$
077: if (attribute != null) {
078: activityUrl = attribute.get("Value").toValue(); //$NON-NLS-1$
079: }
080: // Get the settings for JMS action mode
081: attribute = exAttrs
082: .getFirstExtendedAttributeForName("Pentaho_Activity_Queue"); //$NON-NLS-1$
083: if (attribute != null) {
084: // TODO
085: }
086: // TODO support JCA
087: } catch (Exception e) {
088: e.printStackTrace();
089: }
090:
091: // Get the required parameters and any other "IN" or "INOUT" parameters
092: HashMap parameterValues = new HashMap();
093: for (int i = 1; i < appParameters.length; i++) {
094: if ("solution".equals(appParameters[i].the_formal_name)) { //$NON-NLS-1$
095: solutionId = (String) appParameters[i].the_value;
096: } else if ("action".equals(appParameters[i].the_formal_name)) { //$NON-NLS-1$
097: activityPath = (String) appParameters[i].the_value;
098: } else if ("instance-id".equals(appParameters[i].the_formal_name)) { //$NON-NLS-1$
099: instanceId = (String) appParameters[i].the_value;
100: if (instanceId.trim().length() == 0) {
101: instanceId = null;
102: }
103: } else if ("mode".equals(appParameters[i].the_formal_name)) { //$NON-NLS-1$
104: actionMode = (String) appParameters[i].the_value;
105: } else if (!appParameters[i].the_mode.equals("OUT")) { //$NON-NLS-1$
106: parameterValues.put(appParameters[i].the_formal_name,
107: appParameters[i].the_value);
108: }
109: }
110:
111: // Validate that we have the minimum required parameters
112: if (activityUrl == null) {
113: throw new ApplicationNotDefined(
114: Messages
115: .getErrorString("SharkToolAgent.ERROR_0001_ATTRIBUTE_NOT_SET")); //$NON-NLS-1$
116: }
117:
118: if (solutionId == null) {
119: throw new ApplicationNotDefined(
120: Messages
121: .getErrorString("SharkToolAgent.ERROR_0002_SOLUTION_ID_NOT_SET")); //$NON-NLS-1$
122: }
123:
124: if (activityPath == null) {
125: throw new ApplicationNotDefined(
126: Messages
127: .getErrorString("SharkToolAgent.ERROR_0003_ACTION_NAME_NOT_SET")); //$NON-NLS-1$
128: }
129:
130: if (activityUrl == null) {
131: throw new ApplicationNotDefined(
132: Messages
133: .getErrorString("SharkToolAgent.ERROR_0004_ACTIVITY_UTL_NOT_SET")); //$NON-NLS-1$
134: }
135:
136: status = AbstractToolAgent.APP_STATUS_ACTIVE;
137: StringBuffer resultBuffer = new StringBuffer();
138: try {
139: int pos = activityPath.lastIndexOf('/');
140: String actionPath = null;
141: String actionName = null;
142: if (pos == -1) {
143: actionPath = ""; //$NON-NLS-1$
144: actionName = activityPath;
145: } else {
146: actionPath = activityPath.substring(0, pos);
147: actionName = activityPath.substring(pos + 1);
148: }
149:
150: status = AbstractToolAgent.APP_STATUS_TERMINATED;
151: if ("URL".equalsIgnoreCase(actionMode)) { //$NON-NLS-1$
152: status = httpAction(instanceId, solutionId, actionPath,
153: actionName, parameterValues, activityUrl,
154: resultBuffer);
155: } else if ("direct".equalsIgnoreCase(actionMode)) { //$NON-NLS-1$
156: status = directAction(workitemId, instanceId,
157: solutionId, actionPath, actionName,
158: parameterValues, resultBuffer);
159: } else if ("JMS".equalsIgnoreCase(actionMode)) { //$NON-NLS-1$
160: // TODO
161: } else if ("JCA".equalsIgnoreCase(actionMode)) { //$NON-NLS-1$
162: // TODO
163: }
164:
165: if (status == AbstractToolAgent.APP_STATUS_TERMINATED) {
166: // action aborted
167: }
168: } catch (Throwable throwable) {
169: cus
170: .error(appName
171: + Messages
172: .getErrorString("SharkToolAgent.ERROR_0005_TERMINATED_BADLY") + throwable); //$NON-NLS-1$
173: status = APP_STATUS_INVALID;
174: throw new ToolAgentGeneralException(throwable);
175: }
176: String result = resultBuffer.toString();
177:
178: if (result.equals("")) { //$NON-NLS-1$
179: Logger
180: .error(
181: "SharkToolAgent", Messages.getErrorString("SharkToolAgent.ERROR_0006_INVALID_RESPONSE_FROM_ACTION")); //$NON-NLS-1$ //$NON-NLS-2$
182: status = APP_STATUS_INVALID;
183: return;
184: }
185: try {
186: Document soapDoc = XmlHelper.getDocFromString(result);
187:
188: if (soapDoc == null) {
189: // we did not get an understandable reply from the server
190: // TODO log this
191: status = APP_STATUS_TERMINATED;
192: return;
193: }
194: // TODO check SOAP doc for any error messages
195: // set any returning values into the parameters
196: for (int i = 0; i < appParameters.length; i++) {
197: if (!appParameters[i].the_mode.equals("IN")) { //$NON-NLS-1$
198: Node resultNode = soapDoc
199: .selectSingleNode("//ExecuteActivityResponse/" + appParameters[i].the_formal_name); //$NON-NLS-1$
200: if (resultNode != null) {
201: String value = resultNode.getText();
202: // TODO convert this to another object type if necessary
203: if (value != null) {
204: appParameters[i].the_value = value;
205: }
206: }
207: }
208: }
209: status = APP_STATUS_FINISHED;
210: } catch (Throwable ex) {
211: cus
212: .error(appName
213: + Messages
214: .getErrorString("SharkToolAgent.ERROR_0005_TERMINATED_BADLY") + ex); //$NON-NLS-1$
215: status = APP_STATUS_INVALID;
216: throw new ToolAgentGeneralException(ex);
217: }
218:
219: }
220:
221: public long httpAction(String instanceId, String solutionId,
222: String actionPath, String actionName,
223: HashMap parameterValues, String activityUrl,
224: StringBuffer resultBuffer) {
225: StringBuffer urlStr = new StringBuffer();
226:
227: urlStr
228: .append(activityUrl)
229: .append("?solution=").append(solutionId).append("&path=").append(actionPath).append("&action=").append(actionName); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
230:
231: if (instanceId != null) {
232: urlStr.append("&instance-id=" + instanceId); //$NON-NLS-1$
233: }
234:
235: // set any returning values into the parameters
236: Iterator parameterValueIterator = parameterValues.keySet()
237: .iterator();
238: while (parameterValueIterator.hasNext()) {
239: String name = (String) parameterValueIterator.next();
240: String value = (String) parameterValues.get(name);
241: urlStr.append("&" + name + "=" + value); //$NON-NLS-1$ //$NON-NLS-2$
242: }
243:
244: try {
245: HttpUtil.getURLContent(urlStr.toString(), resultBuffer);
246: return AbstractToolAgent.APP_STATUS_RUNNING;
247: } catch (MalformedURLException e) {
248: // TODO log this
249: } catch (IOException e) {
250: // TODO log this
251: }
252: return AbstractToolAgent.APP_STATUS_TERMINATED;
253: }
254:
255: public long directAction(String workitemId, String instanceId,
256: String solutionName, String actionPath, String actionName,
257: HashMap parameterValues, StringBuffer resultBuffer) {
258: // PentahoSystem.systemEntryPoint();
259: try {
260: StandaloneSession userSession = new StandaloneSession(
261: "Shark Workflow Tool Agent", workitemId); //$NON-NLS-1$
262:
263: String processId = this .getClass().getName();
264:
265: SimpleOutputHandler outputHandler = new SimpleOutputHandler(
266: (OutputStream) null, false);
267: SimpleParameterProvider parameterProvider = new SimpleParameterProvider(
268: parameterValues);
269:
270: HttpWebServiceRequestHandler requestHandler = new HttpWebServiceRequestHandler(
271: userSession, instanceId, outputHandler,
272: parameterProvider, null);
273:
274: requestHandler.setProcessId(processId);
275: requestHandler.setAction(actionPath, actionName);
276: requestHandler.setSolutionName(solutionName);
277:
278: IRuntimeContext runtime = null;
279: try {
280: runtime = requestHandler.handleActionRequest(0, 0);
281: resultBuffer.append(SoapUtil.getSoapHeader());
282: SoapUtil.generateSoapResponse(runtime, outputHandler,
283: null, resultBuffer, requestHandler
284: .getMessages());
285: resultBuffer.append(SoapUtil.getSoapFooter());
286: } finally {
287: if (runtime != null) {
288: runtime.dispose();
289: }
290: }
291: return AbstractToolAgent.APP_STATUS_TERMINATED;
292: } finally {
293: // PentahoSystem.systemExitPoint();
294: }
295: }
296:
297: public String getInfo(SharkTransaction t) {
298: return Messages.getString("SharkToolAgent.TOOL_AGENT_INFO"); //$NON-NLS-1$
299: }
300:
301: }
|