Home » openejb-3.1.2-src » org.apache » openejb » server » axis » [javadoc | source]

    1   /**
    2    *   Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   package org.apache.openejb.server.axis;
   18   
   19   import java.io.InputStream;
   20   import java.io.IOException;
   21   import java.net.URI;
   22   import java.net.URL;
   23   import java.util.Iterator;
   24   import java.util.Map;
   25   import javax.servlet.http.HttpServletResponse;
   26   import javax.wsdl.OperationType;
   27   import javax.xml.soap.MimeHeader;
   28   import javax.xml.soap.MimeHeaders;
   29   import javax.xml.soap.SOAPMessage;
   30   
   31   import org.apache.axis.AxisEngine;
   32   import org.apache.axis.AxisFault;
   33   import org.apache.axis.Constants;
   34   import org.apache.axis.Message;
   35   import org.apache.axis.MessageContext;
   36   import org.apache.axis.SOAPPart;
   37   import org.apache.axis.handlers.soap.SOAPService;
   38   import org.apache.axis.message.SOAPEnvelope;
   39   import org.apache.axis.soap.SOAPConstants;
   40   import org.apache.axis.transport.http.HTTPConstants;
   41   import org.apache.axis.utils.Messages;
   42   import org.apache.openejb.server.webservices.WsConstants;
   43   import org.apache.openejb.server.webservices.saaj.SaajUniverse;
   44   import org.apache.openejb.server.httpd.HttpRequest;
   45   import org.apache.openejb.server.httpd.HttpResponse;
   46   import org.apache.openejb.server.httpd.HttpListener;
   47   import org.apache.openejb.util.Logger;
   48   import org.apache.openejb.util.LogCategory;
   49   import org.w3c.dom.Element;
   50   
   51   public class AxisWsContainer implements HttpListener {
   52       private static final Logger logger = Logger.getInstance(LogCategory.AXIS, AxisWsContainer.class);
   53       public static final String REQUEST = AxisWsContainer.class.getName() + "@Request";
   54       public static final String RESPONSE = AxisWsContainer.class.getName() + "@Response";
   55   
   56       public static final String XSD_NS = "http://www.w3.org/2001/XMLSchema";
   57   
   58       private final URL wsdlLocation;
   59       private final SOAPService service;
   60   
   61       private final ClassLoader classLoader;
   62       private final Map wsdlMap;
   63   
   64       public AxisWsContainer(URL wsdlURL, SOAPService service, Map wsdlMap, ClassLoader classLoader) {
   65           this.wsdlLocation = wsdlURL;
   66           this.service = service;
   67           this.wsdlMap = wsdlMap;
   68           if (classLoader == null) {
   69               this.classLoader = Thread.currentThread().getContextClassLoader();
   70           } else {
   71               this.classLoader = classLoader;
   72           }
   73       }
   74   
   75       public void onMessage(HttpRequest request, HttpResponse response) throws Exception {
   76           SaajUniverse universe = new SaajUniverse();
   77           universe.set(SaajUniverse.AXIS1);
   78           try {
   79               doService(request, response);
   80           } finally {
   81               universe.unset();
   82           }
   83       }
   84       
   85       protected void doService(HttpRequest req, HttpResponse res) throws Exception {
   86           org.apache.axis.MessageContext messageContext = new org.apache.axis.MessageContext(null);
   87           req.setAttribute(WsConstants.MESSAGE_CONTEXT, messageContext);
   88   
   89           messageContext.setClassLoader(classLoader);
   90   
   91           Message responseMessage = null;
   92   
   93           String contentType = req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);
   94           String contentLocation = req.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION);
   95           InputStream inputStream = req.getInputStream();
   96           Message requestMessage = new Message(inputStream, false, contentType, contentLocation);
   97   
   98           messageContext.setRequestMessage(requestMessage);
   99           messageContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO, req.getURI().getPath());
  100           messageContext.setProperty(org.apache.axis.MessageContext.TRANS_URL, req.getURI().toString());
  101           messageContext.setService(service);
  102           messageContext.setProperty(REQUEST, req);
  103           messageContext.setProperty(RESPONSE, res);
  104           messageContext.setProperty(AxisEngine.PROP_DISABLE_PRETTY_XML, Boolean.TRUE);
  105   
  106           ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
  107           try {
  108               try {
  109                   String characterEncoding = (String) requestMessage.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
  110                   if (characterEncoding != null) {
  111                       messageContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, characterEncoding);
  112                   } else {
  113                       messageContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "UTF-8");
  114                   }
  115   
  116   
  117                   String soapAction = req.getHeader(HTTPConstants.HEADER_SOAP_ACTION);
  118                   if (soapAction != null) {
  119                       messageContext.setUseSOAPAction(true);
  120                       messageContext.setSOAPActionURI(soapAction);
  121                   }
  122   
  123                   SOAPEnvelope env = requestMessage.getSOAPEnvelope();
  124                   if (env != null && env.getSOAPConstants() != null) {
  125                       messageContext.setSOAPConstants(env.getSOAPConstants());
  126                   }
  127                   SOAPService service = messageContext.getService();
  128   
  129                   Thread.currentThread().setContextClassLoader(classLoader);
  130                   service.invoke(messageContext);
  131   
  132                   responseMessage = messageContext.getResponseMessage();
  133               } catch (AxisFault fault) {
  134                   
  135                  	if(req.getMethod() == HttpRequest.Method.GET && req.getParameters().isEmpty()){
  136                  		String serviceName = req.getURI().getRawPath();
  137                       serviceName = serviceName.substring(serviceName.lastIndexOf("/")+1);
  138                  		printServiceInfo(res,serviceName);
  139                  		return;
  140                  	}else{
  141                  		responseMessage = handleFault(fault, res, messageContext);
  142                  	}
  143   
  144               } catch (Exception e) {
  145                   responseMessage = handleException(messageContext, res, e);
  146               }
  147               //TODO investigate and fix operation == null!
  148               if (messageContext.getOperation() != null) {
  149                   if (messageContext.getOperation().getMep() == OperationType.ONE_WAY) {
  150                       // No content, so just indicate accepted
  151                       res.setStatusCode(202);
  152                       return;
  153                   } else if (responseMessage == null) {
  154                       responseMessage = handleException(messageContext, null, new RuntimeException("No response for non-one-way operation"));
  155                   }
  156               } else if (responseMessage == null) {
  157                   res.setStatusCode(202);
  158                   return;
  159               }
  160               try {
  161                   SOAPConstants soapConstants = messageContext.getSOAPConstants();
  162                   String contentType1 = responseMessage.getContentType(soapConstants);
  163                   res.setContentType(contentType1);
  164                   // Transfer MIME headers to HTTP headers for response message.
  165                   MimeHeaders responseMimeHeaders = responseMessage.getMimeHeaders();
  166                   for (Iterator i = responseMimeHeaders.getAllHeaders(); i.hasNext();) {
  167                       MimeHeader responseMimeHeader = (MimeHeader) i.next();
  168                       res.setHeader(responseMimeHeader.getName(),
  169                               responseMimeHeader.getValue());
  170                   }
  171                   //TODO discuss this with dims.
  172   //                // synchronize the character encoding of request and response
  173   //                String responseEncoding = (String) messageContext.getProperty(
  174   //                        SOAPMessage.CHARACTER_SET_ENCODING);
  175   //                if (responseEncoding != null) {
  176   //                    try {
  177   //                        responseMessage.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,
  178   //                                                responseEncoding);
  179   //                    } catch (SOAPException e) {
  180   //                        log.info(Messages.getMessage("exception00"), e);
  181   //                    }
  182   //                }
  183                   //determine content type from message response
  184                   contentType = responseMessage.getContentType(messageContext.
  185                           getSOAPConstants());
  186                   responseMessage.writeTo(res.getOutputStream());
  187               } catch (Exception e) {
  188                   logger.warning(Messages.getMessage("exception00"), e);
  189               }
  190           } finally {
  191               Thread.currentThread().setContextClassLoader(oldClassLoader);
  192           }
  193       }
  194   
  195       private Message handleException(MessageContext context, HttpResponse res, Exception e) {
  196           Message responseMessage;
  197           //other exceptions are internal trouble
  198           responseMessage = context.getResponseMessage();
  199           res.setStatusCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
  200           Message responseMsg = responseMessage;
  201           logger.warning(Messages.getMessage("exception00"), e);
  202           if (responseMsg == null) {
  203               AxisFault fault = AxisFault.makeFault(e);
  204               //log the fault
  205               Element runtimeException = fault.lookupFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
  206               if (runtimeException != null) {
  207                   logger.debug(Messages.getMessage("axisFault00"), fault);
  208                   //strip runtime details
  209                   fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
  210               }
  211               responseMsg = new Message(fault);
  212           }
  213           responseMessage = responseMsg;
  214           SOAPPart soapPart = (SOAPPart) responseMessage.getSOAPPart();
  215           soapPart.getMessage().setMessageContext(context);
  216           return responseMessage;
  217       }
  218   
  219       private Message handleFault(AxisFault fault, HttpResponse res, MessageContext context) {
  220           Message responseMessage;
  221           Element runtimeException = fault.lookupFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
  222   
  223           logger.warning(Messages.getMessage("axisFault00"), fault);
  224           if (runtimeException != null) {
  225               //strip runtime details
  226               fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
  227           }
  228   
  229           int status = fault.getFaultCode().getLocalPart().startsWith("Server.Unauth")
  230                   ? HttpServletResponse.SC_UNAUTHORIZED
  231                   : HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
  232           if (status == HttpServletResponse.SC_UNAUTHORIZED) {
  233               // unauth access results in authentication request
  234               // TODO: less generic realm choice?
  235               res.setHeader("WWW-Authenticate", "Basic realm=\"AXIS\"");
  236           }
  237           res.setStatusCode(status);
  238           responseMessage = context.getResponseMessage();
  239           if (responseMessage == null) {
  240               responseMessage = new Message(fault);
  241               SOAPPart soapPart = (SOAPPart) responseMessage.getSOAPPart();
  242               soapPart.getMessage().setMessageContext(context);
  243           }
  244           return responseMessage;
  245       }
  246   
  247       public void getWsdl(HttpRequest request, HttpResponse response) throws Exception {
  248           URI realLocation = request.getURI();
  249   //        log.info("Request at " + realLocation);
  250           String query = realLocation.getQuery();
  251           if (query == null || !query.toLowerCase().startsWith("wsdl")) {
  252               throw new IllegalStateException("request must contain a  wsdl or WSDL parameter: " + request.getParameters());
  253           }
  254           String locationKey;
  255           if (query.length() > 4) {
  256               locationKey = query.substring(5);
  257           } else {
  258               locationKey = wsdlLocation.toString();
  259           }
  260           Object wsdl = wsdlMap.get(locationKey);
  261           if (wsdl == null) {
  262               throw new IllegalStateException("No wsdl or schema known at location: " + locationKey);
  263           }
  264           URI updated = new URI(realLocation.getScheme(),
  265                   realLocation.getUserInfo(),
  266                   realLocation.getHost(),
  267                   realLocation.getPort(),
  268                   null, //try null for no path
  269                   null,
  270                   null);
  271           String replaced = ((String) wsdl).replaceAll(WsConstants.LOCATION_REPLACEMENT_TOKEN, updated.toString());
  272           response.getOutputStream().write(replaced.getBytes());
  273           response.getOutputStream().flush();
  274       }
  275   
  276       public void destroy() {
  277       }
  278   
  279       /**
  280        * print a snippet of service info.
  281        * @param response response
  282        * @param serviceName Name of the service
  283        */
  284   
  285       private void printServiceInfo(HttpResponse response,String serviceName) throws IOException{
  286           response.setContentType("text/html; charset=utf-8");
  287           StringBuffer output = new StringBuffer("<h1>")
  288                   .append(serviceName).append("</h1>\n");
  289   
  290           output.append("<p>").append(Messages.getMessage("axisService00"))
  291                   .append("</p>\n");
  292           output.append(
  293                   "<i>").append(
  294                   Messages.getMessage("perhaps00") ).append(
  295                   "</i>\n");
  296           response.getOutputStream().write(output.toString().getBytes());
  297       }
  298   
  299   }
  300   
  301   
  302   
  303   
  304   
  305   
  306   
  307   
  308   
  309   
  310   
  311   
  312   
  313   
  314   
  315   
  316   
  317   
  318   
  319   
  320   
  321   
  322   
  323   

Home » openejb-3.1.2-src » org.apache » openejb » server » axis » [javadoc | source]