Thu, 31 Aug 2017 15:18:52 +0800
merge
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. Oracle designates this |
aoqi@0 | 8 | * particular file as subject to the "Classpath" exception as provided |
aoqi@0 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
aoqi@0 | 10 | * |
aoqi@0 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 15 | * accompanied this code). |
aoqi@0 | 16 | * |
aoqi@0 | 17 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 20 | * |
aoqi@0 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 22 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 23 | * questions. |
aoqi@0 | 24 | */ |
aoqi@0 | 25 | |
aoqi@0 | 26 | package com.sun.xml.internal.ws.transport.http.server; |
aoqi@0 | 27 | |
aoqi@0 | 28 | import com.sun.istack.internal.Nullable; |
aoqi@0 | 29 | import com.sun.xml.internal.stream.buffer.XMLStreamBufferResult; |
aoqi@0 | 30 | import com.sun.xml.internal.ws.api.Component; |
aoqi@0 | 31 | import com.sun.xml.internal.ws.api.WSBinding; |
aoqi@0 | 32 | import com.sun.xml.internal.ws.api.BindingID; |
aoqi@0 | 33 | import com.sun.xml.internal.ws.api.databinding.MetadataReader; |
aoqi@0 | 34 | import com.sun.xml.internal.ws.api.message.Packet; |
aoqi@0 | 35 | import com.sun.xml.internal.ws.binding.BindingImpl; |
aoqi@0 | 36 | import com.sun.xml.internal.ws.api.server.*; |
aoqi@0 | 37 | import com.sun.xml.internal.ws.server.EndpointFactory; |
aoqi@0 | 38 | import com.sun.xml.internal.ws.server.ServerRtException; |
aoqi@0 | 39 | import com.sun.xml.internal.ws.util.xml.XmlUtil; |
aoqi@0 | 40 | import com.sun.xml.internal.ws.transport.http.HttpAdapterList; |
aoqi@0 | 41 | import com.sun.xml.internal.ws.transport.http.HttpAdapter; |
aoqi@0 | 42 | import com.sun.istack.internal.NotNull; |
aoqi@0 | 43 | |
aoqi@0 | 44 | import java.net.MalformedURLException; |
aoqi@0 | 45 | |
aoqi@0 | 46 | import javax.xml.namespace.QName; |
aoqi@0 | 47 | import javax.xml.transform.Source; |
aoqi@0 | 48 | import javax.xml.transform.TransformerException; |
aoqi@0 | 49 | import javax.xml.ws.*; |
aoqi@0 | 50 | import javax.xml.ws.spi.http.HttpContext; |
aoqi@0 | 51 | import javax.xml.ws.wsaddressing.W3CEndpointReference; |
aoqi@0 | 52 | import javax.xml.parsers.ParserConfigurationException; |
aoqi@0 | 53 | |
aoqi@0 | 54 | import java.io.IOException; |
aoqi@0 | 55 | import java.net.URL; |
aoqi@0 | 56 | import java.util.ArrayList; |
aoqi@0 | 57 | import java.util.Collections; |
aoqi@0 | 58 | import java.util.HashMap; |
aoqi@0 | 59 | import java.util.List; |
aoqi@0 | 60 | import java.util.Map; |
aoqi@0 | 61 | import java.util.concurrent.Executor; |
aoqi@0 | 62 | import java.lang.reflect.InvocationTargetException; |
aoqi@0 | 63 | import java.lang.reflect.Method; |
aoqi@0 | 64 | |
aoqi@0 | 65 | import org.xml.sax.EntityResolver; |
aoqi@0 | 66 | import org.xml.sax.SAXException; |
aoqi@0 | 67 | import org.w3c.dom.Element; |
aoqi@0 | 68 | |
aoqi@0 | 69 | |
aoqi@0 | 70 | /** |
aoqi@0 | 71 | * Implements {@link Endpoint}. |
aoqi@0 | 72 | * <p/> |
aoqi@0 | 73 | * <p/> |
aoqi@0 | 74 | * This class accumulates the information necessary to create |
aoqi@0 | 75 | * {@link WSEndpoint}, and then when {@link #publish} method |
aoqi@0 | 76 | * is called it will be created. |
aoqi@0 | 77 | * <p/> |
aoqi@0 | 78 | * <p/> |
aoqi@0 | 79 | * This object also allows accumulated information to be retrieved. |
aoqi@0 | 80 | * |
aoqi@0 | 81 | * @author Jitendra Kotamraju |
aoqi@0 | 82 | */ |
aoqi@0 | 83 | public class EndpointImpl extends Endpoint { |
aoqi@0 | 84 | |
aoqi@0 | 85 | private static final WebServicePermission ENDPOINT_PUBLISH_PERMISSION = |
aoqi@0 | 86 | new WebServicePermission("publishEndpoint"); |
aoqi@0 | 87 | |
aoqi@0 | 88 | /** |
aoqi@0 | 89 | * Once the service is published, this field will |
aoqi@0 | 90 | * be set to the {@link HttpEndpoint} instance. |
aoqi@0 | 91 | * <p/> |
aoqi@0 | 92 | * But don't declare the type as {@link HttpEndpoint} |
aoqi@0 | 93 | * to avoid static type dependency that cause the class loading to |
aoqi@0 | 94 | * fail if the LW HTTP server doesn't exist. |
aoqi@0 | 95 | */ |
aoqi@0 | 96 | private Object actualEndpoint; |
aoqi@0 | 97 | |
aoqi@0 | 98 | // information accumulated for creating WSEndpoint |
aoqi@0 | 99 | private final WSBinding binding; |
aoqi@0 | 100 | private @Nullable final Object implementor; |
aoqi@0 | 101 | private List<Source> metadata; |
aoqi@0 | 102 | private Executor executor; |
aoqi@0 | 103 | private Map<String, Object> properties = Collections.emptyMap(); // always non-null |
aoqi@0 | 104 | private boolean stopped; |
aoqi@0 | 105 | private @Nullable EndpointContext endpointContext; |
aoqi@0 | 106 | private @NotNull final Class<?> implClass; |
aoqi@0 | 107 | private final Invoker invoker; |
aoqi@0 | 108 | private Container container; |
aoqi@0 | 109 | |
aoqi@0 | 110 | |
aoqi@0 | 111 | public EndpointImpl(@NotNull BindingID bindingId, @NotNull Object impl, |
aoqi@0 | 112 | WebServiceFeature ... features) { |
aoqi@0 | 113 | this(bindingId, impl, impl.getClass(), |
aoqi@0 | 114 | InstanceResolver.createSingleton(impl).createInvoker(), features); |
aoqi@0 | 115 | } |
aoqi@0 | 116 | |
aoqi@0 | 117 | public EndpointImpl(@NotNull BindingID bindingId, @NotNull Class implClass, |
aoqi@0 | 118 | javax.xml.ws.spi.Invoker invoker, |
aoqi@0 | 119 | WebServiceFeature ... features) { |
aoqi@0 | 120 | this(bindingId, null, implClass, new InvokerImpl(invoker), features); |
aoqi@0 | 121 | } |
aoqi@0 | 122 | |
aoqi@0 | 123 | private EndpointImpl(@NotNull BindingID bindingId, Object impl, @NotNull Class implClass, |
aoqi@0 | 124 | Invoker invoker, WebServiceFeature ... features) { |
aoqi@0 | 125 | binding = BindingImpl.create(bindingId, features); |
aoqi@0 | 126 | this.implClass = implClass; |
aoqi@0 | 127 | this.invoker = invoker; |
aoqi@0 | 128 | this.implementor = impl; |
aoqi@0 | 129 | } |
aoqi@0 | 130 | |
aoqi@0 | 131 | |
aoqi@0 | 132 | /** |
aoqi@0 | 133 | * Wraps an already created {@link WSEndpoint} into an {@link EndpointImpl}, |
aoqi@0 | 134 | * and immediately publishes it with the given context. |
aoqi@0 | 135 | * |
aoqi@0 | 136 | * @param wse created endpoint |
aoqi@0 | 137 | * @param serverContext supported http context |
aoqi@0 | 138 | * @deprecated This is a backdoor method. Don't use it unless you know what you are doing. |
aoqi@0 | 139 | */ |
aoqi@0 | 140 | public EndpointImpl(WSEndpoint wse, Object serverContext) { |
aoqi@0 | 141 | this(wse, serverContext, null); |
aoqi@0 | 142 | } |
aoqi@0 | 143 | |
aoqi@0 | 144 | /** |
aoqi@0 | 145 | * Wraps an already created {@link WSEndpoint} into an {@link EndpointImpl}, |
aoqi@0 | 146 | * and immediately publishes it with the given context. |
aoqi@0 | 147 | * |
aoqi@0 | 148 | * @param wse created endpoint |
aoqi@0 | 149 | * @param serverContext supported http context |
aoqi@0 | 150 | * @param ctxt endpoint context |
aoqi@0 | 151 | * @deprecated This is a backdoor method. Don't use it unless you know what you are doing. |
aoqi@0 | 152 | */ |
aoqi@0 | 153 | public EndpointImpl(WSEndpoint wse, Object serverContext, EndpointContext ctxt) { |
aoqi@0 | 154 | endpointContext = ctxt; |
aoqi@0 | 155 | actualEndpoint = new HttpEndpoint(null, getAdapter(wse, "")); |
aoqi@0 | 156 | ((HttpEndpoint) actualEndpoint).publish(serverContext); |
aoqi@0 | 157 | binding = wse.getBinding(); |
aoqi@0 | 158 | implementor = null; // this violates the semantics, but hey, this is a backdoor. |
aoqi@0 | 159 | implClass = null; |
aoqi@0 | 160 | invoker = null; |
aoqi@0 | 161 | } |
aoqi@0 | 162 | |
aoqi@0 | 163 | /** |
aoqi@0 | 164 | * Wraps an already created {@link WSEndpoint} into an {@link EndpointImpl}, |
aoqi@0 | 165 | * and immediately publishes it with the given context. |
aoqi@0 | 166 | * |
aoqi@0 | 167 | * @param wse created endpoint |
aoqi@0 | 168 | * @param address endpoint address |
aoqi@0 | 169 | * @deprecated This is a backdoor method. Don't use it unless you know what you are doing. |
aoqi@0 | 170 | */ |
aoqi@0 | 171 | public EndpointImpl(WSEndpoint wse, String address) { |
aoqi@0 | 172 | this(wse, address, null); |
aoqi@0 | 173 | } |
aoqi@0 | 174 | |
aoqi@0 | 175 | |
aoqi@0 | 176 | /** |
aoqi@0 | 177 | * Wraps an already created {@link WSEndpoint} into an {@link EndpointImpl}, |
aoqi@0 | 178 | * and immediately publishes it with the given context. |
aoqi@0 | 179 | * |
aoqi@0 | 180 | * @param wse created endpoint |
aoqi@0 | 181 | * @param address endpoint address |
aoqi@0 | 182 | * @param ctxt endpoint context |
aoqi@0 | 183 | * @deprecated This is a backdoor method. Don't use it unless you know what you are doing. |
aoqi@0 | 184 | */ |
aoqi@0 | 185 | public EndpointImpl(WSEndpoint wse, String address, EndpointContext ctxt) { |
aoqi@0 | 186 | URL url; |
aoqi@0 | 187 | try { |
aoqi@0 | 188 | url = new URL(address); |
aoqi@0 | 189 | } catch (MalformedURLException ex) { |
aoqi@0 | 190 | throw new IllegalArgumentException("Cannot create URL for this address " + address); |
aoqi@0 | 191 | } |
aoqi@0 | 192 | if (!url.getProtocol().equals("http")) { |
aoqi@0 | 193 | throw new IllegalArgumentException(url.getProtocol() + " protocol based address is not supported"); |
aoqi@0 | 194 | } |
aoqi@0 | 195 | if (!url.getPath().startsWith("/")) { |
aoqi@0 | 196 | throw new IllegalArgumentException("Incorrect WebService address=" + address + |
aoqi@0 | 197 | ". The address's path should start with /"); |
aoqi@0 | 198 | } |
aoqi@0 | 199 | endpointContext = ctxt; |
aoqi@0 | 200 | actualEndpoint = new HttpEndpoint(null, getAdapter(wse, url.getPath())); |
aoqi@0 | 201 | ((HttpEndpoint) actualEndpoint).publish(address); |
aoqi@0 | 202 | binding = wse.getBinding(); |
aoqi@0 | 203 | implementor = null; // this violates the semantics, but hey, this is a backdoor. |
aoqi@0 | 204 | implClass = null; |
aoqi@0 | 205 | invoker = null; |
aoqi@0 | 206 | } |
aoqi@0 | 207 | |
aoqi@0 | 208 | public Binding getBinding() { |
aoqi@0 | 209 | return binding; |
aoqi@0 | 210 | } |
aoqi@0 | 211 | |
aoqi@0 | 212 | public Object getImplementor() { |
aoqi@0 | 213 | return implementor; |
aoqi@0 | 214 | } |
aoqi@0 | 215 | |
aoqi@0 | 216 | public void publish(String address) { |
aoqi@0 | 217 | canPublish(); |
aoqi@0 | 218 | URL url; |
aoqi@0 | 219 | try { |
aoqi@0 | 220 | url = new URL(address); |
aoqi@0 | 221 | } catch (MalformedURLException ex) { |
aoqi@0 | 222 | throw new IllegalArgumentException("Cannot create URL for this address " + address); |
aoqi@0 | 223 | } |
aoqi@0 | 224 | if (!url.getProtocol().equals("http")) { |
aoqi@0 | 225 | throw new IllegalArgumentException(url.getProtocol() + " protocol based address is not supported"); |
aoqi@0 | 226 | } |
aoqi@0 | 227 | if (!url.getPath().startsWith("/")) { |
aoqi@0 | 228 | throw new IllegalArgumentException("Incorrect WebService address=" + address + |
aoqi@0 | 229 | ". The address's path should start with /"); |
aoqi@0 | 230 | } |
aoqi@0 | 231 | createEndpoint(url.getPath()); |
aoqi@0 | 232 | ((HttpEndpoint) actualEndpoint).publish(address); |
aoqi@0 | 233 | } |
aoqi@0 | 234 | |
aoqi@0 | 235 | public void publish(Object serverContext) { |
aoqi@0 | 236 | canPublish(); |
aoqi@0 | 237 | if (!com.sun.net.httpserver.HttpContext.class.isAssignableFrom(serverContext.getClass())) { |
aoqi@0 | 238 | throw new IllegalArgumentException(serverContext.getClass() + " is not a supported context."); |
aoqi@0 | 239 | } |
aoqi@0 | 240 | createEndpoint(((com.sun.net.httpserver.HttpContext)serverContext).getPath()); |
aoqi@0 | 241 | ((HttpEndpoint) actualEndpoint).publish(serverContext); |
aoqi@0 | 242 | } |
aoqi@0 | 243 | |
aoqi@0 | 244 | public void publish(HttpContext serverContext) { |
aoqi@0 | 245 | canPublish(); |
aoqi@0 | 246 | createEndpoint(serverContext.getPath()); |
aoqi@0 | 247 | ((HttpEndpoint) actualEndpoint).publish(serverContext); |
aoqi@0 | 248 | } |
aoqi@0 | 249 | |
aoqi@0 | 250 | public void stop() { |
aoqi@0 | 251 | if (isPublished()) { |
aoqi@0 | 252 | ((HttpEndpoint) actualEndpoint).stop(); |
aoqi@0 | 253 | actualEndpoint = null; |
aoqi@0 | 254 | stopped = true; |
aoqi@0 | 255 | } |
aoqi@0 | 256 | } |
aoqi@0 | 257 | |
aoqi@0 | 258 | public boolean isPublished() { |
aoqi@0 | 259 | return actualEndpoint != null; |
aoqi@0 | 260 | } |
aoqi@0 | 261 | |
aoqi@0 | 262 | public List<Source> getMetadata() { |
aoqi@0 | 263 | return metadata; |
aoqi@0 | 264 | } |
aoqi@0 | 265 | |
aoqi@0 | 266 | public void setMetadata(java.util.List<Source> metadata) { |
aoqi@0 | 267 | if (isPublished()) { |
aoqi@0 | 268 | throw new IllegalStateException("Cannot set Metadata. Endpoint is already published"); |
aoqi@0 | 269 | } |
aoqi@0 | 270 | this.metadata = metadata; |
aoqi@0 | 271 | } |
aoqi@0 | 272 | |
aoqi@0 | 273 | public Executor getExecutor() { |
aoqi@0 | 274 | return executor; |
aoqi@0 | 275 | } |
aoqi@0 | 276 | |
aoqi@0 | 277 | public void setExecutor(Executor executor) { |
aoqi@0 | 278 | this.executor = executor; |
aoqi@0 | 279 | } |
aoqi@0 | 280 | |
aoqi@0 | 281 | public Map<String, Object> getProperties() { |
aoqi@0 | 282 | return new HashMap<String, Object>(properties); |
aoqi@0 | 283 | } |
aoqi@0 | 284 | |
aoqi@0 | 285 | public void setProperties(Map<String, Object> map) { |
aoqi@0 | 286 | this.properties = new HashMap<String, Object>(map); |
aoqi@0 | 287 | } |
aoqi@0 | 288 | |
aoqi@0 | 289 | /* |
aoqi@0 | 290 | * Checks the permission of "publishEndpoint" before accessing HTTP classes. |
aoqi@0 | 291 | * Also it checks if there is an available HTTP server implementation. |
aoqi@0 | 292 | */ |
aoqi@0 | 293 | private void createEndpoint(String urlPattern) { |
aoqi@0 | 294 | // Checks permission for "publishEndpoint" |
aoqi@0 | 295 | SecurityManager sm = System.getSecurityManager(); |
aoqi@0 | 296 | if (sm != null) { |
aoqi@0 | 297 | sm.checkPermission(ENDPOINT_PUBLISH_PERMISSION); |
aoqi@0 | 298 | } |
aoqi@0 | 299 | |
aoqi@0 | 300 | // See if HttpServer implementation is available |
aoqi@0 | 301 | try { |
aoqi@0 | 302 | Class.forName("com.sun.net.httpserver.HttpServer"); |
aoqi@0 | 303 | } catch (Exception e) { |
aoqi@0 | 304 | throw new UnsupportedOperationException("Couldn't load light weight http server", e); |
aoqi@0 | 305 | } |
aoqi@0 | 306 | container = getContainer(); |
aoqi@0 | 307 | MetadataReader metadataReader = EndpointFactory.getExternalMetadatReader(implClass, binding); |
aoqi@0 | 308 | WSEndpoint wse = WSEndpoint.create( |
aoqi@0 | 309 | implClass, true, |
aoqi@0 | 310 | invoker, |
aoqi@0 | 311 | getProperty(QName.class, Endpoint.WSDL_SERVICE), |
aoqi@0 | 312 | getProperty(QName.class, Endpoint.WSDL_PORT), |
aoqi@0 | 313 | container, |
aoqi@0 | 314 | binding, |
aoqi@0 | 315 | getPrimaryWsdl(metadataReader), |
aoqi@0 | 316 | buildDocList(), |
aoqi@0 | 317 | (EntityResolver) null, |
aoqi@0 | 318 | false |
aoqi@0 | 319 | ); |
aoqi@0 | 320 | // Don't load HttpEndpoint class before as it may load HttpServer classes |
aoqi@0 | 321 | actualEndpoint = new HttpEndpoint(executor, getAdapter(wse, urlPattern)); |
aoqi@0 | 322 | } |
aoqi@0 | 323 | |
aoqi@0 | 324 | private <T> T getProperty(Class<T> type, String key) { |
aoqi@0 | 325 | Object o = properties.get(key); |
aoqi@0 | 326 | if (o == null) return null; |
aoqi@0 | 327 | if (type.isInstance(o)) |
aoqi@0 | 328 | return type.cast(o); |
aoqi@0 | 329 | else |
aoqi@0 | 330 | throw new IllegalArgumentException("Property " + key + " has to be of type " + type); // i18n |
aoqi@0 | 331 | } |
aoqi@0 | 332 | |
aoqi@0 | 333 | /** |
aoqi@0 | 334 | * Convert metadata sources using identity transform. So that we can |
aoqi@0 | 335 | * reuse the Source object multiple times. |
aoqi@0 | 336 | */ |
aoqi@0 | 337 | private List<SDDocumentSource> buildDocList() { |
aoqi@0 | 338 | List<SDDocumentSource> r = new ArrayList<SDDocumentSource>(); |
aoqi@0 | 339 | |
aoqi@0 | 340 | if (metadata != null) { |
aoqi@0 | 341 | for (Source source : metadata) { |
aoqi@0 | 342 | try { |
aoqi@0 | 343 | XMLStreamBufferResult xsbr = XmlUtil.identityTransform(source, new XMLStreamBufferResult()); |
aoqi@0 | 344 | String systemId = source.getSystemId(); |
aoqi@0 | 345 | |
aoqi@0 | 346 | r.add(SDDocumentSource.create(new URL(systemId), xsbr.getXMLStreamBuffer())); |
aoqi@0 | 347 | } catch (TransformerException te) { |
aoqi@0 | 348 | throw new ServerRtException("server.rt.err", te); |
aoqi@0 | 349 | } catch (IOException te) { |
aoqi@0 | 350 | throw new ServerRtException("server.rt.err", te); |
aoqi@0 | 351 | } catch (SAXException e) { |
aoqi@0 | 352 | throw new ServerRtException("server.rt.err", e); |
aoqi@0 | 353 | } catch (ParserConfigurationException e) { |
aoqi@0 | 354 | throw new ServerRtException("server.rt.err", e); |
aoqi@0 | 355 | } |
aoqi@0 | 356 | } |
aoqi@0 | 357 | } |
aoqi@0 | 358 | |
aoqi@0 | 359 | return r; |
aoqi@0 | 360 | } |
aoqi@0 | 361 | |
aoqi@0 | 362 | /** |
aoqi@0 | 363 | * Gets wsdl from @WebService or @WebServiceProvider |
aoqi@0 | 364 | */ |
aoqi@0 | 365 | private @Nullable SDDocumentSource getPrimaryWsdl(MetadataReader metadataReader) { |
aoqi@0 | 366 | // Takes care of @WebService, @WebServiceProvider's wsdlLocation |
aoqi@0 | 367 | EndpointFactory.verifyImplementorClass(implClass, metadataReader); |
aoqi@0 | 368 | String wsdlLocation = EndpointFactory.getWsdlLocation(implClass, metadataReader); |
aoqi@0 | 369 | if (wsdlLocation != null) { |
aoqi@0 | 370 | ClassLoader cl = implClass.getClassLoader(); |
aoqi@0 | 371 | URL url = cl.getResource(wsdlLocation); |
aoqi@0 | 372 | if (url != null) { |
aoqi@0 | 373 | return SDDocumentSource.create(url); |
aoqi@0 | 374 | } |
aoqi@0 | 375 | throw new ServerRtException("cannot.load.wsdl", wsdlLocation); |
aoqi@0 | 376 | } |
aoqi@0 | 377 | return null; |
aoqi@0 | 378 | } |
aoqi@0 | 379 | |
aoqi@0 | 380 | private void canPublish() { |
aoqi@0 | 381 | if (isPublished()) { |
aoqi@0 | 382 | throw new IllegalStateException( |
aoqi@0 | 383 | "Cannot publish this endpoint. Endpoint has been already published."); |
aoqi@0 | 384 | } |
aoqi@0 | 385 | if (stopped) { |
aoqi@0 | 386 | throw new IllegalStateException( |
aoqi@0 | 387 | "Cannot publish this endpoint. Endpoint has been already stopped."); |
aoqi@0 | 388 | } |
aoqi@0 | 389 | } |
aoqi@0 | 390 | |
aoqi@0 | 391 | public EndpointReference getEndpointReference(Element...referenceParameters) { |
aoqi@0 | 392 | return getEndpointReference(W3CEndpointReference.class, referenceParameters); |
aoqi@0 | 393 | } |
aoqi@0 | 394 | |
aoqi@0 | 395 | public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, Element...referenceParameters) { |
aoqi@0 | 396 | if (!isPublished()) { |
aoqi@0 | 397 | throw new WebServiceException("Endpoint is not published yet"); |
aoqi@0 | 398 | } |
aoqi@0 | 399 | return ((HttpEndpoint)actualEndpoint).getEndpointReference(clazz,referenceParameters); |
aoqi@0 | 400 | } |
aoqi@0 | 401 | |
aoqi@0 | 402 | @Override |
aoqi@0 | 403 | public void setEndpointContext(EndpointContext ctxt) { |
aoqi@0 | 404 | this.endpointContext = ctxt; |
aoqi@0 | 405 | } |
aoqi@0 | 406 | |
aoqi@0 | 407 | private HttpAdapter getAdapter(WSEndpoint endpoint, String urlPattern) { |
aoqi@0 | 408 | HttpAdapterList adapterList = null; |
aoqi@0 | 409 | if (endpointContext != null) { |
aoqi@0 | 410 | if (endpointContext instanceof Component) { |
aoqi@0 | 411 | adapterList = ((Component) endpointContext).getSPI(HttpAdapterList.class); |
aoqi@0 | 412 | } |
aoqi@0 | 413 | |
aoqi@0 | 414 | if (adapterList == null) { |
aoqi@0 | 415 | for(Endpoint e : endpointContext.getEndpoints()) { |
aoqi@0 | 416 | if (e.isPublished() && e != this) { |
aoqi@0 | 417 | adapterList = ((HttpEndpoint)(((EndpointImpl)e).actualEndpoint)).getAdapterOwner(); |
aoqi@0 | 418 | assert adapterList != null; |
aoqi@0 | 419 | break; |
aoqi@0 | 420 | } |
aoqi@0 | 421 | } |
aoqi@0 | 422 | } |
aoqi@0 | 423 | } |
aoqi@0 | 424 | if (adapterList == null) { |
aoqi@0 | 425 | adapterList = new ServerAdapterList(); |
aoqi@0 | 426 | } |
aoqi@0 | 427 | return adapterList.createAdapter("", urlPattern, endpoint); |
aoqi@0 | 428 | } |
aoqi@0 | 429 | |
aoqi@0 | 430 | /** |
aoqi@0 | 431 | * Endpoints within a EndpointContext get the same container. |
aoqi@0 | 432 | */ |
aoqi@0 | 433 | private Container getContainer() { |
aoqi@0 | 434 | if (endpointContext != null) { |
aoqi@0 | 435 | if (endpointContext instanceof Component) { |
aoqi@0 | 436 | Container c = ((Component) endpointContext).getSPI(Container.class); |
aoqi@0 | 437 | if (c != null) |
aoqi@0 | 438 | return c; |
aoqi@0 | 439 | } |
aoqi@0 | 440 | |
aoqi@0 | 441 | for(Endpoint e : endpointContext.getEndpoints()) { |
aoqi@0 | 442 | if (e.isPublished() && e != this) { |
aoqi@0 | 443 | return ((EndpointImpl)e).container; |
aoqi@0 | 444 | } |
aoqi@0 | 445 | } |
aoqi@0 | 446 | } |
aoqi@0 | 447 | return new ServerContainer(); |
aoqi@0 | 448 | } |
aoqi@0 | 449 | |
aoqi@0 | 450 | private static class InvokerImpl extends Invoker { |
aoqi@0 | 451 | private javax.xml.ws.spi.Invoker spiInvoker; |
aoqi@0 | 452 | |
aoqi@0 | 453 | InvokerImpl(javax.xml.ws.spi.Invoker spiInvoker) { |
aoqi@0 | 454 | this.spiInvoker = spiInvoker; |
aoqi@0 | 455 | } |
aoqi@0 | 456 | |
aoqi@0 | 457 | @Override |
aoqi@0 | 458 | public void start(@NotNull WSWebServiceContext wsc, @NotNull WSEndpoint endpoint) { |
aoqi@0 | 459 | try { |
aoqi@0 | 460 | spiInvoker.inject(wsc); |
aoqi@0 | 461 | } catch (IllegalAccessException e) { |
aoqi@0 | 462 | throw new WebServiceException(e); |
aoqi@0 | 463 | } catch (InvocationTargetException e) { |
aoqi@0 | 464 | throw new WebServiceException(e); |
aoqi@0 | 465 | } |
aoqi@0 | 466 | } |
aoqi@0 | 467 | |
aoqi@0 | 468 | public Object invoke(@NotNull Packet p, @NotNull Method m, @NotNull Object... args) throws InvocationTargetException, IllegalAccessException { |
aoqi@0 | 469 | return spiInvoker.invoke(m, args); |
aoqi@0 | 470 | } |
aoqi@0 | 471 | } |
aoqi@0 | 472 | } |