/*
* 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+"/";
}
}