/* * Copyright (c) 1998-2011 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.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; import javax.jws.HandlerChain; import javax.jws.WebService; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import javax.xml.stream.XMLStreamException; import javax.xml.ws.WebServiceException; import javax.xml.ws.handler.Handler; import javax.xml.ws.handler.HandlerResolver; import javax.xml.ws.handler.LogicalHandler; import com.caucho.util.L10N; import com.caucho.soap.jaxws.handlerchain.HandlerChains; import com.caucho.xml.stream.StaxUtil; import com.caucho.xml.stream.XMLStreamReaderImpl; import com.caucho.xml.stream.XMLStreamWriterImpl; public class JAXWSUtil { private static final Logger log = Logger.getLogger(JAXWSUtil.class.getName()); private final static L10N L = new L10N(JAXWSUtil.class); private static Unmarshaller _handlerChainUnmarshaller = null; public static void writeStartSOAPEnvelope(Writer out, String namespace) throws IOException { out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); out.write("<soapenv:Envelope xmlns:soapenv=\"" + namespace + "\">"); out.write("<soapenv:Body>"); out.flush(); } public static void writeEndSOAPEnvelope(Writer out) throws IOException { out.write("</soapenv:Body>"); out.write("</soapenv:Envelope>"); out.flush(); } public static void extractSOAPBody(InputStream in, OutputStream out) throws WebServiceException { boolean foundBody = false; try { XMLStreamReaderImpl reader = new XMLStreamReaderImpl(in); // skip the Envelope reader.nextTag(); if (reader.getEventType() != reader.START_ELEMENT || ! "Envelope".equals(reader.getLocalName())) { throw new WebServiceException(L.l("Invalid response from server: No Envelope found")); } // find the body while (reader.hasNext()) { reader.next(); if (reader.getEventType() == reader.START_ELEMENT && "Body".equals(reader.getLocalName())) { // Copy the body contents to a StreamDataHandler reader.nextTag(); XMLStreamWriterImpl xmlWriter = new XMLStreamWriterImpl(out, false); StaxUtil.copyReaderToWriter(reader, xmlWriter); xmlWriter.flush(); foundBody = true; break; } } } catch (XMLStreamException e) { throw new WebServiceException(e); } if (! foundBody) throw new WebServiceException(L.l("Invalid response from server")); } public static HandlerResolver createHandlerResolver(Class cl, HandlerChain handlerChain) throws WebServiceException { try { if (_handlerChainUnmarshaller == null) { JAXBContext context = JAXBContext.newInstance("com.caucho.soap.jaxws.handlerchain"); _handlerChainUnmarshaller = context.createUnmarshaller(); } if (log.isLoggable(Level.FINER)) { log.finer("Creating handler chain for " + cl + " from file " + handlerChain.file()); } InputStream is = cl.getResourceAsStream(handlerChain.file()); HandlerChains handlerChains = (HandlerChains) _handlerChainUnmarshaller.unmarshal(is); return handlerChains; } catch (Exception e) { throw new WebServiceException(e); } } public static List<Handler> sortHandlerChain(List<Handler> handlerChain) { // According to the JAX-WS documentation, handler chains must be sorted // so that all LogicalHandlers appear before protocol Handlers // (protocol Handlers are just Handlers that are not LogicalHandlers) // // XXX do this by bubbling up instead of creating a new list List list = new ArrayList<Handler>(); for (int i = 0; i < handlerChain.size(); i++) { Handler handler = handlerChain.get(i); if (handler instanceof LogicalHandler) list.add(handler); } for (int i = 0; i < handlerChain.size(); i++) { Handler handler = handlerChain.get(i); if (! (handler instanceof LogicalHandler)) list.add(handler); } return list; } public static Class getEndpointInterface(Class type) { WebService webService = (WebService) type.getAnnotation(WebService.class); if (webService != null && ! "".equals(webService.endpointInterface())) { try { ClassLoader loader = type.getClassLoader(); return loader.loadClass(webService.endpointInterface()); } catch (ClassNotFoundException e) { throw new WebServiceException(e); } } return type; } public static String getTargetNamespace(Class type, Class api) { WebService webService = (WebService) type.getAnnotation(WebService.class); // try to get the namespace from the annotation first... if (webService != null) { if (! "".equals(webService.targetNamespace())) return webService.targetNamespace(); else if (! api.equals(type)) { webService = (WebService) api.getAnnotation(WebService.class); if (! "".equals(webService.targetNamespace())) return webService.targetNamespace(); } } // get the namespace from the package name String namespace = null; String packageName = type.getPackage().getName(); StringTokenizer st = new StringTokenizer(packageName, "."); while (st.hasMoreTokens()) { if (namespace == null) namespace = st.nextToken(); else namespace = st.nextToken() + "." + namespace; } return "http://"+namespace+"/"; } }