src/share/jaxws_classes/com/sun/xml/internal/ws/handler/HandlerChainsModel.java

Thu, 12 Oct 2017 19:44:07 +0800

author
aoqi
date
Thu, 12 Oct 2017 19:44:07 +0800
changeset 760
e530533619ec
parent 637
9c07ef4934dd
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.ws.handler;
    28 import com.sun.xml.internal.ws.api.BindingID;
    29 import com.sun.xml.internal.ws.api.WSBinding;
    30 import com.sun.xml.internal.ws.streaming.XMLStreamReaderUtil;
    31 import com.sun.xml.internal.ws.transport.http.DeploymentDescriptorParser;
    32 import com.sun.xml.internal.ws.util.HandlerAnnotationInfo;
    33 import com.sun.xml.internal.ws.util.JAXWSUtils;
    34 import com.sun.xml.internal.ws.util.UtilException;
    36 import javax.annotation.PostConstruct;
    37 import javax.xml.namespace.QName;
    38 import javax.xml.stream.XMLStreamConstants;
    39 import javax.xml.stream.XMLStreamReader;
    40 import javax.xml.ws.handler.Handler;
    41 import javax.xml.ws.handler.PortInfo;
    42 import java.lang.reflect.Method;
    43 import java.util.ArrayList;
    44 import java.util.HashSet;
    45 import java.util.List;
    46 import java.util.Set;
    47 import java.util.StringTokenizer;
    48 import java.util.logging.Logger;
    51 public class HandlerChainsModel {
    52     private static final Logger logger = Logger.getLogger(
    53             com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".util");
    55     private Class annotatedClass;
    56     private List<HandlerChainType> handlerChains;
    57     private String id;
    58     /** Creates a new instance of HandlerChains */
    59     private HandlerChainsModel(Class annotatedClass) {
    60         this.annotatedClass = annotatedClass;
    61     }
    63     private List<HandlerChainType> getHandlerChain() {
    64         if (handlerChains == null) {
    65             handlerChains = new ArrayList<HandlerChainType>();
    66         }
    67         return handlerChains;
    68     }
    70     public String getId() {
    71         return id;
    72     }
    74     public void setId(String value) {
    75         this.id = value;
    76     }
    77     /**
    78      * reader should be on <handler-chains> element
    79      */
    80     public static HandlerChainsModel parseHandlerConfigFile(Class annotatedClass, XMLStreamReader reader) {
    81         ensureProperName(reader,QNAME_HANDLER_CHAINS);
    82         HandlerChainsModel handlerModel = new HandlerChainsModel(annotatedClass);
    83         List<HandlerChainType> hChains = handlerModel.getHandlerChain();
    84         XMLStreamReaderUtil.nextElementContent(reader);
    86         while (reader.getName().equals(QNAME_HANDLER_CHAIN)) {
    87             HandlerChainType hChain = new HandlerChainType();
    88             XMLStreamReaderUtil.nextElementContent(reader);
    90             if (reader.getName().equals(QNAME_CHAIN_PORT_PATTERN)) {
    91                 QName portNamePattern = XMLStreamReaderUtil.getElementQName(reader);
    92                 hChain.setPortNamePattern(portNamePattern);
    93                 XMLStreamReaderUtil.nextElementContent(reader);
    94             } else if (reader.getName().equals(QNAME_CHAIN_PROTOCOL_BINDING)) {
    95                 String bindingList = XMLStreamReaderUtil.getElementText(reader);
    96                 StringTokenizer stk = new StringTokenizer(bindingList);
    97                 while(stk.hasMoreTokens()) {
    98                     String token = stk.nextToken();
    99                     // This will convert tokens into Binding URI
   100                     hChain.addProtocolBinding(token);
   101                 }
   102                 XMLStreamReaderUtil.nextElementContent(reader);
   103             } else if (reader.getName().equals(QNAME_CHAIN_SERVICE_PATTERN)) {
   104                 QName serviceNamepattern = XMLStreamReaderUtil.getElementQName(reader);
   105                 hChain.setServiceNamePattern(serviceNamepattern);
   106                 XMLStreamReaderUtil.nextElementContent(reader);
   107             }
   108             List<HandlerType> handlers = hChain.getHandlers();
   109             // process all <handler> elements
   110             while (reader.getName().equals(QNAME_HANDLER)) {
   111                 HandlerType handler = new HandlerType();
   113                 XMLStreamReaderUtil.nextContent(reader);
   114                 if (reader.getName().equals(QNAME_HANDLER_NAME)) {
   115                     String handlerName =
   116                             XMLStreamReaderUtil.getElementText(reader).trim();
   117                     handler.setHandlerName(handlerName);
   118                     XMLStreamReaderUtil.nextContent(reader);
   119                 }
   121                 // handler class
   122                 ensureProperName(reader, QNAME_HANDLER_CLASS);
   123                 String handlerClass =
   124                         XMLStreamReaderUtil.getElementText(reader).trim();
   125                 handler.setHandlerClass(handlerClass);
   126                 XMLStreamReaderUtil.nextContent(reader);
   128                 // init params (ignored)
   129                 while (reader.getName().equals(QNAME_HANDLER_PARAM)) {
   130                     skipInitParamElement(reader);
   131                 }
   133                 // headers (ignored)
   134                 while (reader.getName().equals(QNAME_HANDLER_HEADER)) {
   135                     skipTextElement(reader);
   136                 }
   138                 // roles (not stored per handler)
   139                 while (reader.getName().equals(QNAME_HANDLER_ROLE)) {
   140                     List<String> soapRoles = handler.getSoapRoles();
   141                     soapRoles.add(XMLStreamReaderUtil.getElementText(reader));
   142                     XMLStreamReaderUtil.nextContent(reader);
   143                 }
   145                 handlers.add(handler);
   147                 // move past </handler>
   148                 ensureProperName(reader, QNAME_HANDLER);
   149                 XMLStreamReaderUtil.nextContent(reader);
   150             }
   152             // move past </handler-chain>
   153             ensureProperName(reader, QNAME_HANDLER_CHAIN);
   154             hChains.add(hChain);
   155             XMLStreamReaderUtil.nextContent(reader);
   156         }
   158         return handlerModel;
   159     }
   161     /**
   162      * <p>This method is called internally by HandlerAnnotationProcessor,
   163      * and by
   164      * {@link com.sun.xml.internal.ws.transport.http.DeploymentDescriptorParser}
   165      * directly when it reaches the handler chains element in the
   166      * descriptor file it is parsing.
   167      * @param reader should be on <handler-chains> element
   168      * @return A HandlerAnnotationInfo object that stores the
   169      * handlers and roles.
   170      */
   174     public static HandlerAnnotationInfo parseHandlerFile(XMLStreamReader reader,
   175             ClassLoader classLoader, QName serviceName, QName portName,
   176             WSBinding wsbinding) {
   177         ensureProperName(reader,QNAME_HANDLER_CHAINS);
   178         String bindingId = wsbinding.getBindingId().toString();
   179         HandlerAnnotationInfo info = new HandlerAnnotationInfo();
   181         XMLStreamReaderUtil.nextElementContent(reader);
   183         List<Handler> handlerChain = new ArrayList<Handler>();
   184         Set<String> roles = new HashSet<String>();
   186         while (reader.getName().equals(QNAME_HANDLER_CHAIN)) {
   188             XMLStreamReaderUtil.nextElementContent(reader);
   190             if (reader.getName().equals(QNAME_CHAIN_PORT_PATTERN)) {
   191                 if (portName == null) {
   192                     logger.warning("handler chain sepcified for port " +
   193                             "but port QName passed to parser is null");
   194                 }
   195                 boolean parseChain = JAXWSUtils.matchQNames(portName,
   196                         XMLStreamReaderUtil.getElementQName(reader));
   197                 if (!parseChain) {
   198                     skipChain(reader);
   199                     continue;
   200                 }
   201                 XMLStreamReaderUtil.nextElementContent(reader);
   202             } else if (reader.getName().equals(QNAME_CHAIN_PROTOCOL_BINDING)) {
   203                 if (bindingId == null) {
   204                     logger.warning("handler chain sepcified for bindingId " +
   205                             "but bindingId passed to parser is null");
   206                 }
   207                 String bindingConstraint = XMLStreamReaderUtil.getElementText(reader);
   208                 boolean skipThisChain = true;
   209                 StringTokenizer stk = new StringTokenizer(bindingConstraint);
   210                 List<String> bindingList = new ArrayList<String>();
   211                 while(stk.hasMoreTokens()) {
   212                     String tokenOrURI = stk.nextToken();
   213                     /*
   214                     Convert short-form tokens to API's binding ids
   215                     Unknown token, Put it as it is
   216                     */
   217                     tokenOrURI = DeploymentDescriptorParser.getBindingIdForToken(tokenOrURI);
   218                     String binding = BindingID.parse(tokenOrURI).toString();
   219                     bindingList.add(binding);
   220                 }
   221                 if(bindingList.contains(bindingId)){
   222                     skipThisChain = false;
   223                 }
   225                 if (skipThisChain) {
   226                     skipChain(reader);
   227                     continue;
   228                 }
   229                 XMLStreamReaderUtil.nextElementContent(reader);
   230             } else if (reader.getName().equals(QNAME_CHAIN_SERVICE_PATTERN)) {
   231                 if (serviceName == null) {
   232                     logger.warning("handler chain sepcified for service " +
   233                             "but service QName passed to parser is null");
   234                 }
   235                 boolean parseChain = JAXWSUtils.matchQNames(
   236                         serviceName,
   237                         XMLStreamReaderUtil.getElementQName(reader));
   238                 if (!parseChain) {
   239                     skipChain(reader);
   240                     continue;
   241                 }
   242                 XMLStreamReaderUtil.nextElementContent(reader);
   243             }
   245             // process all <handler> elements
   246             while (reader.getName().equals(QNAME_HANDLER)) {
   247                 Handler handler;
   249                 XMLStreamReaderUtil.nextContent(reader);
   250                 if (reader.getName().equals(QNAME_HANDLER_NAME)) {
   251                     skipTextElement(reader);
   252                 }
   254                 // handler class
   255                 ensureProperName(reader, QNAME_HANDLER_CLASS);
   256                 try {
   257                     handler = (Handler) loadClass(classLoader,
   258                             XMLStreamReaderUtil.getElementText(reader).trim()).newInstance();
   259                 } catch (InstantiationException ie){
   260                     throw new RuntimeException(ie);
   261                 } catch (IllegalAccessException e) {
   262                     throw new RuntimeException(e);
   263                 }
   264                 XMLStreamReaderUtil.nextContent(reader);
   266                 // init params (ignored)
   267                 while (reader.getName().equals(QNAME_HANDLER_PARAM)) {
   268                     skipInitParamElement(reader);
   269                 }
   271                 // headers (ignored)
   272                 while (reader.getName().equals(QNAME_HANDLER_HEADER)) {
   273                     skipTextElement(reader);
   274                 }
   276                 // roles (not stored per handler)
   277                 while (reader.getName().equals(QNAME_HANDLER_ROLE)) {
   278                     roles.add(XMLStreamReaderUtil.getElementText(reader));
   279                     XMLStreamReaderUtil.nextContent(reader);
   280                 }
   282                 // call @PostConstruct method on handler if present
   283                 for (Method method : handler.getClass().getMethods()) {
   284                     if (method.getAnnotation(PostConstruct.class) == null) {
   285                         continue;
   286                     }
   287                     try {
   288                         method.invoke(handler, new Object [0]);
   289                         break;
   290                     } catch (Exception e) {
   291                         throw new RuntimeException(e);
   292                     }
   293                 }
   295                 handlerChain.add(handler);
   297                 // move past </handler>
   298                 ensureProperName(reader, QNAME_HANDLER);
   299                 XMLStreamReaderUtil.nextContent(reader);
   300             }
   302             // move past </handler-chain>
   303             ensureProperName(reader, QNAME_HANDLER_CHAIN);
   304             XMLStreamReaderUtil.nextContent(reader);
   305         }
   307         info.setHandlers(handlerChain);
   308         info.setRoles(roles);
   309         return info;
   310     }
   312     public HandlerAnnotationInfo getHandlersForPortInfo(PortInfo info){
   314         HandlerAnnotationInfo handlerInfo = new HandlerAnnotationInfo();
   315         List<Handler> handlerClassList = new ArrayList<Handler>();
   316         Set<String> roles = new HashSet<String>();
   318         for(HandlerChainType hchain : handlerChains) {
   319             boolean hchainMatched = false;
   320             if((!hchain.isConstraintSet()) ||
   321                     JAXWSUtils.matchQNames(info.getServiceName(), hchain.getServiceNamePattern()) ||
   322                     JAXWSUtils.matchQNames(info.getPortName(), hchain.getPortNamePattern()) ||
   323                     hchain.getProtocolBindings().contains(info.getBindingID()) ){
   324                 hchainMatched = true;
   326             }
   327             if(hchainMatched) {
   328                 for(HandlerType handler : hchain.getHandlers()) {
   329                     try {
   330                         Handler handlerClass = (Handler) loadClass(annotatedClass.getClassLoader(),
   331                                 handler.getHandlerClass()).newInstance();
   332                         callHandlerPostConstruct(handlerClass);
   333                         handlerClassList.add(handlerClass);
   334                     } catch (InstantiationException ie){
   335                         throw new RuntimeException(ie);
   336                     } catch (IllegalAccessException e) {
   337                         throw new RuntimeException(e);
   338                     }
   340                     roles.addAll(handler.getSoapRoles());
   341                 }
   343             }
   344         }
   346         handlerInfo.setHandlers(handlerClassList);
   347         handlerInfo.setRoles(roles);
   348         return handlerInfo;
   350     }
   352     private static Class loadClass(ClassLoader loader, String name) {
   353         try {
   354             return Class.forName(name, true, loader);
   355         } catch (ClassNotFoundException e) {
   356             throw new UtilException(
   357                     "util.handler.class.not.found",
   358                     name);
   359         }
   360     }
   362     private static void callHandlerPostConstruct(Object handlerClass) {
   363         // call @PostConstruct method on handler if present
   364         for (Method method : handlerClass.getClass().getMethods()) {
   365             if (method.getAnnotation(PostConstruct.class) == null) {
   366                 continue;
   367             }
   368             try {
   369                 method.invoke(handlerClass, new Object [0]);
   370                 break;
   371             } catch (Exception e) {
   372                 throw new RuntimeException(e);
   373             }
   374         }
   375     }
   377     private static void skipChain(XMLStreamReader reader) {
   378         while (XMLStreamReaderUtil.nextContent(reader) !=
   379                 XMLStreamConstants.END_ELEMENT ||
   380                 !reader.getName().equals(QNAME_HANDLER_CHAIN)) {}
   381         XMLStreamReaderUtil.nextElementContent(reader);
   382     }
   384     private static void skipTextElement(XMLStreamReader reader) {
   385         XMLStreamReaderUtil.nextContent(reader);
   386         XMLStreamReaderUtil.nextElementContent(reader);
   387         XMLStreamReaderUtil.nextElementContent(reader);
   388     }
   390     private static void skipInitParamElement(XMLStreamReader reader) {
   391         int state;
   392         do {
   393             state = XMLStreamReaderUtil.nextContent(reader);
   394         } while (state != XMLStreamReader.END_ELEMENT ||
   395                 !reader.getName().equals(QNAME_HANDLER_PARAM));
   396         XMLStreamReaderUtil.nextElementContent(reader);
   397     }
   399     private static void ensureProperName(XMLStreamReader reader,
   400             QName expectedName) {
   402         if (!reader.getName().equals(expectedName)) {
   403             failWithLocalName("util.parser.wrong.element", reader,
   404                     expectedName.getLocalPart());
   405         }
   406     }
   408     static void ensureProperName(XMLStreamReader reader, String expectedName) {
   409         if (!reader.getLocalName().equals(expectedName)) {
   410             failWithLocalName("util.parser.wrong.element", reader,
   411                     expectedName);
   412         }
   413     }
   415     private static void failWithLocalName(String key,
   416             XMLStreamReader reader, String arg) {
   417         throw new UtilException(key,
   418             Integer.toString(reader.getLocation().getLineNumber()),
   419             reader.getLocalName(),
   420             arg );
   421     }
   423     public static final String PROTOCOL_SOAP11_TOKEN = "##SOAP11_HTTP";
   424     public static final String PROTOCOL_SOAP12_TOKEN = "##SOAP12_HTTP";
   425     public static final String PROTOCOL_XML_TOKEN = "##XML_HTTP";
   427     public static final String NS_109 =
   428             "http://java.sun.com/xml/ns/javaee";
   429     public static final QName QNAME_CHAIN_PORT_PATTERN =
   430             new QName(NS_109, "port-name-pattern");
   431     public static final QName QNAME_CHAIN_PROTOCOL_BINDING =
   432             new QName(NS_109, "protocol-bindings");
   433     public static final QName QNAME_CHAIN_SERVICE_PATTERN =
   434             new QName(NS_109, "service-name-pattern");
   435     public static final QName QNAME_HANDLER_CHAIN =
   436             new QName(NS_109, "handler-chain");
   437     public static final QName QNAME_HANDLER_CHAINS =
   438             new QName(NS_109, "handler-chains");
   439     public static final QName QNAME_HANDLER =
   440             new QName(NS_109, "handler");
   441     public static final QName QNAME_HANDLER_NAME =
   442             new QName(NS_109, "handler-name");
   443     public static final QName QNAME_HANDLER_CLASS =
   444             new QName(NS_109, "handler-class");
   445     public static final QName QNAME_HANDLER_PARAM =
   446             new QName(NS_109, "init-param");
   447     public static final QName QNAME_HANDLER_PARAM_NAME =
   448             new QName(NS_109, "param-name");
   449     public static final QName QNAME_HANDLER_PARAM_VALUE =
   450             new QName(NS_109, "param-value");
   451     public static final QName QNAME_HANDLER_HEADER =
   452             new QName(NS_109, "soap-header");
   453     public static final QName QNAME_HANDLER_ROLE =
   454             new QName(NS_109, "soap-role");
   456     static class HandlerChainType {
   457         //constraints
   458         QName serviceNamePattern;
   459         QName portNamePattern;
   460         List<String> protocolBindings;
   462         // This flag is set if one of the above constraint is set on handler chain
   463         boolean constraintSet = false;
   465         List<HandlerType> handlers;
   466         String id;
   469         /** Creates a new instance of HandlerChain */
   470         public HandlerChainType() {
   471             protocolBindings = new ArrayList<String>();
   472         }
   474         public void setServiceNamePattern(QName value) {
   475             this.serviceNamePattern = value;
   476             constraintSet = true;
   477         }
   479         public QName getServiceNamePattern() {
   480             return serviceNamePattern;
   481         }
   483         public void setPortNamePattern(QName value) {
   484             this.portNamePattern = value;
   485             constraintSet = true;
   486         }
   488         public QName getPortNamePattern() {
   489             return portNamePattern;
   490         }
   492         public List<java.lang.String> getProtocolBindings() {
   493             return this.protocolBindings;
   494         }
   496         public void addProtocolBinding(String tokenOrURI){
   497             /*
   498             Convert short-form tokens to API's binding ids
   499             Unknown token, Put it as it is
   500             */
   501             tokenOrURI = DeploymentDescriptorParser.getBindingIdForToken(tokenOrURI);
   502             String binding = BindingID.parse(tokenOrURI).toString();
   503             protocolBindings.add(binding);
   504             constraintSet = true;
   505         }
   507         public boolean isConstraintSet() {
   508             return constraintSet || !protocolBindings.isEmpty();
   509         }
   510         public java.lang.String getId() {
   511             return id;
   512         }
   514         public void setId(java.lang.String value) {
   515             this.id = value;
   516         }
   518         public List<HandlerType> getHandlers() {
   519             if (handlers == null) {
   520                 handlers = new ArrayList<HandlerType>();
   521             }
   522             return this.handlers;
   523         }
   524     }
   526     static class HandlerType {
   527         String handlerName;
   528         String handlerClass;
   529         List<String> soapRoles;
   531         java.lang.String id;
   533         /** Creates a new instance of HandlerComponent */
   534         public HandlerType() {
   535         }
   537         public String getHandlerName() {
   538             return handlerName;
   539         }
   541         public void setHandlerName(String value) {
   542             this.handlerName = value;
   543         }
   545         public String getHandlerClass() {
   546             return handlerClass;
   547         }
   549         public void setHandlerClass(String value) {
   550             this.handlerClass = value;
   551         }
   553         public java.lang.String getId() {
   554             return id;
   555         }
   557         public void setId(java.lang.String value) {
   558             this.id = value;
   559         }
   561         public List<String> getSoapRoles() {
   562             if (soapRoles == null) {
   563                 soapRoles = new ArrayList<String>();
   564             }
   565             return this.soapRoles;
   566         }
   567     }
   568 }

mercurial