aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.ws.util; aoqi@0: aoqi@0: import com.sun.xml.internal.ws.api.WSBinding; aoqi@0: import com.sun.xml.internal.ws.api.databinding.MetadataReader; aoqi@0: import com.sun.xml.internal.ws.api.server.AsyncProvider; aoqi@0: import com.sun.xml.internal.ws.api.streaming.XMLStreamReaderFactory; aoqi@0: import com.sun.xml.internal.ws.handler.HandlerChainsModel; aoqi@0: import com.sun.xml.internal.ws.model.ReflectAnnotationReader; aoqi@0: import com.sun.xml.internal.ws.server.EndpointFactory; aoqi@0: import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil; aoqi@0: import com.sun.istack.internal.NotNull; aoqi@0: aoqi@0: import javax.jws.HandlerChain; aoqi@0: import javax.jws.WebService; aoqi@0: import javax.jws.soap.SOAPMessageHandlers; aoqi@0: import javax.xml.namespace.QName; aoqi@0: import javax.xml.stream.XMLStreamException; aoqi@0: import javax.xml.stream.XMLStreamReader; aoqi@0: import javax.xml.ws.Provider; aoqi@0: import javax.xml.ws.Service; aoqi@0: import java.io.IOException; aoqi@0: import java.io.InputStream; aoqi@0: import java.net.URL; aoqi@0: import java.util.logging.Logger; aoqi@0: aoqi@0: /** aoqi@0: *

Used by client and server side to create handler information aoqi@0: * from annotated class. The public methods all return a aoqi@0: * HandlerChainInfo that contains the handlers and role information aoqi@0: * needed at runtime. aoqi@0: * aoqi@0: *

All of the handler chain descriptors follow the same schema, aoqi@0: * whether they are wsdl customizations, handler files specified aoqi@0: * by an annotation, or are included in the sun-jaxws.xml file. aoqi@0: * So this class is used for all handler xml information. The aoqi@0: * two public entry points are aoqi@0: * {@link HandlerAnnotationProcessor#buildHandlerInfo}, called aoqi@0: * when you have an annotated class that points to a file. aoqi@0: * aoqi@0: *

The methods in the class are static so that it may called aoqi@0: * from the runtime statically. aoqi@0: * aoqi@0: * @see com.sun.xml.internal.ws.util.HandlerAnnotationInfo aoqi@0: * aoqi@0: * @author JAX-WS Development Team aoqi@0: */ aoqi@0: public class HandlerAnnotationProcessor { aoqi@0: aoqi@0: private static final Logger logger = Logger.getLogger( aoqi@0: com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".util"); aoqi@0: aoqi@0: /** aoqi@0: *

This method is called by aoqi@0: * {@link EndpointFactory} when aoqi@0: * they have an annotated class. aoqi@0: * aoqi@0: *

If there is no handler chain annotation on the class, aoqi@0: * this method will return null. Otherwise it will load the aoqi@0: * class and call the parseHandlerFile method to read the aoqi@0: * information. aoqi@0: * aoqi@0: * @return A HandlerAnnotationInfo object that stores the aoqi@0: * handlers and roles. Will return null if the class passed aoqi@0: * in has no handler chain annotation. aoqi@0: */ aoqi@0: public static HandlerAnnotationInfo buildHandlerInfo(@NotNull aoqi@0: Class clazz, QName serviceName, QName portName, WSBinding binding) { aoqi@0: aoqi@0: MetadataReader metadataReader = EndpointFactory.getExternalMetadatReader(clazz, binding); aoqi@0: if (metadataReader == null) { aoqi@0: metadataReader = new ReflectAnnotationReader(); aoqi@0: } aoqi@0: aoqi@0: // clazz = checkClass(clazz); aoqi@0: HandlerChain handlerChain = metadataReader.getAnnotation(HandlerChain.class, clazz); aoqi@0: if (handlerChain == null) { aoqi@0: clazz = getSEI(clazz, metadataReader); aoqi@0: if (clazz != null) aoqi@0: handlerChain = metadataReader.getAnnotation(HandlerChain.class, clazz); aoqi@0: if (handlerChain == null) aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: if (clazz.getAnnotation(SOAPMessageHandlers.class) != null) { aoqi@0: throw new UtilException( aoqi@0: "util.handler.cannot.combine.soapmessagehandlers"); aoqi@0: } aoqi@0: InputStream iStream = getFileAsStream(clazz, handlerChain); aoqi@0: XMLStreamReader reader = aoqi@0: XMLStreamReaderFactory.create(null,iStream, true); aoqi@0: XMLStreamReaderUtil.nextElementContent(reader); aoqi@0: HandlerAnnotationInfo handlerAnnInfo = HandlerChainsModel.parseHandlerFile(reader, clazz.getClassLoader(), aoqi@0: serviceName, portName, binding); aoqi@0: try { aoqi@0: reader.close(); aoqi@0: iStream.close(); aoqi@0: } catch (XMLStreamException e) { aoqi@0: e.printStackTrace(); aoqi@0: throw new UtilException(e.getMessage()); aoqi@0: } catch (IOException e) { aoqi@0: e.printStackTrace(); aoqi@0: throw new UtilException(e.getMessage()); aoqi@0: } aoqi@0: return handlerAnnInfo; aoqi@0: } aoqi@0: aoqi@0: public static HandlerChainsModel buildHandlerChainsModel(final Class clazz) { aoqi@0: if(clazz == null) { aoqi@0: return null; aoqi@0: } aoqi@0: HandlerChain handlerChain = aoqi@0: clazz.getAnnotation(HandlerChain.class); aoqi@0: if(handlerChain == null) aoqi@0: return null; aoqi@0: InputStream iStream = getFileAsStream(clazz, handlerChain); aoqi@0: XMLStreamReader reader = aoqi@0: XMLStreamReaderFactory.create(null,iStream, true); aoqi@0: XMLStreamReaderUtil.nextElementContent(reader); aoqi@0: HandlerChainsModel handlerChainsModel = HandlerChainsModel.parseHandlerConfigFile(clazz, reader); aoqi@0: try { aoqi@0: reader.close(); aoqi@0: iStream.close(); aoqi@0: } catch (XMLStreamException e) { aoqi@0: e.printStackTrace(); aoqi@0: throw new UtilException(e.getMessage()); aoqi@0: } catch (IOException e) { aoqi@0: e.printStackTrace(); aoqi@0: throw new UtilException(e.getMessage()); aoqi@0: } aoqi@0: return handlerChainsModel; aoqi@0: } aoqi@0: aoqi@0: static Class getClass(String className) { aoqi@0: try { aoqi@0: return Thread.currentThread().getContextClassLoader().loadClass( aoqi@0: className); aoqi@0: } catch (ClassNotFoundException e) { aoqi@0: throw new UtilException("util.handler.class.not.found", aoqi@0: className); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: static Class getSEI(Class clazz, MetadataReader metadataReader) { aoqi@0: if (metadataReader == null) { aoqi@0: metadataReader = new ReflectAnnotationReader(); aoqi@0: } aoqi@0: aoqi@0: if (Provider.class.isAssignableFrom(clazz) || AsyncProvider.class.isAssignableFrom(clazz)) { aoqi@0: //No SEI for Provider Implementation aoqi@0: return null; aoqi@0: } aoqi@0: if (Service.class.isAssignableFrom(clazz)) { aoqi@0: //No SEI for Service class aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: WebService webService = metadataReader.getAnnotation(WebService.class, clazz); aoqi@0: if (webService == null) { aoqi@0: throw new UtilException("util.handler.no.webservice.annotation", clazz.getCanonicalName()); aoqi@0: } aoqi@0: aoqi@0: String ei = webService.endpointInterface(); aoqi@0: if (ei.length() > 0) { aoqi@0: clazz = getClass(webService.endpointInterface()); aoqi@0: WebService ws = metadataReader.getAnnotation(WebService.class, clazz); aoqi@0: if (ws == null) { aoqi@0: throw new UtilException("util.handler.endpoint.interface.no.webservice", aoqi@0: webService.endpointInterface()); aoqi@0: } aoqi@0: return clazz; aoqi@0: } aoqi@0: return null; aoqi@0: } aoqi@0: aoqi@0: static InputStream getFileAsStream(Class clazz, HandlerChain chain) { aoqi@0: URL url = clazz.getResource(chain.file()); aoqi@0: if (url == null) { aoqi@0: url = Thread.currentThread().getContextClassLoader(). aoqi@0: getResource(chain.file()); aoqi@0: } aoqi@0: if (url == null) { aoqi@0: String tmp = clazz.getPackage().getName(); aoqi@0: tmp = tmp.replace('.', '/'); aoqi@0: tmp += "/" + chain.file(); aoqi@0: url = aoqi@0: Thread.currentThread().getContextClassLoader().getResource(tmp); aoqi@0: } aoqi@0: if (url == null) { aoqi@0: throw new UtilException("util.failed.to.find.handlerchain.file", aoqi@0: clazz.getName(), chain.file()); aoqi@0: } aoqi@0: try { aoqi@0: return url.openStream(); aoqi@0: } catch (IOException e) { aoqi@0: throw new UtilException("util.failed.to.parse.handlerchain.file", aoqi@0: clazz.getName(), chain.file()); aoqi@0: } aoqi@0: } aoqi@0: }