org.pentaho.platform.engine.services.SoapHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.platform.engine.services.SoapHelper.java

Source

/*
 * 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 2005 - 2008 Pentaho Corporation.  All rights reserved. 
 * 
 * @created Jul 17, 2005 
 * @author James Dixon
 * 
 */

package org.pentaho.platform.engine.services;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.commons.connection.IPentahoResultSet;
import org.pentaho.platform.api.engine.IOutputHandler;
import org.pentaho.platform.api.engine.IRuntimeContext;
import org.pentaho.platform.api.repository.IContentItem;
import org.pentaho.platform.engine.core.output.SimpleOutputHandler;
import org.pentaho.platform.engine.services.messages.Messages;
import org.pentaho.platform.util.messages.LocaleHelper;

public class SoapHelper {
    private static final Log logger = LogFactory.getLog(SoapHelper.class);

    public static void generateSoapResponse(final IRuntimeContext context, final OutputStream outputStream,
            final SimpleOutputHandler outputHandler, final OutputStream contentStream, final List messages) {

        StringBuffer messageBuffer = new StringBuffer();
        SoapHelper.generateSoapResponse(context, outputHandler, contentStream, messageBuffer, messages);
        try {
            outputStream.write(messageBuffer.toString().getBytes(LocaleHelper.getSystemEncoding()));
        } catch (IOException e) {
            SoapHelper.logger.error(null, e);
        }
    }

    public static String getSoapHeader() {
        return "<SOAP-ENV:Envelope " + //$NON-NLS-1$
                "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " + //$NON-NLS-1$
                "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n " + //$NON-NLS-1$
                "<SOAP-ENV:Body>\n"; //$NON-NLS-1$

    }

    public static String getSoapFooter() {
        return "</SOAP-ENV:Body>\n</SOAP-ENV:Envelope>"; //$NON-NLS-1$

    }

    public static void generateSoapError(final StringBuffer messageBuffer, final List messages) {

        // TODO mlowery begin hack: copied in getFirstError code from MessageFormatter
        // to avoid needing an IPentahoSession
        String message = null;
        String errorStart = PentahoMessenger.getUserString("ERROR"); //$NON-NLS-1$
        int pos = errorStart.indexOf('{');
        if (pos != -1) {
            errorStart = errorStart.substring(0, pos);
        }
        Iterator msgIterator = messages.iterator();
        while (msgIterator.hasNext()) {
            String msg = (String) msgIterator.next();
            if (msg.indexOf(errorStart) == 0) {
                message = msg;
            }
        }
        // TODO mlowery end hack

        messageBuffer.append("<SOAP-ENV:Fault>\n"); //$NON-NLS-1$

        if (message == null) {
            message = Messages.getErrorString("SoapHelper.ERROR_0001_UNKNOWN_ERROR"); //$NON-NLS-1$
        }

        // Envelope envelope = new Envelope();
        // Fault fault = new Fault( );
        // TODO: Generate the following message using the envelope and fault objects

        // TODO determine if this is a reciever or a sender problem by examining
        // the error code
        boolean senderFault = (message.indexOf("SolutionEngine.ERROR_0002") != -1) || //$NON-NLS-1$ // solution not specifed
                (message.indexOf("SolutionEngine.ERROR_0003") != -1) || //$NON-NLS-1$ // Path not specifeid
                (message.indexOf("SolutionEngine.ERROR_0004") != -1) || //$NON-NLS-1$ // Action not specified
                (message.indexOf("SolutionEngine.ERROR_0005") != -1); //$NON-NLS-1$ // Action not found
        // send the error code
        // TODO parse out the error code
        messageBuffer.append("<SOAP-ENV:faultcode>\n <SOAP-ENV:Subcode>\n<SOAP-ENV:Value><![CDATA[" + message //$NON-NLS-1$
                + "]]></SOAP-ENV:Value>\n </SOAP-ENV:Subcode>\n </SOAP-ENV:faultcode>"); //$NON-NLS-1$

        if (senderFault) {
            messageBuffer.append("<SOAP-ENV:faultactor>SOAP-ENV:Client</SOAP-ENV:faultactor>\n"); //$NON-NLS-1$
        } else {
            messageBuffer.append("<SOAP-ENV:faultactor>SOAP-ENV:Server</SOAP-ENV:faultactor>\n"); //$NON-NLS-1$
        }

        // send the error reason
        messageBuffer.append(
                "<SOAP-ENV:faultstring><SOAP-ENV:Text xml:lang=\"" + LocaleHelper.getDefaultLocale().toString() //$NON-NLS-1$
                        + "\"><![CDATA[" + message + "]]></SOAP-ENV:Text>\n </SOAP-ENV:faultstring>\n"); //$NON-NLS-1$ //$NON-NLS-2$

        // send the details
        messageBuffer.append("<SOAP-ENV:Detail>"); //$NON-NLS-1$

        Iterator messageIterator = messages.iterator();
        while (messageIterator.hasNext()) {
            messageBuffer.append(
                    "<message name=\"trace\"><![CDATA[" + (String) messageIterator.next() + "]]></message>\n"); //$NON-NLS-1$ //$NON-NLS-2$
        }
        messageBuffer.append("</SOAP-ENV:Detail>"); //$NON-NLS-1$

        messageBuffer.append("</SOAP-ENV:Fault>\n"); //$NON-NLS-1$

    }

    public static String openSoapResponse() {
        return "<ExecuteActivityResponse xmlns:m=\"http://pentaho.org\">\n"; //$NON-NLS-1$
    }

    public static String closeSoapResponse() {
        return "</ExecuteActivityResponse>\n"; //$NON-NLS-1$
    }

    public static void generateSoapResponse(final IRuntimeContext context, final SimpleOutputHandler outputHandler,
            final OutputStream contentStream, final StringBuffer messageBuffer, final List messages) {
        // we need to generate a soap package for this
        // the outputs of the action need to be put into the package

        /*
         * This is the format of the response message package
         * 
         * 
         * <SOAP-ENV:Envelope
         * xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
         * SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         * <SOAP-ENV:Body> <m:ExecuteActivityResponse
         * xmlns:m="http://pentaho.org"> <result>...</result> <result>...</result>
         * <result>...</result> </m:ExecuteActivityResponse> </SOAP-ENV:Body>
         * </SOAP-ENV:Envelope>
         * 
         */

        if ((context == null) || (context.getStatus() != IRuntimeContext.RUNTIME_STATUS_SUCCESS)) {
            SoapHelper.generateSoapError(messageBuffer, messages);
        } else {

            messageBuffer.append(SoapHelper.openSoapResponse());

            IContentItem contentItem = outputHandler.getFeedbackContentItem();

            // hmm do we need this to be ordered?
            Set outputNames = context.getOutputNames();

            Iterator outputNameIterator = outputNames.iterator();
            while (outputNameIterator.hasNext()) {
                String outputName = (String) outputNameIterator.next();
                contentItem = outputHandler.getOutputContentItem(IOutputHandler.RESPONSE, IOutputHandler.CONTENT,
                        context.getSolutionName(), context.getInstanceId(), "text/xml"); //$NON-NLS-1$
                if ((outputNames.size() == 1) && (contentItem != null)) {
                    String mimeType = contentItem.getMimeType();
                    if ((mimeType != null) && mimeType.startsWith("text/")) { //$NON-NLS-1$
                        if (mimeType.equals("text/xml")) { //$NON-NLS-1$
                            // this should be ok to embed directly, any CDATA
                            // sections in the XML will be ok
                            messageBuffer.append("<").append(outputName).append(">") //$NON-NLS-1$//$NON-NLS-2$
                                    .append(contentStream.toString()).append("</").append(outputName).append(">"); //$NON-NLS-1$ //$NON-NLS-2$
                        } else if (mimeType.startsWith("text/")) { //$NON-NLS-1$
                            // put this is a CDATA section and hope it does not
                            // contain the string ']]>'
                            messageBuffer.append("<").append(outputName).append("><![CDATA[") //$NON-NLS-1$ //$NON-NLS-2$
                                    .append(contentStream.toString()).append("]]></").append(outputName) //$NON-NLS-1$
                                    .append(">"); //$NON-NLS-1$
                        }
                    } else {
                        Object value = context.getOutputParameter(outputName).getValue();
                        if (value == null) {
                            value = ""; //$NON-NLS-1$
                        }
                        messageBuffer.append(SoapHelper.toSOAP(outputName, value));
                    }
                } else {
                    Object value = context.getOutputParameter(outputName).getValue();
                    if (value == null) {
                        value = ""; //$NON-NLS-1$
                    }
                    messageBuffer.append(SoapHelper.toSOAP(outputName, value));
                }
            }
            messageBuffer.append(SoapHelper.closeSoapResponse());
        }
    }

    public static String toSOAP(final String name, final Object item) {

        if (item instanceof String) {
            return SoapHelper.toSOAP(name, (String) item);
        } else if (item instanceof List) {
            return SoapHelper.toSOAP(name, (List) item);
        } else if (item instanceof IPentahoResultSet) {
            return SoapHelper.toSOAP(name, (IPentahoResultSet) item);
        } else if (item instanceof IContentItem) {
            return SoapHelper.toSOAP(name, ((IContentItem) item).getId());
        }
        return null;
    }

    @SuppressWarnings("deprecation")
    private static String toSOAP(final String name, final IPentahoResultSet resultSet) {
        StringBuffer messageBuffer = new StringBuffer();
        messageBuffer.append("<" + name + ">\n"); //$NON-NLS-1$ //$NON-NLS-2$
        Object[][] columnHeaders = resultSet.getMetaData().getColumnHeaders();
        Object[][] rowHeaders = resultSet.getMetaData().getRowHeaders();
        boolean hasColumnHeaders = columnHeaders != null;
        boolean hasRowHeaders = rowHeaders != null;

        if (hasColumnHeaders) {
            for (Object[] element : columnHeaders) {
                messageBuffer.append("<COLUMN-HDR-ROW>\n"); //$NON-NLS-1$
                for (int column = 0; column < element.length; column++) {
                    messageBuffer.append("<COLUMN-HDR-ITEM><![CDATA[").append(element[column]) //$NON-NLS-1$
                            .append("]]></COLUMN-HDR-ITEM>\n"); //$NON-NLS-1$
                }
                messageBuffer.append("</COLUMN-HDR-ROW>\n"); //$NON-NLS-1$
            }
        }

        if (hasRowHeaders) {
            for (Object[] element : rowHeaders) {
                messageBuffer.append("<ROW-HDR-ROW>\n"); //$NON-NLS-1$
                for (int column = 0; column < element.length; column++) {
                    messageBuffer.append("<ROW-HDR-ITEM><![CDATA[").append(element[column]) //$NON-NLS-1$
                            .append("]]></ROW-HDR-ITEM>\n"); //$NON-NLS-1$
                }
                messageBuffer.append("</ROW-HDR-ROW>\n"); //$NON-NLS-1$
            }
        }

        Object[] dataRow = resultSet.next();
        while (dataRow != null) {
            messageBuffer.append("<DATA-ROW>\n"); //$NON-NLS-1$
            for (Object element : dataRow) {
                messageBuffer.append("<DATA-ITEM><![CDATA[").append(element).append("]]></DATA-ITEM>\n"); //$NON-NLS-1$//$NON-NLS-2$
            }
            messageBuffer.append("</DATA-ROW>\n"); //$NON-NLS-1$
            dataRow = resultSet.next();
        }
        messageBuffer.append("</" + name + ">\n"); //$NON-NLS-1$ //$NON-NLS-2$

        return messageBuffer.toString();
    }

    public static String toSOAP(final String name, final String value) {
        // example code only, probably bogus
        return "<" + name + "><![CDATA[" + value + "]]></" + name + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    }

    public static String toSOAP(final String name, final long value) {
        // example code only, probably bogus
        return "<" + name + "><![CDATA[" + value + "]]></" + name + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    }

    public static String toSOAP(final String name, final Date value) {
        // example code only, probably bogus
        return "<" + name + "><![CDATA[" + value + "]]></" + name + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    }

    public static String toSOAP(final String name, final List list) {

        return "<" + name + "><![CDATA[" + list.toString() + "]]></" + name + ">"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
    }

}