org.eclipse.swordfish.plugins.cxf.support.NMROutputStream.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.swordfish.plugins.cxf.support.NMROutputStream.java

Source

/*******************************************************************************
 * Copyright (c) 2008, 2009 SOPERA GmbH.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     SOPERA GmbH - initial API and implementation
 *******************************************************************************/
package org.eclipse.swordfish.plugins.cxf.support;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.InterfaceInfo;
import org.apache.cxf.ws.addressing.EndpointReferenceType;
import org.apache.cxf.wsdl.EndpointReferenceUtils;
import org.apache.servicemix.cxf.transport.nmr.NMRConduit;
import org.apache.servicemix.cxf.transport.nmr.NMRMessageHelper;
import org.apache.servicemix.jbi.jaxp.SourceTransformer;
import org.apache.servicemix.nmr.api.Channel;
import org.apache.servicemix.nmr.api.Endpoint;
import org.apache.servicemix.nmr.api.NMR;
import org.apache.servicemix.nmr.api.Pattern;
import org.apache.servicemix.nmr.api.Reference;
import org.apache.servicemix.nmr.api.Status;
import org.eclipse.swordfish.internal.core.util.xml.XmlUtil;

public class NMROutputStream extends CachedOutputStream {
    private final static String SOAP_MESSAGE_PREFIX = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body>";

    private final static String SOAP_MESSAGE_SUFFIX = "</soap:Body></soap:Envelope>";
    private static final Log LOG = LogFactory.getLog(NMROutputStream.class);

    private Message message;
    private boolean isOneWay;
    private Channel channel;
    private NMRConduit conduit;
    private EndpointReferenceType target;

    public NMROutputStream(Message m, NMR nmr, EndpointReferenceType target, NMRConduit conduit) {
        message = m;
        this.channel = nmr.createChannel();
        this.conduit = conduit;
        this.target = target;

    }

    @Override
    protected void doFlush() throws IOException {

    }

    @Override
    protected void doClose() throws IOException {
        isOneWay = message.getExchange().isOneWay();
        sendOutputMessage();
        if (target != null) {
            target.getClass();
        }
        channel.close();
    }

    protected void sendOutputMessage() throws IOException {
        try {
            for (Iterator it = message.values().iterator(); it.hasNext();) {
                LOG.info(it.next());
            }
            org.apache.servicemix.nmr.api.Exchange xchng = createNMRMessageExchange();
            Source source = message.getContent(Source.class);
            String contentSrc = new SourceTransformer().toString(source);
            LOG.info("Sending message\n" + contentSrc);

            if (!isOneWay) {
                channel.sendSync(xchng);
                Source content = (xchng.getFault(false) != null) ? xchng.getFault().getBody(Source.class)
                        : xchng.getOut().getBody(Source.class);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Content of exchange:\n" + xchng.display(true));
                }

                if (xchng.getError() != null) {
                    throw new IOException("Remote service error");
                }

                content = wrapEnvelope(content);
                Message inMessage = new MessageImpl();
                message.getExchange().setInMessage(inMessage);
                InputStream ins = NMRMessageHelper.convertMessageToInputStream(content);
                if (ins == null) {
                    throw new IOException("Unable to retrieve message");
                }
                inMessage.setContent(InputStream.class, ins);
                conduit.getMessageObserver().onMessage(inMessage);
                xchng.setStatus(Status.Done);
                channel.send(xchng);

            } else {
                channel.sendSync(xchng);
            }
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            throw new IOException(e.toString());
        }
    }

    private org.apache.servicemix.nmr.api.Exchange createNMRMessageExchange() throws IOException {
        Member member = (Member) message.get(Method.class.getName());
        Class<?> clz = member.getDeclaringClass();
        Exchange exchange = message.getExchange();
        BindingOperationInfo bop = exchange.get(BindingOperationInfo.class);

        LOG.info("Invoking service" + clz);

        WebService ws = clz.getAnnotation(WebService.class);
        InterfaceInfo info = message.getExchange().get(InterfaceInfo.class);
        QName interfaceName = null;
        if (ws != null && ws.name() != null && !"".equals(ws.name())) {
            interfaceName = new QName(ws.targetNamespace(), ws.name());
        } else {
            if (info != null) {
                interfaceName = info.getName();
            }
        }
        QName serviceName;
        if (target != null) {
            serviceName = EndpointReferenceUtils.getServiceName(target, conduit.getBus());
        } else {
            serviceName = message.getExchange().get(org.apache.cxf.service.Service.class).getName();
        }

        LOG.info("Create messageExchange" + serviceName);
        org.apache.servicemix.nmr.api.Exchange xchng;
        if (isOneWay) {
            xchng = channel.createExchange(Pattern.InOnly);
        } else if (bop.getOutput() == null) {
            xchng = channel.createExchange(Pattern.RobustInOnly);
        } else {
            xchng = channel.createExchange(Pattern.InOut);
        }
        org.apache.servicemix.nmr.api.Message inMsg = xchng.getIn();
        LOG.info("Exchange endpoint " + serviceName);
        LOG.info("setup message contents on " + inMsg);
        inMsg.setBody(getMessageContent(message));
        /*
              for (Iterator it = message.keySet().iterator(); it.hasNext();) {
                 String key = (String) it.next();
                 inMsg.setHeader(key, message.get(key));
              }
        */
        LOG.info("service for exchange " + serviceName);

        Map<String, Object> refProps = new HashMap<String, Object>();
        if (interfaceName != null) {
            refProps.put(Endpoint.INTERFACE_NAME, interfaceName.toString());
        }
        refProps.put(Endpoint.SERVICE_NAME, serviceName.toString());
        Reference ref = channel.getNMR().getEndpointRegistry().lookup(refProps);
        xchng.setTarget(ref);
        xchng.setOperation(bop.getName());
        return xchng;
    }

    private Source getMessageContent(Message message2) throws IOException {
        return unwrapEnvelope(new StreamSource(this.getInputStream()));

    }

    private Source wrapEnvelope(Source source) {
        String message = XmlUtil.toStringFromSource(source);
        if (!message.contains(":Body")) {
            int index = message.indexOf(">") + 1;
            String xmlPrefix = message.substring(0, index);
            String cutMessage = message.substring(index);
            message = xmlPrefix + SOAP_MESSAGE_PREFIX + cutMessage + SOAP_MESSAGE_SUFFIX;

        }
        try {
            return new SourceTransformer()
                    .toDOMSource(new org.eclipse.swordfish.internal.core.util.xml.StringSource(message));
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    private Source unwrapEnvelope(Source source) {
        String message = XmlUtil.toStringFromSource(source);
        if (message.contains(":Body")) {
            int index = message.indexOf(">") + 1;
            String xmlPrefix = message.substring(0, index);
            String cutMessage = message.substring(index);
            int startIndex = cutMessage.indexOf(":Body");
            startIndex = cutMessage.indexOf(">", startIndex) + 1;
            int endIndex = cutMessage.indexOf(":Body", startIndex);// end   of body
            endIndex = cutMessage.substring(0, endIndex).lastIndexOf("</");
            String bodyMessage = cutMessage.substring(startIndex, endIndex);
            bodyMessage = xmlPrefix + bodyMessage;
            message = bodyMessage;
        }
        try {
            return new SourceTransformer()
                    .toDOMSource(new org.eclipse.swordfish.internal.core.util.xml.StringSource(message));
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    @Override
    protected void onWrite() throws IOException {

    }

}