Package org.objectweb.celtix.bus.ws.addressing

Source Code of org.objectweb.celtix.bus.ws.addressing.ContextUtils

package org.objectweb.celtix.bus.ws.addressing;



import java.lang.reflect.Method;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import javax.xml.ws.WebFault;
import javax.xml.ws.handler.MessageContext;
import static javax.xml.ws.handler.MessageContext.MESSAGE_OUTBOUND_PROPERTY;

import org.objectweb.celtix.bindings.BindingContextUtils;
import org.objectweb.celtix.bindings.DataBindingCallback;
import org.objectweb.celtix.bindings.ServerBinding;
import org.objectweb.celtix.bus.jaxws.JAXBDataBindingCallback;
import org.objectweb.celtix.common.logging.LogUtils;
import org.objectweb.celtix.context.ObjectMessageContext;
import org.objectweb.celtix.context.OutputStreamMessageContext;
import org.objectweb.celtix.transports.ServerTransport;
import org.objectweb.celtix.ws.addressing.AddressingProperties;
import org.objectweb.celtix.ws.addressing.AttributedURIType;
import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
import org.objectweb.celtix.ws.addressing.ObjectFactory;
import org.objectweb.celtix.ws.addressing.RelatesToType;

import static org.objectweb.celtix.context.ObjectMessageContext.CORRELATION_IN;
import static org.objectweb.celtix.context.ObjectMessageContext.CORRELATION_OUT;
import static org.objectweb.celtix.context.ObjectMessageContext.REQUESTOR_ROLE_PROPERTY;
import static org.objectweb.celtix.context.OutputStreamMessageContext.ONEWAY_MESSAGE_TF;
import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES;
import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES_INBOUND;
import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES_OUTBOUND;
import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND;
import static org.objectweb.celtix.ws.addressing.JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND;


/**
* Holder for utility methods relating to contexts.
*/
public final class ContextUtils {

    public static final ObjectFactory WSA_OBJECT_FACTORY = new ObjectFactory();

    private static final String WS_ADDRESSING_PACKAGE =
        EndpointReferenceType.class.getPackage().getName();
    private static final Logger LOG = LogUtils.getL7dLogger(ContextUtils.class);
   
    private static final String TO_PROPERTY =
        "org.objectweb.celtix.ws.addressing.to";
    private static final String REPLYTO_PROPERTY =
        "org.objectweb.celtix.ws.addressing.replyto";
    private static final String USING_PROPERTY =
        "org.objectweb.celtix.ws.addressing.using";
   
    /**
     * Used to fabricate a Uniform Resource Name from a UUID string
     */
    private static final String URN_UUID = "urn:uuid:";


    private static JAXBContext jaxbContext;
    
    /**
     * Used by MAPAggregator to cache bad MAP fault name
     */
    private static final String MAP_FAULT_NAME_PROPERTY =
        "org.objectweb.celtix.ws.addressing.map.fault.name";

    /**
     * Used by MAPAggregator to cache bad MAP fault reason
     */
    private static final String MAP_FAULT_REASON_PROPERTY =
        "org.objectweb.celtix.ws.addressing.map.fault.reason";
   /**
    * Prevents instantiation.
    */
    private ContextUtils() {
    }

   /**
    * Determine if context indicates message is outbound.
    *
    * @param context the current MessageContext
    * @return true iff the message direction is outbound
    */
    public static boolean isOutbound(MessageContext context) {
        Boolean outbound = (Boolean)context.get(MESSAGE_OUTBOUND_PROPERTY);
        return outbound != null && outbound.booleanValue();
    }

   /**
    * Determine if context indicates current messaging role is that of
    * requestor.
    *
    * @param context the current MessageContext
    * @return true iff the current messaging role is that of requestor
    */
    public static boolean isRequestor(MessageContext context) {
        Boolean requestor = (Boolean)context.get(REQUESTOR_ROLE_PROPERTY);
        return requestor != null && requestor.booleanValue();
    }

    /**
     * Determine if context indicates current invocation is oneway.
     *
     * @param context the current MessageContext
     * @return true iff the current invocation is oneway
     */
    public static boolean isOneway(MessageContext context) {
        Boolean oneway = (Boolean)context.get(ONEWAY_MESSAGE_TF);
        return oneway != null && oneway.booleanValue();
    }

    /**
     * Get appropriate context property name for message addressing properties.
     *
     * @param isProviderContext true if the binding provider request context
     * available to the client application as opposed to the message context
     * visible to handlers
     * @param isRequestor true iff the current messaging role is that of
     * requestor
     * @param isOutbound true iff the message is outbound
     * @return the property name to use when caching the MAPs in the context
     */
    public static String getMAPProperty(boolean isRequestor,
                                        boolean isProviderContext,
                                        boolean isOutbound) {
        return isRequestor
                ? isProviderContext
                 ? CLIENT_ADDRESSING_PROPERTIES
                 : isOutbound
                   ? CLIENT_ADDRESSING_PROPERTIES_OUTBOUND
                   : CLIENT_ADDRESSING_PROPERTIES_INBOUND
               : isOutbound
                 ? SERVER_ADDRESSING_PROPERTIES_OUTBOUND
                 : SERVER_ADDRESSING_PROPERTIES_INBOUND;
    }
   
    /**
     * Get appropriate context property name for correlation ID.
     *
     * @param isOutbound true iff the message is outbound
     * @return the property name to use when caching the
     * correlation ID in the context
     */
    public static String getCorrelationIDProperty(boolean isOutbound) {
        return isOutbound ? CORRELATION_OUT : CORRELATION_IN;
    }


    /**
     * Store MAPs in the context.
     *
     * @param context the message context
     * @param isOutbound true iff the message is outbound
     */
    public static void storeMAPs(AddressingProperties maps,
                                 MessageContext context,
                                 boolean isOutbound) {
        storeMAPs(maps, context, isOutbound, isRequestor(context), true, false);
    }

    /**
     * Store MAPs in the context.
     *
     * @param maps the MAPs to store
     * @param context the message context
     * @param isOutbound true iff the message is outbound
     * @param isRequestor true iff the current messaging role is that of
     * requestor
     * @param handler true if HANDLER scope, APPLICATION scope otherwise
     */
    public static void storeMAPs(AddressingProperties maps,
                                 MessageContext context,
                                 boolean isOutbound,
                                 boolean isRequestor,
                                 boolean handler) {
        storeMAPs(maps, context, isOutbound, isRequestor, handler, false);
    }
   
    /**
     * Store MAPs in the context.
     *
     * @param maps the MAPs to store
     * @param context the message context
     * @param isOutbound true iff the message is outbound
     * @param isRequestor true iff the current messaging role is that of
     * requestor
     * @param handler true if HANDLER scope, APPLICATION scope otherwise
     * @param isProviderContext true if the binding provider request context
     */
    public static void storeMAPs(AddressingProperties maps,
                                 MessageContext context,
                                 boolean isOutbound,
                                 boolean isRequestor,
                                 boolean handler,
                                 boolean isProviderContext) {
        if (maps != null) {
            String mapProperty = getMAPProperty(isRequestor, isProviderContext, isOutbound);
            LOG.log(Level.INFO,
                    "associating MAPs with context property {0}",
                    mapProperty);
            context.put(mapProperty, maps);
            context.setScope(mapProperty,
                             handler
                             ? MessageContext.Scope.HANDLER
                             : MessageContext.Scope.APPLICATION);
        }
    }


    /**
     * @param context the message context
     * @param isProviderContext true if the binding provider request context
     * available to the client application as opposed to the message context
     * visible to handlers
     * @param isOutbound true iff the message is outbound
     * @return the current addressing properties
     */
    public static AddressingPropertiesImpl retrieveMAPs(
                                                   MessageContext context,
                                                   boolean isProviderContext,
                                                   boolean isOutbound) {
        boolean isRequestor = ContextUtils.isRequestor(context);
        String mapProperty =
            ContextUtils.getMAPProperty(isProviderContext,
                                        isRequestor,
                                        isOutbound);
        LOG.log(Level.INFO,
                "retrieving MAPs from context property {0}",
                mapProperty);
        AddressingPropertiesImpl maps =
            (AddressingPropertiesImpl)context.get(mapProperty);
        if (maps != null) {
            LOG.log(Level.INFO, "current MAPs {0}", maps);
        } else if (!isProviderContext) {
            LOG.warning("MAPS_RETRIEVAL_FAILURE_MSG");
        }
        return maps;
    }

    /**
     * Helper method to get an attributed URI.
     *
     * @param uri the URI
     * @return an AttributedURIType encapsulating the URI
     */
    public static AttributedURIType getAttributedURI(String uri) {
        AttributedURIType attributedURI =
            WSA_OBJECT_FACTORY.createAttributedURIType();
        attributedURI.setValue(uri);
        return attributedURI;
    }

    /**
     * Helper method to get a RealtesTo instance.
     *
     * @param uri the related URI
     * @return a RelatesToType encapsulating the URI
     */
    public static RelatesToType getRelatesTo(String uri) {
        RelatesToType relatesTo =
            WSA_OBJECT_FACTORY.createRelatesToType();
        relatesTo.setValue(uri);
        return relatesTo;
    }

    /**
     * Helper method to determine if an EPR address is generic (either null,
     * none or anonymous).
     *
     * @param ref the EPR under test
     * @return true iff the address is generic
     */
    public static boolean isGenericAddress(EndpointReferenceType ref) {
        return ref == null
               || ref.getAddress() == null
               || Names.WSA_ANONYMOUS_ADDRESS.equals(ref.getAddress().getValue())
               || Names.WSA_NONE_ADDRESS.equals(ref.getAddress().getValue());
    }

    /**
     * Helper method to determine if an MAPs Action is empty (a null action
     * is considered empty, whereas a zero length action suppresses
     * the propogation of the Action property).
     *
     * @param ref the MAPs Action under test
     * @return true iff the Action is empty
     */
    public static boolean hasEmptyAction(AddressingProperties maps) {
        boolean empty = maps.getAction() == null;
        if (maps.getAction() != null
            && maps.getAction().getValue().length() == 0) {
            maps.setAction(null);
            empty = false;
        }
        return empty;
    }

    /**
     * Rebase server transport on replyTo
     *
     * @param inMAPs the incoming MAPs
     * @param context the message context
     */
    public static void rebaseTransport(AddressingProperties inMAPs,
                                       MessageContext context,
                                       ServerBinding serverBinding,
                                       ServerTransport serverTransport) {
        // ensure there is a MAPs instance available for the outbound
        // partial response that contains appropriate To and ReplyTo
        // properties (i.e. anonymous & none respectively)
        AddressingPropertiesImpl maps = new AddressingPropertiesImpl();
        maps.setTo(ContextUtils.getAttributedURI(Names.WSA_ANONYMOUS_ADDRESS));
        maps.setReplyTo(WSA_OBJECT_FACTORY.createEndpointReferenceType());
        maps.getReplyTo().setAddress(getAttributedURI(Names.WSA_NONE_ADDRESS));
        maps.setAction(getAttributedURI(""));
        maps.exposeAs(inMAPs.getNamespaceURI());
        storeMAPs(maps, context, true, true, true, true);

        if (serverTransport != null && serverBinding != null) {
            try {
                OutputStreamMessageContext outputContext =
                    serverTransport.rebase(context, inMAPs.getReplyTo());
                if (outputContext != null) {
                    serverBinding.partialResponse(outputContext,
                                                  getDataBindingCallback());
                }
                BindingContextUtils.storeDecoupledResponse(context, true);
            } catch (Exception e) {
                LOG.log(Level.WARNING, "SERVER_TRANSPORT_REBASE_FAILURE_MSG", e);
            }
        }
    }

    /**
     * Store UsingAddressing override flag in the context
     *
     * @param override true if UsingAddressing should be overridden
     * @param context the message context
     */  
    public static void storeUsingAddressing(boolean override, MessageContext context) {
        context.put(USING_PROPERTY, Boolean.valueOf(override));
        context.setScope(USING_PROPERTY, MessageContext.Scope.APPLICATION);
    }
   
    /**
     * Retrieve UsingAddressing override flag from the context
     *
     * @param override true if UsingAddressing should be overridden
     * @param context the message context
     */  
    public static boolean retrieveUsingAddressing(MessageContext context) {
        Boolean override = (Boolean)context.get(USING_PROPERTY);
        return override != null && override.booleanValue();
    }

    /**
     * Store To EPR in the context
     *
     * @param to the To EPR
     * @param context the message context
     */  
    public static void storeTo(EndpointReferenceType to,
                               MessageContext context) {
        context.put(TO_PROPERTY, to);
        context.setScope(TO_PROPERTY, MessageContext.Scope.APPLICATION);
    }
   
    /**
     * Retrieve To EPR from the context.
     *
     * @param context the message context
     * @returned the retrieved EPR
     */
    public static EndpointReferenceType retrieveTo(MessageContext context) {
        /*
        // required?
        ClientTransport transport = BindingContextUtils.retrieveClientTransport(context);
        EndpointReferenceType to = null;
        if (transport != null) {
            to = transport.getTargetEndpoint();
        } else {
            to = (EndpointReferenceType)context.get(TO_PROPERTY);
        }
        return to;
        */
        return (EndpointReferenceType)context.get(TO_PROPERTY);
    }
   
    /**
     * Store ReplyTo EPR in the context
     *
     * @param replyTo the ReplyTo EPR
     * @param context the message context
     */  
    public static void storeReplyTo(EndpointReferenceType replyTo,
                                       MessageContext context) {
        context.put(REPLYTO_PROPERTY, replyTo);
        context.setScope(REPLYTO_PROPERTY, MessageContext.Scope.APPLICATION);
    }

    /**
     * Retrieve ReplyTo EPR from the context.
     *
     * @param context the message context
     * @returned the retrieved EPR
     */
    public static EndpointReferenceType retrieveReplyTo(MessageContext context) {
        /*
        // required?
        ClientTransport transport = BindingContextUtils.retrieveClientTransport(context);
        EndpointReferenceType replyTo = null;
        if (transport != null) {
            try {
                replyTo = transport.getDecoupledEndpoint();
            } catch (IOException ioe) {
                // ignore
            }
        } else {
            replyTo = (EndpointReferenceType)context.get(REPLYTO_PROPERTY);
        }
        return replyTo;
        */
        return (EndpointReferenceType)context.get(REPLYTO_PROPERTY);
    }

    /**
     * Store bad MAP fault name in the context.
     *
     * @param faultName the fault name to store
     * @param context the message context
     */
    public static void storeMAPFaultName(String faultName,
                                         MessageContext context) {
        context.put(MAP_FAULT_NAME_PROPERTY, faultName);
        context.setScope(MAP_FAULT_NAME_PROPERTY,
                         MessageContext.Scope.HANDLER);
    }

    /**
     * Retrieve MAP fault name from the context.
     *
     * @param context the message context
     * @returned the retrieved fault name
     */
    public static String retrieveMAPFaultName(MessageContext context) {
        return (String)context.get(MAP_FAULT_NAME_PROPERTY);
    }

    /**
     * Store MAP fault reason in the context.
     *
     * @param reason the fault reason to store
     * @param context the message context
     */
    public static void storeMAPFaultReason(String reason,
                                           MessageContext context) {
        context.put(MAP_FAULT_REASON_PROPERTY, reason);
        context.setScope(MAP_FAULT_REASON_PROPERTY,
                         MessageContext.Scope.HANDLER);
    }

    /**
     * Retrieve MAP fault reason from the context.
     *
     * @param context the message context
     * @returned the retrieved fault reason
     */
    public static String retrieveMAPFaultReason(MessageContext context) {
        return (String)context.get(MAP_FAULT_REASON_PROPERTY);
    }

    /**
     * Store correlation ID in the context
     *
     * @param id the correlation ID
     * @param isOutbound true if message is outbound
     * @param context the message context
     */  
    public static void storeCorrelationID(RelatesToType id,
                                          boolean isOutbound,
                                          MessageContext context) {
        storeCorrelationID(id.getValue(), isOutbound, context);
    }
   
    /**
     * Store correlation ID in the context
     *
     * @param id the correlation ID
     * @param isOutbound true if message is outbound
     * @param context the message context
     */  
    public static void storeCorrelationID(AttributedURIType id,
                                          boolean isOutbound,
                                          MessageContext context) {
        storeCorrelationID(id.getValue(), isOutbound, context);
    }
   
    /**
     * Store correlation ID in the context
     *
     * @param id the correlation ID
     * @param isOutbound true if message is outbound
     * @param context the message context
     */  
    protected static void storeCorrelationID(String id,
                                           boolean isOutbound,
                                           MessageContext context) {
        context.put(getCorrelationIDProperty(isOutbound), id);
        context.setScope(getCorrelationIDProperty(isOutbound),
                         MessageContext.Scope.APPLICATION);
    }
   
    /**
     * Retrieve correlation ID from the context.
     *
     * @param context the message context
     * @param isOutbound true if message is outbound
     * @returned the retrieved correlation ID
     */
    public static String retrieveCorrelationID(MessageContext context,
                                               boolean isOutbound) {
        return (String)context.get(getCorrelationIDProperty(isOutbound));
    }
   
    /**
     * Retrieve a JAXBContext for marshalling and unmarshalling JAXB generated
     * types.
     *
     * @return a JAXBContext
     */
    public static JAXBContext getJAXBContext() throws JAXBException {
        synchronized (ContextUtils.class) {
            if (jaxbContext == null) {
                jaxbContext = JAXBContext.newInstance(WS_ADDRESSING_PACKAGE);
            }
        }
        return jaxbContext;
    }

    /**
     * Set the encapsulated JAXBContext (used by unit tests).
     *
     * @param ctx JAXBContext
     */
    public static void setJAXBContext(JAXBContext ctx) throws JAXBException {
        synchronized (ContextUtils.class) {
            jaxbContext = ctx;
        }
    }
   
   
    /**
     * @return a generated UUID
     */
    public static String generateUUID() {
        return URN_UUID + UUID.randomUUID();
    }
   
    /**
     * Construct the Action URI.
     *
     * @param context the message context
     * @return the Action URI
     */
    public static AttributedURIType getAction(MessageContext context) {
        String action = null;
        // REVISIT: add support for @{Fault}Action annotation (generated
        // from the wsaw:Action WSDL element)
        LOG.fine("Determining action");
        Throwable fault =
            (Throwable)context.get(ObjectMessageContext.METHOD_FAULT);
        Method method = (Method)context.get(ObjectMessageContext.METHOD_OBJ);
        LOG.fine("method: " + method + ", fault: " + fault);
        if (method != null) {
            if (fault != null) {
                WebFault webFault = fault.getClass().getAnnotation(WebFault.class);
                action = getAction(webFault.targetNamespace(),
                                   method,
                                   webFault.name(),
                                   true);
            } else {
                if (ContextUtils.isRequestor(context)) {
                    RequestWrapper requestWrapper =
                        method.getAnnotation(RequestWrapper.class);
                    if (requestWrapper != null) {
                        action = getAction(requestWrapper.targetNamespace(),
                                           method,
                                           requestWrapper.localName(),
                                           false);
                    } else {
                        //TODO: What if the WSDL is RPC-Literal encoded.
                        // We need to get action out of available annotations?
                        //
                       
                        WebService wsAnnotation = method.getDeclaringClass().getAnnotation(WebService.class);
                        WebMethod wmAnnotation = method.getAnnotation(WebMethod.class);
                       
                        action = getAction(wsAnnotation.targetNamespace(),
                                           method,
                                           wmAnnotation.operationName(),
                                           false);
                    }
                       
                } else {
                    ResponseWrapper responseWrapper =
                        method.getAnnotation(ResponseWrapper.class);
                    if (responseWrapper != null) {
                        action = getAction(responseWrapper.targetNamespace(),
                                           method,
                                           responseWrapper.localName(),
                                          false);
                    } else {
                       //RPC-Literal case.
                        WebService wsAnnotation = method.getDeclaringClass().getAnnotation(WebService.class);
                        WebMethod wmAnnotation = method.getAnnotation(WebMethod.class);
                       
                        action = getAction(wsAnnotation.targetNamespace(),
                                           method,
                                           wmAnnotation.operationName(),
                                           false);
                    }
                }
            }
        }
        return action != null ? getAttributedURI(action) : null;
    }
       

    /**
     * Construct the Action string.
     *
     * @param targetNamespace the target namespace
     * @param method the method
     * @param localName the local name
     * @param isFault true if a fault
     * @return action string
     */
    private static String getAction(String targetNamespace,
                                    Method method,
                                    String localName,
                                    boolean isFault) {
        String action = null;
        action = targetNamespace;
        action += Names.WSA_ACTION_DELIMITER;
        action += method.getDeclaringClass().getSimpleName();
        if (isFault) {
            action += method.getName();
            action += Names.WSA_FAULT_DELIMITER;
        }
        action += Names.WSA_ACTION_DELIMITER;
        action += localName;
        return action;
    }

    /**
     * Get a DataBindingCallback (for use with an outgoing partial response).
     *
     * @return a DataBindingCallback
     */
    private static DataBindingCallback getDataBindingCallback()
        throws JAXBException {
        return new JAXBDataBindingCallback(null,
                                           DataBindingCallback.Mode.PARTS,
                                           getJAXBContext());
    }
}










TOP

Related Classes of org.objectweb.celtix.bus.ws.addressing.ContextUtils

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.