Package org.objectweb.celtix.bindings

Source Code of org.objectweb.celtix.bindings.AbstractServerBinding

package org.objectweb.celtix.bindings;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.wsdl.Port;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;

import org.objectweb.celtix.Bus;
import org.objectweb.celtix.BusException;
import org.objectweb.celtix.common.injection.ResourceInjector;
import org.objectweb.celtix.common.logging.LogUtils;
import org.objectweb.celtix.context.InputStreamMessageContext;
import org.objectweb.celtix.context.ObjectMessageContext;
import org.objectweb.celtix.context.OutputStreamMessageContext;
import org.objectweb.celtix.resource.DefaultResourceManager;
import org.objectweb.celtix.resource.ResourceManager;
import org.objectweb.celtix.resource.ResourceResolver;
import org.objectweb.celtix.transports.ServerTransport;
import org.objectweb.celtix.transports.ServerTransportCallback;
import org.objectweb.celtix.transports.TransportFactory;
import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
import org.objectweb.celtix.wsdl.EndpointReferenceUtils;

import static org.objectweb.celtix.bindings.JAXWSConstants.BUS_PROPERTY;
import static org.objectweb.celtix.bindings.JAXWSConstants.SERVER_BINDING_PROPERTY;
import static org.objectweb.celtix.bindings.JAXWSConstants.SERVER_TRANSPORT_PROPERTY;

public abstract class AbstractServerBinding extends AbstractBindingBase implements ServerBinding {

    private static final Logger LOG = LogUtils.getL7dLogger(AbstractServerBinding.class);

    protected ServerBindingEndpointCallback sbeCallback;

    public AbstractServerBinding(Bus b, EndpointReferenceType ref,
                                 ServerBindingEndpointCallback sbcb) {
        super(b, ref);
        sbeCallback = sbcb;
    }

    // --- ServerBinding interface ---

    public void activate() throws WSDLException, IOException {
        transport = createTransport(reference);

        ServerTransportCallback tc = new ServerTransportCallback() {

            public void dispatch(InputStreamMessageContext ctx, ServerTransport t) {
                AbstractServerBinding.this.dispatch(ctx, t);
            }

            public Executor getExecutor() {
                return sbeCallback.getExecutor();
            }
        };
        serverTransport().activate(tc);
       
        injectSystemHandlers();
    }

    public void deactivate() throws IOException {
        serverTransport().deactivate();
    }

    /**
     * Make an initial partial response to an incoming request. The partial
     * response may only contain 'header' information, and not a 'body'.
     *
     * @param context object message context
     * @param callback callback for data binding
     */
    public void partialResponse(OutputStreamMessageContext outputContext,
                                DataBindingCallback callback) throws IOException {
        ObjectMessageContext objectMessageContext = createObjectContext();
        objectMessageContext.putAll(outputContext);
        BindingContextUtils.storeDataBindingCallback(objectMessageContext, callback);

        if (callback != null) {
            Request request = new Request(this, transport, objectMessageContext);
            request.setOneway(true);

            try {
                request.process(outputContext);
                terminateOutputContext(outputContext);
            } finally {
                request.complete();
            }
        } else {
            transport.finalPrepareOutputStreamContext(outputContext);
            terminateOutputContext(outputContext);
        }
    }
   
    // --- ServerBinding interface ---

    // --- Methods to be implemented by concrete server bindings ---

    public abstract AbstractBindingImpl getBindingImpl();
   
    public abstract QName getOperationName(MessageContext ctx);
   

    // --- Methods to be implemented by concrete server bindings ---

    protected void finalPrepareOutputStreamContext(ServerTransport t, MessageContext bindingContext,
                                                   OutputStreamMessageContext ostreamContext)
        throws IOException {
        t.finalPrepareOutputStreamContext(ostreamContext);
    }

    protected boolean isFault(ObjectMessageContext objCtx, MessageContext bindingCtx) {
        if (getBindingImpl().hasFault(bindingCtx)) {
            return true;
        }
        return objCtx.getException() != null;
    }
   
    protected void dispatch(InputStreamMessageContext istreamCtx, final ServerTransport t) {
        LOG.info("Dispatched to binding on thread : " + Thread.currentThread());
        // storeSource(istreamCtx, t);
        BindingContextUtils.storeServerBindingEndpointCallback(istreamCtx, sbeCallback);
       
        final ServerRequest inMsg = new ServerRequest(this, istreamCtx);        
       
        Exception inboundException = null;
       
        try {
            inMsg.processInbound();  
            if (!inMsg.doDispatch()) {
                LOG.log(Level.INFO,
                        "handlers have halted inbound message processing or specifically prevent dispatch");
            }
        } catch (Exception ex) {
            inboundException = ex;
            LOG.log(Level.INFO, "inbound message processing resulted in exception: ", ex);
        }
       
        // if an error occured during processing of the inbound request
        // or if the processing direction was halted by one of the handlers
        // or if this is a one-way operation: send response (but traverse
        // system handlers only if operation is one-way).
       
        boolean doDispatch = null == inboundException && inMsg.doDispatch();
       
        if (!doDispatch || inMsg.isOneway()) {
    
            inMsg.processOutbound(t, inboundException);
           
            if (!doDispatch) {
                return;
            }
        }
  
        // everything was OK: dispatch to implementor
       
        Runnable invoker = new Runnable() {
            public void run() {
                LOG.log(Level.INFO, "Before invoking on implementor");
                assert null != inMsg.getObjectCtx();
                inMsg.doInvocation();
                LOG.log(Level.INFO, "After invoking on implementor");
                if (!inMsg.isOneway()) {
                    // process response
                    inMsg.processOutbound(t, null);
                }
            }
        };

        // the dispatch must be async if the request is decoupled or oneway and the
        // transport is unable to proceed to the next request until this thread
        // is freed up
        if ((BindingContextUtils.retrieveDecoupledResponse(inMsg.getObjectCtx())
             || inMsg.isOneway())
            && BindingContextUtils.retrieveAsyncOnewayDispatch(istreamCtx)) {
            // invoke implementor asynchronously
            executeAsync(invoker);
        } else {
            // invoke implementor directly
            invoker.run();
        }
    }
   
    protected ServerTransport createTransport(EndpointReferenceType ref) throws WSDLException, IOException {
       
        try {
            Port port = EndpointReferenceUtils.getPort(bus.getWSDLManager(), ref);
            List<?> exts = port.getExtensibilityElements();
            if (exts.size() > 0) {               
                ExtensibilityElement el = (ExtensibilityElement)exts.get(0);
                TransportFactory tf =
                    bus.getTransportFactoryManager().
                        getTransportFactory(el.getElementType().getNamespaceURI());
                return tf.createServerTransport(ref);
            }
        } catch (BusException ex) {
            LOG.severe("TRANSPORT_FACTORY_RETRIEVAL_FAILURE_MSG");
        }
        return null;
    }
   
    protected ServerTransport serverTransport() {
        return (ServerTransport)transport;
    }

    /*
    protected void storeSource(MessageContext context, ServerTransport st) {
        BindingContextUtils.storeBinding(context, this);
        BindingContextUtils.storeTransport(context, st);
        BindingContextUtils.storeBus(context, bus);
    }
    */
   
    private void injectSystemHandlers() {
        ResourceManager rm = new DefaultResourceManager();
        rm.addResourceResolver(new ResourceResolver() {
            @SuppressWarnings("unchecked")
            public <T> T resolve(String resourceName, Class<T> resourceType) {
                if (BUS_PROPERTY.equals(resourceName)) {
                    return  (T)AbstractServerBinding.this.getBus();
                } else if (SERVER_BINDING_PROPERTY.equals(resourceName)) {
                    return  (T)AbstractServerBinding.this;
                } else if (SERVER_TRANSPORT_PROPERTY.equals(resourceName)) {
                    return (T)transport;
                }
                return null;
            }
           
            public InputStream getAsStream(String name) {
                return null;
            }           
        });
        ResourceInjector injector = new ResourceInjector(rm);
       
        getBindingImpl().injectSystemHandlers(injector);
    }
   
    private void terminateOutputContext(OutputStreamMessageContext outputContext)
        throws IOException {
        outputContext.getOutputStream().flush();
        outputContext.getOutputStream().close();
   

    private void executeAsync(Runnable command) {
        Executor executor =
            sbeCallback.getExecutor() != null
            ? sbeCallback.getExecutor()
            : getBus().getWorkQueueManager().getAutomaticWorkQueue();
        try {
            executor.execute(command);
        } catch (RejectedExecutionException ree) {
            LOG.log(Level.WARNING, "ONEWAY_FALLBACK_TO_DIRECT_MSG", ree);
            command.run();
        }
    }   
}
TOP

Related Classes of org.objectweb.celtix.bindings.AbstractServerBinding

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.