/*
* 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 Scott Ferguson
*/
package com.caucho.soap.reflect;
import com.caucho.jaxb.JAXBContextImpl;
import com.caucho.jaxb.JAXBUtil;
import com.caucho.soap.jaxws.JAXWSUtil;
import com.caucho.soap.skeleton.DirectSkeleton;
import com.caucho.soap.skeleton.AbstractAction;
import com.caucho.soap.wsdl.WSDLDefinitions;
import com.caucho.util.L10N;
import org.w3c.dom.Node;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.WebServiceException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;
/**
* Introspects a web service
*/
public class WebServiceIntrospector {
private static final Logger log
= Logger.getLogger(WebServiceIntrospector.class.getName());
private static XMLOutputFactory _outputFactory = null;
public static final L10N L = new L10N(WebServiceIntrospector.class);
/**
* Introspects the class
*/
public static DirectSkeleton introspect(Class type)
throws JAXBException, WebServiceException
{
// matches RI stub for the WSDL location
return introspect(type, "REPLACE_WITH_ACTUAL_URL", null);
}
/**
* Introspects the class
*/
public static DirectSkeleton introspect(Class type,
String wsdlLocation,
WSDLDefinitions wsdl)
throws JAXBException, WebServiceException
{
// server/4221 vs soap/0301
/*
if (! type.isAnnotationPresent(WebService.class))
throw new RuntimeException(L.l("{0}: needs a @WebService annotation.",
type.getName()));
*/
boolean isInterface = type.isInterface();
WebService webService = (WebService) type.getAnnotation(WebService.class);
// Get all the classes that JAXB needs, then generate schema for them
HashSet<Class> jaxbClasses = new HashSet<Class>();
JAXBUtil.introspectClass(type, jaxbClasses);
Class[] jaxbClassArray = new Class[jaxbClasses.size()];
jaxbClasses.toArray(jaxbClassArray);
Class api = JAXWSUtil.getEndpointInterface(type);
String namespace = JAXWSUtil.getTargetNamespace(type, api);
Map<String,Object> properties = new HashMap<String,Object>();
properties.put(JAXBContextImpl.TARGET_NAMESPACE, namespace);
JAXBContextImpl jaxbContext =
new JAXBContextImpl(jaxbClassArray, properties);
Marshaller marshaller = jaxbContext.createMarshaller();
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
DirectSkeleton skel =
new DirectSkeleton(type, api, jaxbContext, wsdlLocation, namespace, wsdl);
Method[] methods = type.getMethods();
boolean excludeIfNoWebMethod = false;
for (int i = 0; i < methods.length; i++) {
WebMethod webMethod = methods[i].getAnnotation(WebMethod.class);
if (webMethod != null && ! webMethod.exclude()) {
excludeIfNoWebMethod = true;
break;
}
}
for (int i = 0; i < methods.length; i++) {
if ((methods[i].getModifiers() & Modifier.PUBLIC) == 0)
continue;
WebMethod webMethod = methods[i].getAnnotation(WebMethod.class);
if (api != type) {
/* XXX: needed for demo
if (webMethod != null)
throw new WebServiceException(L.l("Cannot use WebMethod with WebService.endpointInterface: {0}", type));
*/
try {
api.getDeclaredMethod(methods[i].getName(),
methods[i].getParameterTypes());
}
catch (NoSuchMethodException e) {
// ignore methods not declared in the endpoint interface
continue;
}
}
if (excludeIfNoWebMethod && webMethod == null)
continue;
if (webService == null && webMethod == null && ! isInterface)
continue;
if (webMethod == null && methods[i].getDeclaringClass() != type)
continue;
if (webMethod != null && webMethod.exclude())
continue;
AbstractAction action =
AbstractAction.createAction(methods[i], jaxbContext, namespace, wsdl,
marshaller, unmarshaller);
skel.addAction(methods[i], action);
}
return skel;
}
private static XMLStreamWriter getStreamWriter(DOMResult result)
throws XMLStreamException
{
if (_outputFactory == null)
_outputFactory = XMLOutputFactory.newInstance();
return _outputFactory.createXMLStreamWriter(result);
}
}