325N/A/*
325N/A * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A */
325N/A
325N/Apackage com.sun.xml.internal.ws.handler;
325N/A
325N/Aimport com.sun.xml.internal.ws.api.BindingID;
325N/Aimport com.sun.xml.internal.ws.api.WSBinding;
325N/Aimport com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
325N/Aimport com.sun.xml.internal.ws.transport.http.DeploymentDescriptorParser;
325N/Aimport com.sun.xml.internal.ws.util.HandlerAnnotationInfo;
325N/Aimport com.sun.xml.internal.ws.util.JAXWSUtils;
325N/Aimport com.sun.xml.internal.ws.util.UtilException;
325N/A
325N/Aimport javax.annotation.PostConstruct;
325N/Aimport javax.xml.namespace.QName;
325N/Aimport javax.xml.stream.XMLStreamConstants;
325N/Aimport javax.xml.stream.XMLStreamReader;
325N/Aimport javax.xml.ws.handler.Handler;
325N/Aimport javax.xml.ws.handler.PortInfo;
325N/Aimport java.lang.reflect.Method;
325N/Aimport java.util.ArrayList;
325N/Aimport java.util.HashSet;
325N/Aimport java.util.List;
325N/Aimport java.util.Set;
325N/Aimport java.util.StringTokenizer;
325N/Aimport java.util.logging.Logger;
325N/A
325N/A
325N/Apublic class HandlerChainsModel {
325N/A private static final Logger logger = Logger.getLogger(
325N/A com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".util");
325N/A
325N/A private Class annotatedClass;
325N/A private List<HandlerChainType> handlerChains;
325N/A private String id;
325N/A /** Creates a new instance of HandlerChains */
325N/A private HandlerChainsModel(Class annotatedClass) {
325N/A this.annotatedClass = annotatedClass;
325N/A }
325N/A
325N/A private List<HandlerChainType> getHandlerChain() {
325N/A if (handlerChains == null) {
325N/A handlerChains = new ArrayList<HandlerChainType>();
325N/A }
325N/A return handlerChains;
325N/A }
325N/A
325N/A public String getId() {
325N/A return id;
325N/A }
325N/A
325N/A public void setId(String value) {
325N/A this.id = value;
325N/A }
325N/A /**
325N/A * reader should be on <handler-chains> element
325N/A */
325N/A public static HandlerChainsModel parseHandlerConfigFile(Class annotatedClass, XMLStreamReader reader) {
325N/A ensureProperName(reader,QNAME_HANDLER_CHAINS);
325N/A HandlerChainsModel handlerModel = new HandlerChainsModel(annotatedClass);
325N/A List<HandlerChainType> hChains = handlerModel.getHandlerChain();
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A
325N/A while (reader.getName().equals(QNAME_HANDLER_CHAIN)) {
325N/A HandlerChainType hChain = new HandlerChainType();
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A
325N/A if (reader.getName().equals(QNAME_CHAIN_PORT_PATTERN)) {
325N/A QName portNamePattern = XMLStreamReaderUtil.getElementQName(reader);
325N/A hChain.setPortNamePattern(portNamePattern);
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A } else if (reader.getName().equals(QNAME_CHAIN_PROTOCOL_BINDING)) {
325N/A String bindingList = XMLStreamReaderUtil.getElementText(reader);
325N/A StringTokenizer stk = new StringTokenizer(bindingList);
325N/A while(stk.hasMoreTokens()) {
325N/A String token = stk.nextToken();
325N/A // This will convert tokens into Binding URI
325N/A hChain.addProtocolBinding(token);
325N/A }
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A } else if (reader.getName().equals(QNAME_CHAIN_SERVICE_PATTERN)) {
325N/A QName serviceNamepattern = XMLStreamReaderUtil.getElementQName(reader);
325N/A hChain.setServiceNamePattern(serviceNamepattern);
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A }
325N/A List<HandlerType> handlers = hChain.getHandlers();
325N/A // process all <handler> elements
325N/A while (reader.getName().equals(QNAME_HANDLER)) {
325N/A HandlerType handler = new HandlerType();
325N/A
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A if (reader.getName().equals(QNAME_HANDLER_NAME)) {
325N/A String handlerName =
325N/A XMLStreamReaderUtil.getElementText(reader).trim();
325N/A handler.setHandlerName(handlerName);
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A }
325N/A
325N/A // handler class
325N/A ensureProperName(reader, QNAME_HANDLER_CLASS);
325N/A String handlerClass =
325N/A XMLStreamReaderUtil.getElementText(reader).trim();
325N/A handler.setHandlerClass(handlerClass);
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A
325N/A // init params (ignored)
325N/A while (reader.getName().equals(QNAME_HANDLER_PARAM)) {
325N/A skipInitParamElement(reader);
325N/A }
325N/A
325N/A // headers (ignored)
325N/A while (reader.getName().equals(QNAME_HANDLER_HEADER)) {
325N/A skipTextElement(reader);
325N/A }
325N/A
325N/A // roles (not stored per handler)
325N/A while (reader.getName().equals(QNAME_HANDLER_ROLE)) {
325N/A List<String> soapRoles = handler.getSoapRoles();
325N/A soapRoles.add(XMLStreamReaderUtil.getElementText(reader));
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A }
325N/A
325N/A handlers.add(handler);
325N/A
325N/A // move past </handler>
325N/A ensureProperName(reader, QNAME_HANDLER);
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A }
325N/A
325N/A // move past </handler-chain>
325N/A ensureProperName(reader, QNAME_HANDLER_CHAIN);
325N/A hChains.add(hChain);
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A }
325N/A
325N/A return handlerModel;
325N/A }
325N/A
325N/A /**
325N/A * <p>This method is called internally by HandlerAnnotationProcessor,
325N/A * and by
325N/A * {@link com.sun.xml.internal.ws.transport.http.DeploymentDescriptorParser}
325N/A * directly when it reaches the handler chains element in the
325N/A * descriptor file it is parsing.
325N/A * @param reader should be on <handler-chains> element
325N/A * @return A HandlerAnnotationInfo object that stores the
325N/A * handlers and roles.
325N/A */
325N/A
325N/A
325N/A
325N/A public static HandlerAnnotationInfo parseHandlerFile(XMLStreamReader reader,
325N/A ClassLoader classLoader, QName serviceName, QName portName,
325N/A WSBinding wsbinding) {
325N/A ensureProperName(reader,QNAME_HANDLER_CHAINS);
325N/A String bindingId = wsbinding.getBindingId().toString();
325N/A HandlerAnnotationInfo info = new HandlerAnnotationInfo();
325N/A
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A
325N/A List<Handler> handlerChain = new ArrayList<Handler>();
325N/A Set<String> roles = new HashSet<String>();
325N/A
325N/A while (reader.getName().equals(QNAME_HANDLER_CHAIN)) {
325N/A
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A
325N/A if (reader.getName().equals(QNAME_CHAIN_PORT_PATTERN)) {
325N/A if (portName == null) {
325N/A logger.warning("handler chain sepcified for port " +
325N/A "but port QName passed to parser is null");
325N/A }
325N/A boolean parseChain = JAXWSUtils.matchQNames(portName,
325N/A XMLStreamReaderUtil.getElementQName(reader));
325N/A if (!parseChain) {
325N/A skipChain(reader);
325N/A continue;
325N/A }
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A } else if (reader.getName().equals(QNAME_CHAIN_PROTOCOL_BINDING)) {
325N/A if (bindingId == null) {
325N/A logger.warning("handler chain sepcified for bindingId " +
325N/A "but bindingId passed to parser is null");
325N/A }
325N/A String bindingConstraint = XMLStreamReaderUtil.getElementText(reader);
325N/A boolean skipThisChain = true;
325N/A StringTokenizer stk = new StringTokenizer(bindingConstraint);
325N/A List<String> bindingList = new ArrayList<String>();
325N/A while(stk.hasMoreTokens()) {
325N/A String tokenOrURI = stk.nextToken();
325N/A /*
325N/A Convert short-form tokens to API's binding ids
325N/A Unknown token, Put it as it is
325N/A */
325N/A tokenOrURI = DeploymentDescriptorParser.getBindingIdForToken(tokenOrURI);
325N/A String binding = BindingID.parse(tokenOrURI).toString();
325N/A bindingList.add(binding);
325N/A }
325N/A if(bindingList.contains(bindingId)){
325N/A skipThisChain = false;
325N/A }
325N/A
325N/A if (skipThisChain) {
325N/A skipChain(reader);
325N/A continue;
325N/A }
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A } else if (reader.getName().equals(QNAME_CHAIN_SERVICE_PATTERN)) {
325N/A if (serviceName == null) {
325N/A logger.warning("handler chain sepcified for service " +
325N/A "but service QName passed to parser is null");
325N/A }
325N/A boolean parseChain = JAXWSUtils.matchQNames(
325N/A serviceName,
325N/A XMLStreamReaderUtil.getElementQName(reader));
325N/A if (!parseChain) {
325N/A skipChain(reader);
325N/A continue;
325N/A }
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A }
325N/A
325N/A // process all <handler> elements
325N/A while (reader.getName().equals(QNAME_HANDLER)) {
325N/A Handler handler;
325N/A
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A if (reader.getName().equals(QNAME_HANDLER_NAME)) {
325N/A skipTextElement(reader);
325N/A }
325N/A
325N/A // handler class
325N/A ensureProperName(reader, QNAME_HANDLER_CLASS);
325N/A try {
325N/A handler = (Handler) loadClass(classLoader,
325N/A XMLStreamReaderUtil.getElementText(reader).trim()).newInstance();
325N/A } catch (InstantiationException ie){
325N/A throw new RuntimeException(ie);
325N/A } catch (IllegalAccessException e) {
325N/A throw new RuntimeException(e);
325N/A }
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A
325N/A // init params (ignored)
325N/A while (reader.getName().equals(QNAME_HANDLER_PARAM)) {
325N/A skipInitParamElement(reader);
325N/A }
325N/A
325N/A // headers (ignored)
325N/A while (reader.getName().equals(QNAME_HANDLER_HEADER)) {
325N/A skipTextElement(reader);
325N/A }
325N/A
325N/A // roles (not stored per handler)
325N/A while (reader.getName().equals(QNAME_HANDLER_ROLE)) {
325N/A roles.add(XMLStreamReaderUtil.getElementText(reader));
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A }
325N/A
325N/A // call @PostConstruct method on handler if present
325N/A for (Method method : handler.getClass().getMethods()) {
325N/A if (method.getAnnotation(PostConstruct.class) == null) {
325N/A continue;
325N/A }
325N/A try {
325N/A method.invoke(handler, new Object [0]);
325N/A break;
325N/A } catch (Exception e) {
325N/A throw new RuntimeException(e);
325N/A }
325N/A }
325N/A
325N/A handlerChain.add(handler);
325N/A
325N/A // move past </handler>
325N/A ensureProperName(reader, QNAME_HANDLER);
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A }
325N/A
325N/A // move past </handler-chain>
325N/A ensureProperName(reader, QNAME_HANDLER_CHAIN);
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A }
325N/A
325N/A info.setHandlers(handlerChain);
325N/A info.setRoles(roles);
325N/A return info;
325N/A }
325N/A
325N/A public HandlerAnnotationInfo getHandlersForPortInfo(PortInfo info){
325N/A
325N/A HandlerAnnotationInfo handlerInfo = new HandlerAnnotationInfo();
325N/A List<Handler> handlerClassList = new ArrayList<Handler>();
325N/A Set<String> roles = new HashSet<String>();
325N/A
325N/A for(HandlerChainType hchain : handlerChains) {
325N/A boolean hchainMatched = false;
325N/A if((!hchain.isConstraintSet()) ||
325N/A JAXWSUtils.matchQNames(info.getServiceName(), hchain.getServiceNamePattern()) ||
325N/A JAXWSUtils.matchQNames(info.getPortName(), hchain.getPortNamePattern()) ||
325N/A hchain.getProtocolBindings().contains(info.getBindingID()) ){
325N/A hchainMatched = true;
325N/A
325N/A }
325N/A if(hchainMatched) {
325N/A for(HandlerType handler : hchain.getHandlers()) {
325N/A try {
325N/A Handler handlerClass = (Handler) loadClass(annotatedClass.getClassLoader(),
325N/A handler.getHandlerClass()).newInstance();
325N/A callHandlerPostConstruct(handlerClass);
325N/A handlerClassList.add(handlerClass);
325N/A } catch (InstantiationException ie){
325N/A throw new RuntimeException(ie);
325N/A } catch (IllegalAccessException e) {
325N/A throw new RuntimeException(e);
325N/A }
325N/A
325N/A roles.addAll(handler.getSoapRoles());
325N/A }
325N/A
325N/A }
325N/A }
325N/A
325N/A handlerInfo.setHandlers(handlerClassList);
325N/A handlerInfo.setRoles(roles);
325N/A return handlerInfo;
325N/A
325N/A }
325N/A
325N/A private static Class loadClass(ClassLoader loader, String name) {
325N/A try {
325N/A return Class.forName(name, true, loader);
325N/A } catch (ClassNotFoundException e) {
325N/A throw new UtilException(
325N/A "util.handler.class.not.found",
325N/A name);
325N/A }
325N/A }
325N/A
325N/A private static void callHandlerPostConstruct(Object handlerClass) {
325N/A // call @PostConstruct method on handler if present
325N/A for (Method method : handlerClass.getClass().getMethods()) {
325N/A if (method.getAnnotation(PostConstruct.class) == null) {
325N/A continue;
325N/A }
325N/A try {
325N/A method.invoke(handlerClass, new Object [0]);
325N/A break;
325N/A } catch (Exception e) {
325N/A throw new RuntimeException(e);
325N/A }
325N/A }
325N/A }
325N/A
325N/A private static void skipChain(XMLStreamReader reader) {
325N/A while (XMLStreamReaderUtil.nextContent(reader) !=
325N/A XMLStreamConstants.END_ELEMENT ||
325N/A !reader.getName().equals(QNAME_HANDLER_CHAIN)) {}
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A }
325N/A
325N/A private static void skipTextElement(XMLStreamReader reader) {
325N/A XMLStreamReaderUtil.nextContent(reader);
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A }
325N/A
325N/A private static void skipInitParamElement(XMLStreamReader reader) {
325N/A int state;
325N/A do {
325N/A state = XMLStreamReaderUtil.nextContent(reader);
325N/A } while (state != XMLStreamReader.END_ELEMENT ||
325N/A !reader.getName().equals(QNAME_HANDLER_PARAM));
325N/A XMLStreamReaderUtil.nextElementContent(reader);
325N/A }
325N/A
325N/A private static void ensureProperName(XMLStreamReader reader,
325N/A QName expectedName) {
325N/A
325N/A if (!reader.getName().equals(expectedName)) {
325N/A failWithLocalName("util.parser.wrong.element", reader,
325N/A expectedName.getLocalPart());
325N/A }
325N/A }
325N/A
325N/A static void ensureProperName(XMLStreamReader reader, String expectedName) {
325N/A if (!reader.getLocalName().equals(expectedName)) {
325N/A failWithLocalName("util.parser.wrong.element", reader,
325N/A expectedName);
325N/A }
325N/A }
325N/A
325N/A private static void failWithLocalName(String key,
325N/A XMLStreamReader reader, String arg) {
325N/A throw new UtilException(key,
325N/A Integer.toString(reader.getLocation().getLineNumber()),
325N/A reader.getLocalName(),
325N/A arg );
325N/A }
325N/A
325N/A public static final String PROTOCOL_SOAP11_TOKEN = "##SOAP11_HTTP";
325N/A public static final String PROTOCOL_SOAP12_TOKEN = "##SOAP12_HTTP";
325N/A public static final String PROTOCOL_XML_TOKEN = "##XML_HTTP";
325N/A
325N/A public static final String NS_109 =
325N/A "http://java.sun.com/xml/ns/javaee";
325N/A public static final QName QNAME_CHAIN_PORT_PATTERN =
325N/A new QName(NS_109, "port-name-pattern");
325N/A public static final QName QNAME_CHAIN_PROTOCOL_BINDING =
325N/A new QName(NS_109, "protocol-bindings");
325N/A public static final QName QNAME_CHAIN_SERVICE_PATTERN =
325N/A new QName(NS_109, "service-name-pattern");
325N/A public static final QName QNAME_HANDLER_CHAIN =
325N/A new QName(NS_109, "handler-chain");
325N/A public static final QName QNAME_HANDLER_CHAINS =
325N/A new QName(NS_109, "handler-chains");
325N/A public static final QName QNAME_HANDLER =
325N/A new QName(NS_109, "handler");
325N/A public static final QName QNAME_HANDLER_NAME =
325N/A new QName(NS_109, "handler-name");
325N/A public static final QName QNAME_HANDLER_CLASS =
325N/A new QName(NS_109, "handler-class");
325N/A public static final QName QNAME_HANDLER_PARAM =
325N/A new QName(NS_109, "init-param");
325N/A public static final QName QNAME_HANDLER_PARAM_NAME =
325N/A new QName(NS_109, "param-name");
325N/A public static final QName QNAME_HANDLER_PARAM_VALUE =
325N/A new QName(NS_109, "param-value");
325N/A public static final QName QNAME_HANDLER_HEADER =
325N/A new QName(NS_109, "soap-header");
325N/A public static final QName QNAME_HANDLER_ROLE =
325N/A new QName(NS_109, "soap-role");
325N/A
325N/A static class HandlerChainType {
325N/A //constraints
325N/A QName serviceNamePattern;
325N/A QName portNamePattern;
325N/A List<String> protocolBindings;
325N/A
325N/A // This flag is set if one of the above constraint is set on handler chain
325N/A boolean constraintSet = false;
325N/A
325N/A List<HandlerType> handlers;
325N/A String id;
325N/A
325N/A
325N/A /** Creates a new instance of HandlerChain */
325N/A public HandlerChainType() {
325N/A protocolBindings = new ArrayList<String>();
325N/A }
325N/A
325N/A public void setServiceNamePattern(QName value) {
325N/A this.serviceNamePattern = value;
325N/A constraintSet = true;
325N/A }
325N/A
325N/A public QName getServiceNamePattern() {
325N/A return serviceNamePattern;
325N/A }
325N/A
325N/A public void setPortNamePattern(QName value) {
325N/A this.portNamePattern = value;
325N/A constraintSet = true;
325N/A }
325N/A
325N/A public QName getPortNamePattern() {
325N/A return portNamePattern;
325N/A }
325N/A
325N/A public List<java.lang.String> getProtocolBindings() {
325N/A return this.protocolBindings;
325N/A }
325N/A
325N/A public void addProtocolBinding(String tokenOrURI){
325N/A /*
325N/A Convert short-form tokens to API's binding ids
325N/A Unknown token, Put it as it is
325N/A */
325N/A tokenOrURI = DeploymentDescriptorParser.getBindingIdForToken(tokenOrURI);
325N/A String binding = BindingID.parse(tokenOrURI).toString();
325N/A protocolBindings.add(binding);
325N/A constraintSet = true;
325N/A }
325N/A
325N/A public boolean isConstraintSet() {
325N/A return constraintSet || !protocolBindings.isEmpty();
325N/A }
325N/A public java.lang.String getId() {
325N/A return id;
325N/A }
325N/A
325N/A public void setId(java.lang.String value) {
325N/A this.id = value;
325N/A }
325N/A
325N/A public List<HandlerType> getHandlers() {
325N/A if (handlers == null) {
325N/A handlers = new ArrayList<HandlerType>();
325N/A }
325N/A return this.handlers;
325N/A }
325N/A }
325N/A
325N/A static class HandlerType {
325N/A String handlerName;
325N/A String handlerClass;
325N/A List<String> soapRoles;
325N/A
325N/A java.lang.String id;
325N/A
325N/A /** Creates a new instance of HandlerComponent */
325N/A public HandlerType() {
325N/A }
325N/A
325N/A public String getHandlerName() {
325N/A return handlerName;
325N/A }
325N/A
325N/A public void setHandlerName(String value) {
325N/A this.handlerName = value;
325N/A }
325N/A
325N/A public String getHandlerClass() {
325N/A return handlerClass;
325N/A }
325N/A
325N/A public void setHandlerClass(String value) {
325N/A this.handlerClass = value;
325N/A }
325N/A
325N/A public java.lang.String getId() {
325N/A return id;
325N/A }
325N/A
325N/A public void setId(java.lang.String value) {
325N/A this.id = value;
325N/A }
325N/A
325N/A public List<String> getSoapRoles() {
325N/A if (soapRoles == null) {
325N/A soapRoles = new ArrayList<String>();
325N/A }
325N/A return this.soapRoles;
325N/A }
325N/A }
325N/A}