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 17, 2005
014: * @author James Dixon
015: *
016: */
017:
018: package org.pentaho.core.util;
019:
020: import java.io.IOException;
021: import java.io.OutputStream;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Set;
025:
026: // import org.apache.soap.Envelope;
027: // import org.apache.soap.Fault;
028: import org.pentaho.core.repository.IContentItem;
029: import org.pentaho.core.runtime.IRuntimeContext;
030: import org.pentaho.core.solution.IOutputHandler;
031: import org.pentaho.core.solution.SimpleOutputHandler;
032: import org.pentaho.messages.Messages;
033: import org.pentaho.messages.util.LocaleHelper;
034:
035: public class SoapUtil {
036:
037: public static void generateSoapResponse(IRuntimeContext context,
038: OutputStream outputStream,
039: SimpleOutputHandler outputHandler,
040: OutputStream contentStream, List messages) {
041:
042: StringBuffer messageBuffer = new StringBuffer();
043: generateSoapResponse(context, outputHandler, contentStream,
044: messageBuffer, messages);
045: try {
046: outputStream.write(messageBuffer.toString().getBytes(
047: LocaleHelper.getSystemEncoding()));
048: } catch (IOException e) {
049: // TODO log thid
050: }
051: }
052:
053: public static String getSoapHeader() {
054: return "<SOAP-ENV:Envelope " + //$NON-NLS-1$
055: "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
056: + //$NON-NLS-1$
057: "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n "
058: + //$NON-NLS-1$
059: "<SOAP-ENV:Body>\n"; //$NON-NLS-1$
060:
061: }
062:
063: public static String getSoapFooter() {
064: return "</SOAP-ENV:Body>\n</SOAP-ENV:Envelope>"; //$NON-NLS-1$
065:
066: }
067:
068: public static void generateSoapError(StringBuffer messageBuffer,
069: List messages) {
070:
071: String message = UIUtil.getFirstError(messages);
072:
073: messageBuffer.append("<SOAP-ENV:Fault>\n"); //$NON-NLS-1$
074:
075: if (message == null) {
076: message = Messages
077: .getErrorString("SoapUtil.ERROR_0001_UNKNOWN_ERROR"); //$NON-NLS-1$
078: }
079:
080: // Envelope envelope = new Envelope();
081: // Fault fault = new Fault( );
082: // TODO: Generate the following message using the envelope and fault objects
083:
084: // TODO determine if this is a reciever or a sender problem by examining
085: // the error code
086: boolean senderFault = (message
087: .indexOf("SolutionEngine.ERROR_0002") != -1) || //$NON-NLS-1$ // solution not specifed
088: (message.indexOf("SolutionEngine.ERROR_0003") != -1) || //$NON-NLS-1$ // Path not specifeid
089: (message.indexOf("SolutionEngine.ERROR_0004") != -1) || //$NON-NLS-1$ // Action not specified
090: (message.indexOf("SolutionEngine.ERROR_0005") != -1); //$NON-NLS-1$ // Action not found
091: // send the error code
092: // TODO parse out the error code
093: messageBuffer
094: .append("<SOAP-ENV:faultcode>\n <SOAP-ENV:Subcode>\n<SOAP-ENV:Value><![CDATA[" + message + "]]></SOAP-ENV:Value>\n </SOAP-ENV:Subcode>\n </SOAP-ENV:faultcode>"); //$NON-NLS-1$ //$NON-NLS-2$
095:
096: if (senderFault) {
097: messageBuffer
098: .append("<SOAP-ENV:faultactor>SOAP-ENV:Client</SOAP-ENV:faultactor>\n"); //$NON-NLS-1$
099: } else {
100: messageBuffer
101: .append("<SOAP-ENV:faultactor>SOAP-ENV:Server</SOAP-ENV:faultactor>\n"); //$NON-NLS-1$
102: }
103:
104: // send the error reason
105: messageBuffer
106: .append("<SOAP-ENV:faultstring><SOAP-ENV:Text xml:lang=\"" + LocaleHelper.getDefaultLocale().toString() + "\"><![CDATA[" + message + "]]></SOAP-ENV:Text>\n </SOAP-ENV:faultstring>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
107:
108: // send the details
109: messageBuffer.append("<SOAP-ENV:Detail>"); //$NON-NLS-1$
110:
111: Iterator messageIterator = messages.iterator();
112: while (messageIterator.hasNext()) {
113: messageBuffer
114: .append("<message name=\"trace\"><![CDATA[" + (String) messageIterator.next() + "]]></message>\n"); //$NON-NLS-1$ //$NON-NLS-2$
115: }
116: messageBuffer.append("</SOAP-ENV:Detail>"); //$NON-NLS-1$
117:
118: messageBuffer.append("</SOAP-ENV:Fault>\n"); //$NON-NLS-1$
119:
120: }
121:
122: public static String openSoapResponse() {
123: return "<ExecuteActivityResponse xmlns:m=\"http://pentaho.org\">\n"; //$NON-NLS-1$
124: }
125:
126: public static String closeSoapResponse() {
127: return "</ExecuteActivityResponse>\n"; //$NON-NLS-1$
128: }
129:
130: public static void generateSoapResponse(IRuntimeContext context,
131: SimpleOutputHandler outputHandler,
132: OutputStream contentStream, StringBuffer messageBuffer,
133: List messages) {
134: // we need to generate a soap package for this
135: // the outputs of the action need to be put into the package
136:
137: /*
138: * This is the format of the response message package
139: *
140: *
141: * <SOAP-ENV:Envelope
142: * xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
143: * SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
144: * <SOAP-ENV:Body> <m:ExecuteActivityResponse
145: * xmlns:m="http://pentaho.org"> <result>...</result> <result>...</result>
146: * <result>...</result> </m:ExecuteActivityResponse> </SOAP-ENV:Body>
147: * </SOAP-ENV:Envelope>
148: *
149: */
150:
151: if (context == null
152: || context.getStatus() != IRuntimeContext.RUNTIME_STATUS_SUCCESS) {
153: generateSoapError(messageBuffer, messages);
154: } else {
155:
156: messageBuffer.append(openSoapResponse());
157:
158: IContentItem contentItem = outputHandler
159: .getFeedbackContentItem();
160:
161: // hmm do we need this to be ordered?
162: Set outputNames = context.getOutputNames();
163:
164: Iterator outputNameIterator = outputNames.iterator();
165: while (outputNameIterator.hasNext()) {
166: String outputName = (String) outputNameIterator.next();
167: contentItem = outputHandler.getOutputContentItem(
168: IOutputHandler.RESPONSE,
169: IOutputHandler.CONTENT, context
170: .getSolutionName(), context
171: .getInstanceId(), "text/xml"); //$NON-NLS-1$
172: if (outputNames.size() == 1 && contentItem != null) {
173: String mimeType = contentItem.getMimeType();
174: if (mimeType != null
175: && mimeType.startsWith("text/")) { //$NON-NLS-1$
176: if (mimeType.equals("text/xml")) { //$NON-NLS-1$
177: // this should be ok to embed directly, any CDATA
178: // sections in the XML will be ok
179: messageBuffer
180: .append("<").append(outputName).append(">") //$NON-NLS-1$//$NON-NLS-2$
181: .append(contentStream.toString())
182: .append("</").append(outputName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$
183: } else if (mimeType.startsWith("text/")) { //$NON-NLS-1$
184: // put this is a CDATA section and hope it does not
185: // contain the string ']]>'
186: messageBuffer
187: .append("<").append(outputName).append("><![CDATA[") //$NON-NLS-1$ //$NON-NLS-2$
188: .append(contentStream.toString())
189: .append("]]></").append(outputName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$
190: }
191: } else {
192: Object value = context.getOutputParameter(
193: outputName).getValue();
194: if (value == null) {
195: value = ""; //$NON-NLS-1$
196: }
197: messageBuffer.append(SoapHelper.toSOAP(
198: outputName, value));
199: }
200: } else {
201: Object value = context.getOutputParameter(
202: outputName).getValue();
203: if (value == null) {
204: value = ""; //$NON-NLS-1$
205: }
206: messageBuffer.append(SoapHelper.toSOAP(outputName,
207: value));
208: }
209: }
210: messageBuffer.append(closeSoapResponse());
211: }
212: }
213:
214: }
|