src/share/jaxws_classes/com/sun/xml/internal/ws/binding/BindingImpl.java

Sun, 15 Dec 2013 23:35:45 +0100

author
mkos
date
Sun, 15 Dec 2013 23:35:45 +0100
changeset 494
2fcd3ddb57a6
parent 368
0989ad8c0860
child 637
9c07ef4934dd
permissions
-rw-r--r--

8025152: Enhance activation set up
8028388: 9 jaxws tests failed in nightly build with java.lang.ClassCastException
Summary: fix also reviewed by Bill Shannon, Alexander Fomin
Reviewed-by: dfuchs, hawtin, mgrebac
Contributed-by: bill.shannon@oracle.com

     1 /*
     2  * Copyright (c) 1997, 2013, 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.binding;
    28 import com.oracle.webservices.internal.api.message.MessageContextFactory;
    29 import com.sun.istack.internal.NotNull;
    30 import com.sun.istack.internal.Nullable;
    31 import com.sun.xml.internal.ws.api.BindingID;
    32 import com.sun.xml.internal.ws.api.SOAPVersion;
    33 import com.sun.xml.internal.ws.api.WSBinding;
    34 import com.sun.xml.internal.ws.api.addressing.AddressingVersion;
    35 import com.sun.xml.internal.ws.api.pipe.Codec;
    36 import com.sun.xml.internal.ws.client.HandlerConfiguration;
    37 import com.sun.xml.internal.ws.developer.MemberSubmissionAddressingFeature;
    38 import com.sun.xml.internal.ws.developer.BindingTypeFeature;
    40 import javax.activation.CommandInfo;
    41 import javax.activation.CommandMap;
    42 import javax.activation.MailcapCommandMap;
    43 import javax.xml.namespace.QName;
    44 import javax.xml.ws.Service;
    45 import javax.xml.ws.WebServiceFeature;
    46 import javax.xml.ws.soap.AddressingFeature;
    47 import javax.xml.ws.handler.Handler;
    48 import java.util.Collections;
    49 import java.util.HashMap;
    50 import java.util.HashSet;
    51 import java.util.List;
    52 import java.util.Set;
    53 import java.util.Map;
    56 /**
    57  * Instances are created by the service, which then
    58  * sets the handler chain on the binding impl.
    59  *
    60  * <p>
    61  * This class is made abstract as we don't see a situation when
    62  * a BindingImpl has much meaning without binding id.
    63  * IOW, for a specific binding there will be a class
    64  * extending BindingImpl, for example SOAPBindingImpl.
    65  *
    66  * <p>
    67  * The spi Binding interface extends Binding.
    68  *
    69  * @author WS Development Team
    70  */
    71 public abstract class BindingImpl implements WSBinding {
    73     protected static final WebServiceFeature[] EMPTY_FEATURES = new WebServiceFeature[0];
    75     //This is reset when ever Binding.setHandlerChain() or SOAPBinding.setRoles() is called.
    76     private HandlerConfiguration handlerConfig;
    77     private final Set<QName> addedHeaders = new HashSet<QName>();
    78     private final Set<QName> knownHeaders = new HashSet<QName>();
    79     private final Set<QName> unmodKnownHeaders = Collections.unmodifiableSet(knownHeaders);
    80     private final BindingID bindingId;
    81     // Features that are set(enabled/disabled) on the binding
    82     protected final WebServiceFeatureList features;
    83     // Features that are set(enabled/disabled) on the binding or an operation
    84     protected final Map<QName, WebServiceFeatureList> operationFeatures = new HashMap<QName, WebServiceFeatureList>();
    85     // Features that are set(enabled/disabled) on the binding, an operation or an input message
    86     protected final Map<QName, WebServiceFeatureList> inputMessageFeatures = new HashMap<QName, WebServiceFeatureList>();
    87     // Features that are set(enabled/disabled) on the binding, an operation or an output message
    88     protected final Map<QName, WebServiceFeatureList> outputMessageFeatures = new HashMap<QName, WebServiceFeatureList>();
    89     // Features that are set(enabled/disabled) on the binding, an operation or a fault message
    90     protected final Map<MessageKey, WebServiceFeatureList> faultMessageFeatures = new HashMap<MessageKey, WebServiceFeatureList>();
    92     protected javax.xml.ws.Service.Mode serviceMode = javax.xml.ws.Service.Mode.PAYLOAD;
    94     protected MessageContextFactory messageContextFactory;
    96     protected BindingImpl(BindingID bindingId, WebServiceFeature ... features) {
    97         this.bindingId = bindingId;
    98         handlerConfig = new HandlerConfiguration(Collections.<String>emptySet(), Collections.<Handler>emptyList());
    99         if (handlerConfig.getHandlerKnownHeaders() != null)
   100             knownHeaders.addAll(handlerConfig.getHandlerKnownHeaders());
   101         this.features = new WebServiceFeatureList(features);
   102         this.features.validate();
   103     }
   105     public
   106     @NotNull
   107     List<Handler> getHandlerChain() {
   108         return handlerConfig.getHandlerChain();
   109     }
   111     public HandlerConfiguration getHandlerConfig() {
   112         return handlerConfig;
   113     }
   115     protected void setHandlerConfig(HandlerConfiguration handlerConfig) {
   116         this.handlerConfig = handlerConfig;
   117         knownHeaders.clear();
   118         knownHeaders.addAll(addedHeaders);
   119         if (handlerConfig != null && handlerConfig.getHandlerKnownHeaders() != null)
   120             knownHeaders.addAll(handlerConfig.getHandlerKnownHeaders());
   121     }
   123     public void setMode(@NotNull Service.Mode mode) {
   124         this.serviceMode = mode;
   125     }
   127     public Set<QName> getKnownHeaders() {
   128         return unmodKnownHeaders;
   129     }
   131     public boolean addKnownHeader(QName headerQName) {
   132         addedHeaders.add(headerQName);
   133         return knownHeaders.add(headerQName);
   134     }
   136     public
   137     @NotNull
   138     BindingID getBindingId() {
   139         return bindingId;
   140     }
   142     public final SOAPVersion getSOAPVersion() {
   143         return bindingId.getSOAPVersion();
   144     }
   146     public AddressingVersion getAddressingVersion() {
   147         AddressingVersion addressingVersion;
   148         if (features.isEnabled(AddressingFeature.class))
   149             addressingVersion = AddressingVersion.W3C;
   150         else if (features.isEnabled(MemberSubmissionAddressingFeature.class))
   151             addressingVersion = AddressingVersion.MEMBER;
   152         else
   153             addressingVersion = null;
   154         return addressingVersion;
   155     }
   157     @NotNull
   158     public final Codec createCodec() {
   160         // initialization from here should cover most of cases;
   161         // if not, it would be necessary to call
   162         //   BindingImpl.initializeJavaActivationHandlers()
   163         // explicitly by programmer
   164         initializeJavaActivationHandlers();
   166         return bindingId.createEncoder(this);
   167     }
   169     public static void initializeJavaActivationHandlers() {
   170         // DataHandler.writeTo() may search for DCH. So adding some default ones.
   171         try {
   172             CommandMap map = CommandMap.getDefaultCommandMap();
   173             if (map instanceof MailcapCommandMap) {
   174                 MailcapCommandMap mailMap = (MailcapCommandMap) map;
   176                 // registering our DCH since javamail's DCH doesn't handle
   177                 if (!cmdMapInitialized(mailMap)) {
   178                     mailMap.addMailcap("text/xml;;x-java-content-handler=com.sun.xml.internal.ws.encoding.XmlDataContentHandler");
   179                     mailMap.addMailcap("application/xml;;x-java-content-handler=com.sun.xml.internal.ws.encoding.XmlDataContentHandler");
   180                     mailMap.addMailcap("image/*;;x-java-content-handler=com.sun.xml.internal.ws.encoding.ImageDataContentHandler");
   181                     mailMap.addMailcap("text/plain;;x-java-content-handler=com.sun.xml.internal.ws.encoding.StringDataContentHandler");
   182                 }
   183             }
   184         } catch (Throwable t) {
   185             // ignore the exception.
   186         }
   187     }
   189     private static boolean cmdMapInitialized(MailcapCommandMap mailMap) {
   190         CommandInfo[] commands = mailMap.getAllCommands("text/xml");
   191         if (commands == null || commands.length == 0) {
   192             return false;
   193         }
   195         // SAAJ RI implements it's own DataHandlers which can be used for JAX-WS too;
   196         // see com.sun.xml.internal.messaging.saaj.soap.AttachmentPartImpl#initializeJavaActivationHandlers
   197         // so if found any of SAAJ or our own handler registered, we are ok; anyway using SAAJ directly here
   198         // is not good idea since we don't want standalone JAX-WS to depend on specific SAAJ impl.
   199         // This is also reason for duplication of Handler's code by JAX-WS
   200         String saajClassName = "com.sun.xml.internal.messaging.saaj.soap.XmlDataContentHandler";
   201         String jaxwsClassName = "com.sun.xml.internal.ws.encoding.XmlDataContentHandler";
   202         for (CommandInfo command : commands) {
   203             String commandClass = command.getCommandClass();
   204             if (saajClassName.equals(commandClass) ||
   205                     jaxwsClassName.equals(commandClass)) {
   206                 return true;
   207             }
   208         }
   209         return false;
   210     }
   212     public static BindingImpl create(@NotNull BindingID bindingId) {
   213         if (bindingId.equals(BindingID.XML_HTTP))
   214             return new HTTPBindingImpl();
   215         else
   216             return new SOAPBindingImpl(bindingId);
   217     }
   219     public static BindingImpl create(@NotNull BindingID bindingId, WebServiceFeature[] features) {
   220         // Override the BindingID from the features
   221         for(WebServiceFeature feature : features) {
   222             if (feature instanceof BindingTypeFeature) {
   223                 BindingTypeFeature f = (BindingTypeFeature)feature;
   224                 bindingId = BindingID.parse(f.getBindingId());
   225             }
   226         }
   227         if (bindingId.equals(BindingID.XML_HTTP))
   228             return new HTTPBindingImpl(features);
   229         else
   230             return new SOAPBindingImpl(bindingId, features);
   231     }
   233     public static WSBinding getDefaultBinding() {
   234         return new SOAPBindingImpl(BindingID.SOAP11_HTTP);
   235     }
   237     public String getBindingID() {
   238         return bindingId.toString();
   239     }
   241     public @Nullable <F extends WebServiceFeature> F getFeature(@NotNull Class<F> featureType){
   242         return features.get(featureType);
   243     }
   245     public @Nullable <F extends WebServiceFeature> F getOperationFeature(@NotNull Class<F> featureType,
   246             @NotNull final QName operationName) {
   247         final WebServiceFeatureList operationFeatureList = this.operationFeatures.get(operationName);
   248         return FeatureListUtil.mergeFeature(featureType, operationFeatureList, features);
   249     }
   251     public boolean isFeatureEnabled(@NotNull Class<? extends WebServiceFeature> feature){
   252         return features.isEnabled(feature);
   253     }
   255     public boolean isOperationFeatureEnabled(@NotNull Class<? extends WebServiceFeature> featureType,
   256             @NotNull final QName operationName) {
   257         final WebServiceFeatureList operationFeatureList = this.operationFeatures.get(operationName);
   258         return FeatureListUtil.isFeatureEnabled(featureType, operationFeatureList, features);
   259     }
   261     @NotNull
   262     public WebServiceFeatureList getFeatures() {
   263         //TODO scchen convert BindingID  to WebServiceFeature[]
   264         if(!isFeatureEnabled(com.oracle.webservices.internal.api.EnvelopeStyleFeature.class)) {
   265             WebServiceFeature[] f = { getSOAPVersion().toFeature() };
   266             features.mergeFeatures(f, false);
   267         }
   268         return features;
   269     }
   271     public @NotNull WebServiceFeatureList getOperationFeatures(@NotNull final QName operationName) {
   272         final WebServiceFeatureList operationFeatureList = this.operationFeatures.get(operationName);
   273         return FeatureListUtil.mergeList(operationFeatureList, features);
   274     }
   276     public @NotNull WebServiceFeatureList getInputMessageFeatures(@NotNull final QName operationName) {
   277         final WebServiceFeatureList operationFeatureList = this.operationFeatures.get(operationName);
   278         final WebServiceFeatureList messageFeatureList = this.inputMessageFeatures.get(operationName);
   279         return FeatureListUtil.mergeList(operationFeatureList, messageFeatureList, features);
   281     }
   283     public @NotNull WebServiceFeatureList getOutputMessageFeatures(@NotNull final QName operationName) {
   284         final WebServiceFeatureList operationFeatureList = this.operationFeatures.get(operationName);
   285         final WebServiceFeatureList messageFeatureList = this.outputMessageFeatures.get(operationName);
   286         return FeatureListUtil.mergeList(operationFeatureList, messageFeatureList, features);
   287     }
   289     public @NotNull WebServiceFeatureList getFaultMessageFeatures(@NotNull final QName operationName,
   290             @NotNull final QName messageName) {
   291         final WebServiceFeatureList operationFeatureList = this.operationFeatures.get(operationName);
   292         final WebServiceFeatureList messageFeatureList = this.faultMessageFeatures.get(
   293                 new MessageKey(operationName, messageName));
   294         return FeatureListUtil.mergeList(operationFeatureList, messageFeatureList, features);
   295     }
   297     public void setOperationFeatures(@NotNull final QName operationName, WebServiceFeature... newFeatures) {
   298         if (newFeatures != null) {
   299             WebServiceFeatureList featureList = operationFeatures.get(operationName);
   300             if (featureList == null) {
   301                 featureList = new WebServiceFeatureList();
   302             }
   303             for (WebServiceFeature f : newFeatures) {
   304                 featureList.add(f);
   305             }
   306             operationFeatures.put(operationName, featureList);
   307         }
   308     }
   310     public void setInputMessageFeatures(@NotNull final QName operationName, WebServiceFeature... newFeatures) {
   311         if (newFeatures != null) {
   312             WebServiceFeatureList featureList = inputMessageFeatures.get(operationName);
   313             if (featureList == null) {
   314                 featureList = new WebServiceFeatureList();
   315             }
   316             for (WebServiceFeature f : newFeatures) {
   317                 featureList.add(f);
   318             }
   319             inputMessageFeatures.put(operationName, featureList);
   320         }
   321     }
   323     public void setOutputMessageFeatures(@NotNull final QName operationName, WebServiceFeature... newFeatures) {
   324         if (newFeatures != null) {
   325             WebServiceFeatureList featureList = outputMessageFeatures.get(operationName);
   326             if (featureList == null) {
   327                 featureList = new WebServiceFeatureList();
   328             }
   329             for (WebServiceFeature f : newFeatures) {
   330                 featureList.add(f);
   331             }
   332             outputMessageFeatures.put(operationName, featureList);
   333         }
   334     }
   336     public void setFaultMessageFeatures(@NotNull final QName operationName, @NotNull final QName messageName, WebServiceFeature... newFeatures) {
   337         if (newFeatures != null) {
   338             final MessageKey key = new MessageKey(operationName, messageName);
   339             WebServiceFeatureList featureList = faultMessageFeatures.get(key);
   340             if (featureList == null) {
   341                 featureList = new WebServiceFeatureList();
   342             }
   343             for (WebServiceFeature f : newFeatures) {
   344                 featureList.add(f);
   345             }
   346             faultMessageFeatures.put(key, featureList);
   347         }
   348     }
   350     public synchronized @NotNull com.oracle.webservices.internal.api.message.MessageContextFactory getMessageContextFactory () {
   351         if (messageContextFactory == null) {
   352             messageContextFactory = MessageContextFactory.createFactory(getFeatures().toArray());
   353         }
   354         return messageContextFactory;
   355     }
   357     /**
   358      * Experimental: Identify messages based on the name of the message and the
   359      * operation that uses this message.
   360      */
   361     protected static class MessageKey {
   363         final private QName operationName;
   364         final private QName messageName;
   366         public MessageKey(final QName operationName, final QName messageName) {
   367             this.operationName = operationName;
   368             this.messageName = messageName;
   369         }
   371         @Override
   372         public int hashCode() {
   373             final int hashFirst = this.operationName != null ? this.operationName.hashCode() : 0;
   374             final int hashSecond = this.messageName != null ? this.messageName.hashCode() : 0;
   376             return (hashFirst + hashSecond) * hashSecond + hashFirst;
   377         }
   379         @Override
   380         public boolean equals(Object obj) {
   381             if (obj == null) {
   382                 return false;
   383             }
   384             if (getClass() != obj.getClass()) {
   385                 return false;
   386             }
   387             final MessageKey other = (MessageKey) obj;
   388             if (this.operationName != other.operationName && (this.operationName == null || !this.operationName.equals(other.operationName))) {
   389                 return false;
   390             }
   391             if (this.messageName != other.messageName && (this.messageName == null || !this.messageName.equals(other.messageName))) {
   392                 return false;
   393             }
   394             return true;
   395         }
   397         @Override
   398         public String toString() {
   399            return "(" + this.operationName + ", " + this.messageName + ")";
   400         }
   402     }
   404 }

mercurial