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

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

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

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

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

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