All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.xml.ws.api.BindingID Maven / Gradle / Ivy

There is a newer version: 4.0.3
Show newest version
/*
 * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.xml.ws.api;

import com.sun.istack.NotNull;
import com.sun.xml.ws.api.message.Message;
import com.sun.xml.ws.api.pipe.Codec;
import com.sun.xml.ws.api.pipe.Tube;
import com.sun.xml.ws.binding.BindingImpl;
import com.sun.xml.ws.binding.SOAPBindingImpl;
import com.sun.xml.ws.binding.WebServiceFeatureList;
import com.sun.xml.ws.encoding.SOAPBindingCodec;
import com.sun.xml.ws.encoding.XMLHTTPBindingCodec;
import com.sun.xml.ws.encoding.soap.streaming.SOAPNamespaceConstants;
import com.sun.xml.ws.util.ServiceFinder;
import com.sun.xml.ws.developer.JAXWSProperties;

import jakarta.xml.ws.BindingType;
import jakarta.xml.ws.WebServiceException;
import jakarta.xml.ws.WebServiceFeature;
import jakarta.xml.ws.handler.Handler;
import jakarta.xml.ws.http.HTTPBinding;
import jakarta.xml.ws.soap.MTOMFeature;
import jakarta.xml.ws.soap.SOAPBinding;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * Parsed binding ID string.
 *
 * 

* {@link BindingID} is an immutable object that represents a binding ID, * much like how {@link URL} is a representation of an URL. * Like {@link URL}, this class offers a bunch of methods that let you * query various traits/properties of a binding ID. * *

* {@link BindingID} is extensible; one can plug in a parser from * {@link String} to {@link BindingID} to interpret binding IDs that * the JAX-WS RI does no a-priori knowledge of. * Technologies such as Tango uses this to make the JAX-WS RI understand * binding IDs defined in their world. * * Such technologies are free to extend this class and expose more characterstics. * *

* Even though this class defines a few well known constants, {@link BindingID} * instances do not necessarily have singleton semantics. Use {@link #equals(Object)} * for the comparison. * *

{@link BindingID} and {@link WSBinding}

*

* {@link WSBinding} is mutable and represents a particular "use" of a {@link BindingID}. * As such, it has state like a list of {@link Handler}s, which are inherently local * to a particular usage. For example, if you have two proxies, you need two instances. * * {@link BindingID}, OTOH, is immutable and thus the single instance * that represents "SOAP1.2/HTTP" can be shared and reused by all proxies in the same VM. * * @author Kohsuke Kawaguchi */ public abstract class BindingID { /** * Creates an instance of {@link WSBinding} (which is conceptually an "use" * of {@link BindingID}) from a {@link BindingID}. * * @return * Always a new instance. */ public final @NotNull WSBinding createBinding() { return BindingImpl.create(this); } /** * Returns wsdl:binding@transport attribute. Sub classes * are expected to override this method to provide their transport * attribute. * * @return wsdl:binding@transport attribute * @since JAX-WS RI 2.1.6 */ public @NotNull String getTransport() { return SOAPNamespaceConstants.TRANSPORT_HTTP; } public final @NotNull WSBinding createBinding(WebServiceFeature... features) { return BindingImpl.create(this, features); } public final @NotNull WSBinding createBinding(WSFeatureList features) { return createBinding(features.toArray()); } /** * Gets the SOAP version of this binding. * * TODO: clarify what to do with XML/HTTP binding * * @return * If the binding is using SOAP, this method returns * a {@link SOAPVersion} constant. * * If the binding is not based on SOAP, this method * returns null. See {@link Message} for how a non-SOAP * binding shall be handled by {@link Tube}s. */ public abstract SOAPVersion getSOAPVersion(); /** * Creates a new {@link Codec} for this binding. * * @param binding * Ocassionally some aspects of binding can be overridden by * {@link WSBinding} at runtime by users, so some {@link Codec}s * need to have access to {@link WSBinding} that it's working for. */ public abstract @NotNull Codec createEncoder(@NotNull WSBinding binding); /** * Gets the binding ID, which uniquely identifies the binding. * *

* The relevant specs define the binding IDs and what they mean. * The ID is used in many places to identify the kind of binding * (such as SOAP1.1, SOAP1.2, REST, ...) * * @return * Always non-null same value. */ @Override public abstract String toString(); /** * Returna a new {@link WebServiceFeatureList} instance * that represents the features that are built into this binding ID. * *

* For example, {@link BindingID} for * {@code "{@value SOAPBinding#SOAP11HTTP_MTOM_BINDING}"} * would always return a list that has {@link MTOMFeature} enabled. */ public WebServiceFeatureList createBuiltinFeatureList() { return new WebServiceFeatureList(); } /** * Returns true if this binding can generate WSDL. * *

* For e.g.: SOAP 1.1 and "XSOAP 1.2" is supposed to return true * from this method. For SOAP1.2, there is no standard WSDL, so the * runtime is not generating one and it expects the WSDL is packaged. * */ public boolean canGenerateWSDL() { return false; } /** * Returns a parameter of this binding ID. * *

* Some binding ID, such as those for SOAP/HTTP, uses the URL * query syntax (like {@code ?mtom=true}) to control * the optional part of the binding. This method obtains * the value for such optional parts. * *

* For implementors of the derived classes, if your binding ID * does not define such optional parts (such as the XML/HTTP binding ID), * then you should simply return the specified default value * (which is what this implementation does.) * * @param parameterName * The parameter name, such as "mtom" in the above example. * @param defaultValue * If this binding ID doesn't have the specified parameter explicitly, * this value will be returned. * * @return * the value of the parameter, if it's present (such as "true" * in the above example.) If not present, this method returns * the {@code defaultValue}. */ public String getParameter(String parameterName, String defaultValue) { return defaultValue; } /** * Compares the equality based on {@link #toString()}. */ @Override public boolean equals(Object obj) { if(!(obj instanceof BindingID)) return false; return toString().equals(obj.toString()); } @Override public int hashCode() { return toString().hashCode(); } /** * Parses a binding ID string into a {@link BindingID} object. * *

* This method first checks for a few known values and then delegate * the parsing to {@link BindingIDFactory}. * *

* If parsing succeeds this method returns a value. Otherwise * throws {@link WebServiceException}. * * @throws WebServiceException * If the binding ID is not understood. */ public static @NotNull BindingID parse(String lexical) { if(lexical.equals(XML_HTTP.toString())) return XML_HTTP; if(lexical.equals(REST_HTTP.toString())) return REST_HTTP; if(belongsTo(lexical,SOAP11_HTTP.toString())) return customize(lexical,SOAP11_HTTP); if(belongsTo(lexical,SOAP12_HTTP.toString())) return customize(lexical,SOAP12_HTTP); if(belongsTo(lexical,SOAPBindingImpl.X_SOAP12HTTP_BINDING)) return customize(lexical,X_SOAP12_HTTP); // OK, it's none of the values JAX-WS understands. for( BindingIDFactory f : ServiceFinder.find(BindingIDFactory.class) ) { BindingID r = f.parse(lexical); if(r!=null) return r; } // nobody understood this value throw new WebServiceException("Wrong binding ID: "+lexical); } private static boolean belongsTo(String lexical, String id) { return lexical.equals(id) || lexical.startsWith(id+'?'); } /** * Parses parameter portion and returns appropriately populated {@link SOAPHTTPImpl} */ private static SOAPHTTPImpl customize(String lexical, SOAPHTTPImpl base) { if(lexical.equals(base.toString())) return base; // otherwise we must have query parameter // we assume the spec won't define any tricky parameters that require // complicated handling (such as %HH or non-ASCII char), so this parser // is quite simple-minded. SOAPHTTPImpl r = new SOAPHTTPImpl(base.getSOAPVersion(), lexical, base.canGenerateWSDL()); try { // With X_SOAP12_HTTP, base != lexical and lexical does n't have any query string if(lexical.indexOf('?') == -1) { return r; } String query = URLDecoder.decode(lexical.substring(lexical.indexOf('?')+1),"UTF-8"); for( String token : query.split("&") ) { int idx = token.indexOf('='); if(idx<0) throw new WebServiceException("Malformed binding ID (no '=' in "+token+")"); r.parameters.put(token.substring(0,idx),token.substring(idx+1)); } } catch (UnsupportedEncodingException e) { throw new AssertionError(e); // UTF-8 is supported everywhere } return r; } /** * Figures out the binding from {@link BindingType} annotation. * * @return * default to {@link BindingID#SOAP11_HTTP}, if no such annotation is present. * @see #parse(String) */ public static @NotNull BindingID parse(Class implClass) { BindingType bindingType = implClass.getAnnotation(BindingType.class); if (bindingType != null) { String bindingId = bindingType.value(); if (bindingId.length() > 0) { return BindingID.parse(bindingId); } } return SOAP11_HTTP; } /** * Constant that represents implementation specific SOAP1.2/HTTP which is * used to generate non-standard WSDLs */ public static final SOAPHTTPImpl X_SOAP12_HTTP = new SOAPHTTPImpl( SOAPVersion.SOAP_12, SOAPBindingImpl.X_SOAP12HTTP_BINDING, true); /** * Constant that represents SOAP1.2/HTTP. */ public static final SOAPHTTPImpl SOAP12_HTTP = new SOAPHTTPImpl( SOAPVersion.SOAP_12, SOAPBinding.SOAP12HTTP_BINDING, true); /** * Constant that represents SOAP1.1/HTTP. */ public static final SOAPHTTPImpl SOAP11_HTTP = new SOAPHTTPImpl( SOAPVersion.SOAP_11, SOAPBinding.SOAP11HTTP_BINDING, true); /** * Constant that represents SOAP1.2/HTTP. */ public static final SOAPHTTPImpl SOAP12_HTTP_MTOM = new SOAPHTTPImpl( SOAPVersion.SOAP_12, SOAPBinding.SOAP12HTTP_MTOM_BINDING, true, true); /** * Constant that represents SOAP1.1/HTTP. */ public static final SOAPHTTPImpl SOAP11_HTTP_MTOM = new SOAPHTTPImpl( SOAPVersion.SOAP_11, SOAPBinding.SOAP11HTTP_MTOM_BINDING, true, true); /** * Constant that represents REST. */ public static final BindingID XML_HTTP = new Impl(SOAPVersion.SOAP_11, HTTPBinding.HTTP_BINDING,false) { @Override public Codec createEncoder(WSBinding binding) { return new XMLHTTPBindingCodec(binding.getFeatures()); } }; /** * Constant that represents REST. */ private static final BindingID REST_HTTP = new Impl(SOAPVersion.SOAP_11, JAXWSProperties.REST_BINDING,true) { @Override public Codec createEncoder(WSBinding binding) { return new XMLHTTPBindingCodec(binding.getFeatures()); } }; private static abstract class Impl extends BindingID { final SOAPVersion version; private final String lexical; private final boolean canGenerateWSDL; public Impl(SOAPVersion version, String lexical, boolean canGenerateWSDL) { this.version = version; this.lexical = lexical; this.canGenerateWSDL = canGenerateWSDL; } @Override public SOAPVersion getSOAPVersion() { return version; } @Override public String toString() { return lexical; } @Deprecated @Override public boolean canGenerateWSDL() { return canGenerateWSDL; } } /** * Internal implementation for SOAP/HTTP. */ private static final class SOAPHTTPImpl extends Impl implements Cloneable { /*final*/ Map parameters = new HashMap(); static final String MTOM_PARAM = "mtom"; public SOAPHTTPImpl(SOAPVersion version, String lexical, boolean canGenerateWSDL) { super(version, lexical, canGenerateWSDL); } public SOAPHTTPImpl(SOAPVersion version, String lexical, boolean canGenerateWSDL, boolean mtomEnabled) { this(version, lexical, canGenerateWSDL); String mtomStr = mtomEnabled ? "true" : "false"; parameters.put(MTOM_PARAM, mtomStr); } public @NotNull @Override Codec createEncoder(WSBinding binding) { return new SOAPBindingCodec(binding.getFeatures()); } private Boolean isMTOMEnabled() { String mtom = parameters.get(MTOM_PARAM); return mtom==null?null:Boolean.valueOf(mtom); } @Override public WebServiceFeatureList createBuiltinFeatureList() { WebServiceFeatureList r=super.createBuiltinFeatureList(); Boolean mtom = isMTOMEnabled(); if(mtom != null) r.add(new MTOMFeature(mtom)); return r; } @Override public String getParameter(String parameterName, String defaultValue) { if (parameters.get(parameterName) == null) return super.getParameter(parameterName, defaultValue); return parameters.get(parameterName); } @Override public SOAPHTTPImpl clone() throws CloneNotSupportedException { return (SOAPHTTPImpl) super.clone(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy