soaphandler.java

来自「ejb3 java session bean」· Java 代码 · 共 562 行 · 第 1/2 页

JAVA
562
字号
/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the JBPM BPEL PUBLIC LICENSE AGREEMENT as * published by JBoss Inc.; either version 1.0 of the License, or * (at your option) any later version. * * This software 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. */package org.jbpm.bpel.integration.server;import java.io.IOException;import java.util.Collections;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Map.Entry;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.MessageConsumer;import javax.jms.MessageProducer;import javax.jms.ObjectMessage;import javax.jms.Session;import javax.servlet.ServletContext;import javax.wsdl.Binding;import javax.wsdl.Definition;import javax.wsdl.Message;import javax.wsdl.Operation;import javax.wsdl.Port;import javax.wsdl.PortType;import javax.wsdl.extensions.soap.SOAPBinding;import javax.xml.namespace.QName;import javax.xml.rpc.JAXRPCException;import javax.xml.rpc.handler.Handler;import javax.xml.rpc.handler.HandlerInfo;import javax.xml.rpc.handler.MessageContext;import javax.xml.rpc.handler.soap.SOAPMessageContext;import javax.xml.rpc.soap.SOAPFaultException;import javax.xml.soap.SOAPBody;import javax.xml.soap.SOAPElement;import javax.xml.soap.SOAPEnvelope;import javax.xml.soap.SOAPException;import javax.xml.soap.SOAPMessage;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.xml.sax.SAXException;import org.jbpm.JbpmConfiguration;import org.jbpm.JbpmContext;import org.jbpm.bpel.BpelException;import org.jbpm.bpel.graph.def.BpelProcessDefinition;import org.jbpm.bpel.graph.exe.BpelFaultException;import org.jbpm.bpel.integration.jms.IntegrationConstants;import org.jbpm.bpel.integration.jms.IntegrationControl;import org.jbpm.bpel.integration.jms.PartnerLinkEntry;import org.jbpm.bpel.integration.jms.RequestListener;import org.jbpm.bpel.integration.soap.MessageDirection;import org.jbpm.bpel.integration.soap.SoapBindConstants;import org.jbpm.bpel.integration.soap.SoapFormatter;import org.jbpm.bpel.integration.soap.SoapUtil;import org.jbpm.bpel.sublang.def.PropertyQuery;import org.jbpm.bpel.variable.def.MessageType;import org.jbpm.bpel.wsdl.PropertyAlias;import org.jbpm.bpel.wsdl.xml.WsdlUtil;import org.jbpm.bpel.xml.util.DatatypeUtil;import org.jbpm.bpel.xml.util.XmlUtil;import org.jbpm.util.ClassLoaderUtil;/** * @author Alejandro Guizar * @version $Revision: 1.26 $ $Date: 2007/11/25 13:06:55 $ */public class SoapHandler implements Handler {  private QName[] headers;  private IntegrationControl integrationControl;  private QName portTypeName;  private QName serviceName;  private String portName;  private SoapFormatter formatter;  private static final Log log = LogFactory.getLog(SoapHandler.class);  private static final Map endpointMetadataLookups = readEndpointMetadataLookups();  /** Message context property for the operation name */  static final String OPERATION_NAME_PROP = "org.jbpm.operation.name";  /** Message context property for the message parts */  static final String MESSAGE_PARTS_PROP = "org.jbpm.message.parts";  /** Message context property for the fault name */  static final String FAULT_NAME_PROP = "org.jbpm.fault.name";  /** Message context property for the SOAP fault exception */  static final String FAULT_EXCEPTION_PROP = "org.jbpm.fault.exception";  /** Servlet context attribute for the integration control instance */  public static final String INTEGRATION_CONTROL_ATTR = "org.jbpm.integration.control";  public static final String RESOURCE_ENDPOINT_METADATA_LOOKUPS = "resource.endpoint.metadata.lookups";  /**   * Allocates a new handler for JAX-RPC use.   */  public SoapHandler() {  }  /**   * Allocates a new handler for test purposes.   */  SoapHandler(IntegrationControl integrationControl, QName serviceName, Port port) {    this.integrationControl = integrationControl;    this.serviceName = serviceName;    portName = port.getName();    Binding binding = port.getBinding();    portTypeName = binding.getPortType().getQName();    formatter = new SoapFormatter(binding);  }  public void init(HandlerInfo handlerInfo) throws JAXRPCException {    // save headers    headers = handlerInfo.getHeaders();  }  public void destroy() {    // release port-component specific state    integrationControl = null;  }  public QName[] getHeaders() {    return headers;  }  public boolean handleRequest(MessageContext messageContext) throws JAXRPCException,      SOAPFaultException {    /*     * WSEE 1.1 section 6.2.2.1: If Handler instances are pooled, they must be pooled by Port     * component. This is because Handlers may retain non-client specific state across method calls     * that are specific to the Port component.     */    if (integrationControl == null) {      /*       * COMPLIANCE NOTE: the state initialized in this call is port-component specific, but       * non-client specific       */      lookupEndpointMetadata(messageContext);    }    JbpmContext jbpmContext = integrationControl.getIntegrationServiceFactory()        .getJbpmConfiguration()        .createJbpmContext();    try {      Session jmsSession = integrationControl.createJmsSession();      try {        SOAPMessage soapMessage = ((SOAPMessageContext) messageContext).getMessage();        ObjectMessage jmsRequest = sendRequest(soapMessage, jmsSession, jbpmContext);        Destination replyTo = jmsRequest.getJMSReplyTo();        if (replyTo != null) {          ObjectMessage jmsResponse = receiveResponse(jmsSession, replyTo,              jmsRequest.getJMSMessageID(), jbpmContext);          // remember operation name and message parts for handling response          messageContext.setProperty(OPERATION_NAME_PROP,              jmsRequest.getStringProperty(IntegrationConstants.OPERATION_NAME_PROP));          messageContext.setProperty(MESSAGE_PARTS_PROP, jmsResponse.getObject());          // is response a fault?          String faultName = jmsResponse.getStringProperty(IntegrationConstants.FAULT_NAME_PROP);          if (faultName != null) {            // remember fault name for handling fault            messageContext.setProperty(FAULT_NAME_PROP, faultName);            throw new SOAPFaultException(SoapBindConstants.CLIENT_FAULTCODE,                SoapBindConstants.BUSINESS_FAULTSTRING, null, null);          }        }      }      finally {        jmsSession.close();      }    }    /*     * NO need to set jbpm context as rollback only for any exception, since operations in try-block     * only read definitions from database     */    catch (SOAPFaultException e) {      log.debug("request caused a fault", e);      messageContext.setProperty(FAULT_EXCEPTION_PROP, e);    }    catch (SOAPException e) {      /*       * BP 1.2 R2724: If an INSTANCE receives an envelope that is inconsistent with its WSDL       * description, it SHOULD generate a soap:Fault with a faultcode of "Client", unless a       * "MustUnderstand" or "VersionMismatch" fault is generated.       */      log.debug("incoming soap message carries invalid content", e);      messageContext.setProperty(FAULT_EXCEPTION_PROP, new SOAPFaultException(          SoapBindConstants.CLIENT_FAULTCODE, e.getMessage(), null, null));    }    catch (JMSException e) {      throw new JAXRPCException("message delivery failed", e);    }    finally {      jbpmContext.close();    }    return true;  }  private void lookupEndpointMetadata(MessageContext messageContext) {    // obtain metadata lookup strategy for the given message context class    EndpointMetadataLookup endpointMetadataLookup = getEndpointMetadataLookup(messageContext.getClass());    // lookup metadata in message context    EndpointMetadata endpointMetadata = endpointMetadataLookup.lookupMetaData(messageContext);    Definition definition = endpointMetadata.getWsdlDefinition();    serviceName = endpointMetadata.getServiceName();    portName = endpointMetadata.getPortName();    Binding binding = definition.getService(serviceName).getPort(portName).getBinding();    portTypeName = binding.getPortType().getQName();    formatter = new SoapFormatter(binding, endpointMetadata.getFaultFormat());    ServletContext servletContext = endpointMetadata.getServletContext();    integrationControl = (IntegrationControl) servletContext.getAttribute(INTEGRATION_CONTROL_ATTR);    integrationControl.getMyCatalog().addDefinition(definition);  }  private static EndpointMetadataLookup getEndpointMetadataLookup(Class messageContextClass) {    String contextClassName = messageContextClass.getName();    EndpointMetadataLookup endpointMetadataLookup = (EndpointMetadataLookup) endpointMetadataLookups.get(contextClassName);    if (endpointMetadataLookup == null) {      throw new BpelException("no endpoint metadata lookup for message context: "          + contextClassName);    }    return endpointMetadataLookup;  }  /**   * Obtain the mapping of known message context implementations to their corresponding endpoint   * metadata lookups from the configuration.   */  private static Map readEndpointMetadataLookups() {    // get activity readers resource name    String resource = JbpmConfiguration.Configs.getString(RESOURCE_ENDPOINT_METADATA_LOOKUPS);    // parse lookups document    Element lookupsElem;    try {      lookupsElem = XmlUtil.parseResource(resource);    }    catch (SAXException e) {      log.error("endpoint metadata lookups document contains invalid xml: " + resource, e);      return Collections.EMPTY_MAP;    }    catch (IOException e) {      log.error("could not read endpoint metadata lookups document: " + resource, e);      return Collections.EMPTY_MAP;    }    // walk through endpointMetadataLookup elements    HashMap lookups = new HashMap();    for (Iterator i = XmlUtil.getElements(lookupsElem, null, "endpointMetadataLookup"); i.hasNext();) {      Element lookupElem = (Element) i.next();      String contextClassName = lookupElem.getAttribute("messageContextClass");      // load lookup class      String lookupClassName = lookupElem.getAttribute("lookupClass");      try {        Class lookupClass = ClassLoaderUtil.getClassLoader().loadClass(lookupClassName);        // validate lookup class        if (!EndpointMetadataLookup.class.isAssignableFrom(lookupClass)) {          log.warn("not an endpoint metadata lookup: " + lookupClassName);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?