handlerchaininvoker.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 767 行 · 第 1/2 页

JAVA
767
字号
/* * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Emil Ong */package com.caucho.soap.jaxws;import java.io.*;import java.net.HttpURLConnection;import java.util.*;import java.util.logging.Level;import java.util.logging.Logger;import javax.activation.DataHandler;import javax.servlet.http.HttpServletRequest;import javax.xml.namespace.QName;import javax.xml.stream.XMLStreamException;import javax.xml.soap.MessageFactory;import javax.xml.soap.SOAPException;import javax.xml.soap.SOAPFault;import javax.xml.soap.SOAPMessage;import javax.xml.transform.*;import javax.xml.transform.dom.*;import javax.xml.transform.stream.*;import javax.xml.ws.*;import javax.xml.ws.handler.*;import static javax.xml.ws.handler.MessageContext.*;import javax.xml.ws.handler.soap.*;import javax.xml.ws.soap.SOAPFaultException;import com.caucho.util.L10N;import com.caucho.xml.stream.StaxUtil;import com.caucho.xml.stream.XMLStreamReaderImpl;import com.caucho.xml.stream.XMLStreamWriterImpl;/** * Responsible for invoking a handler chain. * * Expected execution order: *  - prepare() *  - invoke(In|Out)bound() *  - [close()] *  - finish() **/public class HandlerChainInvoker {  private final static Logger log =     Logger.getLogger(HandlerChainInvoker.class.getName());  private final static L10N L = new L10N(HandlerChainInvoker.class);  private final List<Handler> _chain;  private final BindingProvider _bindingProvider;  // maintains state over a request-response pattern  private final boolean[] _invoked;  private Source _source;  private LogicalMessageContextImpl _logicalContext;  private SOAPMessageContextImpl _soapContext;  private RuntimeException _runtimeException = null;  private ProtocolException _protocolException = null;  private boolean _request;  private boolean _outbound;  private int _i;  private static Transformer _transformer;  public HandlerChainInvoker(List<Handler> chain)  {    _chain = JAXWSUtil.sortHandlerChain(chain);    _invoked = new boolean[_chain.size()];    _bindingProvider = null;  }  public HandlerChainInvoker(List<Handler> chain,                              BindingProvider bindingProvider)  {    _chain = JAXWSUtil.sortHandlerChain(chain);    _invoked = new boolean[_chain.size()];    _bindingProvider = bindingProvider;  }  public InputStream invokeServerInbound(HttpServletRequest request,                                         OutputStream os)    throws IOException  {    Map<String,DataHandler> attachments = new HashMap<String,DataHandler>();    Map<String,Object> httpProperties = new HashMap<String,Object>();    httpProperties.put(HTTP_REQUEST_METHOD, request.getMethod());    Map<String,List<String>> headers = new HashMap<String,List<String>>();    Enumeration headerNames = request.getHeaderNames();    while (headerNames.hasMoreElements()) {       String name = (String) headerNames.nextElement();      List<String> values = new ArrayList<String>();      Enumeration headerValues = request.getHeaders(name);      while (headerValues.hasMoreElements()) {        String value = (String) headerValues.nextElement();        values.add(value);      }      headers.put(name, values);    }    httpProperties.put(HTTP_REQUEST_HEADERS, headers);    prepare(httpProperties, /*request=*/true);    if (! invokeInbound(request.getInputStream(), attachments)) {      if (getProtocolException() != null) {        reverseDirection();        invokeInboundFaultHandlers();      }      else if (getRuntimeException() == null)        uninvokeInbound();      closeServer();      finish(os);      return null;    }    return finish();  }  public void invokeServerOutbound(Source source, OutputStream os)  {    Map<String,DataHandler> attachments = new HashMap<String,DataHandler>();    Map<String,Object> httpProperties = new HashMap<String,Object>();    httpProperties.put(HTTP_RESPONSE_CODE, Integer.valueOf(200));    httpProperties.put(HTTP_RESPONSE_HEADERS,                        new HashMap<String,List<String>>());    prepare(httpProperties, /*request=*/false);    if (! invokeOutbound(source, attachments)) {      if (getProtocolException() != null) {        reverseDirection();        invokeOutboundFaultHandlers();      }      /*      else if (getRuntimeException() != null) {        closeServer();        finish(response.getOutputStream());        throw getRuntimeException();      }*/    }    // XXX    closeServer();    finish(os);  }  public boolean invokeClientOutbound(Source source, OutputStream out)    throws ProtocolException  {    // XXX fill this in...    Map<String,DataHandler> attachments = new HashMap<String,DataHandler>();    Map<String,Object> httpProperties = new HashMap<String,Object>();    httpProperties.put(HTTP_REQUEST_METHOD, "POST");    httpProperties.put(HTTP_REQUEST_HEADERS,                        new HashMap<String,List<String>>());    prepare(httpProperties, /*request=*/true);    if (! invokeOutbound(source, attachments)) {      // XXX handle Oneway      if (getProtocolException() != null) {        reverseDirection();        invokeOutboundFaultHandlers();        closeClient();        if (getRuntimeException() != null)          throw getRuntimeException();        if (getProtocolException() != null)          throw getProtocolException();        return false;      }      else if (getRuntimeException() != null) {        closeClient();        throw getRuntimeException();      }      else {        uninvokeOutbound();        closeClient();        if (getRuntimeException() != null)          throw getRuntimeException();        if (getProtocolException() != null)          throw getProtocolException();        return false;      }    }    finish(out);    return true;  }  public InputStream invokeClientInbound(HttpURLConnection httpConnection)    throws IOException  {    // XXX fill this in...    Map<String,DataHandler> attachments = new HashMap<String,DataHandler>();    Map<String,Object> httpProperties = new HashMap<String,Object>();    httpProperties.put(HTTP_RESPONSE_CODE,                        Integer.valueOf(httpConnection.getResponseCode()));    httpProperties.put(HTTP_RESPONSE_HEADERS,                       httpConnection.getHeaderFields());    prepare(httpProperties, /*request=*/false);    if (! invokeInbound(httpConnection.getInputStream(), attachments)) {      if (getProtocolException() != null) {        reverseDirection();        invokeInboundFaultHandlers();        if (getRuntimeException() != null)          throw getRuntimeException();      }      else if (getRuntimeException() != null) {        closeClient();        throw getRuntimeException();      }    }    // XXX    closeClient();    return finish();  }  public void prepare(Map<String,Object> httpProperties, boolean request)  {    _logicalContext = new LogicalMessageContextImpl();    _soapContext = new SOAPMessageContextImpl();    _runtimeException = null;    _protocolException = null;    _request = request;    _logicalContext.putAll(httpProperties);    _soapContext.putAll(httpProperties);    importAppProperties(request);  }  public void closeServer()  {    for (int i = 0; i < _chain.size(); i++)      close(i);  }  public void closeClient()  {    for (int i = _chain.size() - 1; i >= 0; i--)      close(i);  }  public void finish(OutputStream out)  {    exportAppProperties(_request);    /*    if (_runtimeException != null)      return;*/    try {      getTransformer().transform(_source, new StreamResult(out));    }    catch (TransformerException e) {      throw new WebServiceException(e);    }  }  public InputStream finish()  {    exportAppProperties(_request);    if (_runtimeException != null)      return null;    try {      ByteArrayOutputStream baos = new ByteArrayOutputStream();      getTransformer().transform(_source, new StreamResult(baos));      return new ByteArrayInputStream(baos.toByteArray());    }    catch (TransformerException e) {      throw new WebServiceException(e);    }  }  /**   * Invoke the handler chain for an outbound message.   **/  public boolean invokeOutbound(Source source,                                 Map<String,DataHandler> attachments)    throws WebServiceException  {    _source = source;    // Set the mandatory properties    _logicalContext.put(MESSAGE_OUTBOUND_PROPERTY, Boolean.TRUE);    _soapContext.put(MESSAGE_OUTBOUND_PROPERTY, Boolean.TRUE);    _logicalContext.put(OUTBOUND_MESSAGE_ATTACHMENTS, attachments);    _soapContext.put(OUTBOUND_MESSAGE_ATTACHMENTS, attachments);    for (_i = 0; _i < _chain.size(); _i++) {      boolean success = handleMessage(_i);      if (_protocolException != null)        return false;      if (_runtimeException != null)        return false;      if (! success)        return false;    }    return true;  }  /**   * When a message direction is reversed within the chain, this method   * runs the message backwards through the previous handlers.  This   * method should only be invoked when a handler returns false, but   * does not throw any kind of exception.   **/  public boolean uninvokeOutbound()    throws WebServiceException  {    // Set the mandatory properties    _logicalContext.put(MESSAGE_OUTBOUND_PROPERTY, Boolean.FALSE);    _soapContext.put(MESSAGE_OUTBOUND_PROPERTY, Boolean.FALSE);    // NOTE: the order is reversed for inbound messages    for (_i--; _i >= 0; _i--) {      boolean success = handleMessage(_i);      if (_protocolException != null)        return false;

⌨️ 快捷键说明

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