1 /*
2 * Copyright (c) 1997, 2015, 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
52 import javax.xml.parsers.ParserConfigurationException;
53
54 import java.io.IOException;
55 import java.net.URL;
56 import java.util.ArrayList;
57 import java.util.Collections;
58 import java.util.HashMap;
59 import java.util.List;
60 import java.util.Map;
61 import java.util.concurrent.Executor;
62 import java.lang.reflect.InvocationTargetException;
63 import java.lang.reflect.Method;
64
65 import org.xml.sax.EntityResolver;
66 import org.xml.sax.SAXException;
67 import org.w3c.dom.Element;
68
69
70 /**
71 * Implements {@link Endpoint}.
72 * <p/>
73 * <p/>
74 * This class accumulates the information necessary to create
75 * {@link WSEndpoint}, and then when {@link #publish} method
76 * is called it will be created.
77 * <p/>
78 * <p/>
79 * This object also allows accumulated information to be retrieved.
80 *
81 * @author Jitendra Kotamraju
82 */
83 public class EndpointImpl extends Endpoint {
84
85 private static final WebServicePermission ENDPOINT_PUBLISH_PERMISSION =
86 new WebServicePermission("publishEndpoint");
87
88 /**
89 * Once the service is published, this field will
90 * be set to the {@link HttpEndpoint} instance.
91 * <p/>
92 * But don't declare the type as {@link HttpEndpoint}
93 * to avoid static type dependency that cause the class loading to
94 * fail if the LW HTTP server doesn't exist.
95 */
96 private Object actualEndpoint;
97
98 // information accumulated for creating WSEndpoint
188 url = new URL(address);
189 } catch (MalformedURLException ex) {
190 throw new IllegalArgumentException("Cannot create URL for this address " + address);
191 }
192 if (!url.getProtocol().equals("http")) {
193 throw new IllegalArgumentException(url.getProtocol() + " protocol based address is not supported");
194 }
195 if (!url.getPath().startsWith("/")) {
196 throw new IllegalArgumentException("Incorrect WebService address=" + address +
197 ". The address's path should start with /");
198 }
199 endpointContext = ctxt;
200 actualEndpoint = new HttpEndpoint(null, getAdapter(wse, url.getPath()));
201 ((HttpEndpoint) actualEndpoint).publish(address);
202 binding = wse.getBinding();
203 implementor = null; // this violates the semantics, but hey, this is a backdoor.
204 implClass = null;
205 invoker = null;
206 }
207
208 public Binding getBinding() {
209 return binding;
210 }
211
212 public Object getImplementor() {
213 return implementor;
214 }
215
216 public void publish(String address) {
217 canPublish();
218 URL url;
219 try {
220 url = new URL(address);
221 } catch (MalformedURLException ex) {
222 throw new IllegalArgumentException("Cannot create URL for this address " + address);
223 }
224 if (!url.getProtocol().equals("http")) {
225 throw new IllegalArgumentException(url.getProtocol() + " protocol based address is not supported");
226 }
227 if (!url.getPath().startsWith("/")) {
228 throw new IllegalArgumentException("Incorrect WebService address=" + address +
229 ". The address's path should start with /");
230 }
231 createEndpoint(url.getPath());
232 ((HttpEndpoint) actualEndpoint).publish(address);
233 }
234
235 public void publish(Object serverContext) {
236 canPublish();
237 if (!com.sun.net.httpserver.HttpContext.class.isAssignableFrom(serverContext.getClass())) {
238 throw new IllegalArgumentException(serverContext.getClass() + " is not a supported context.");
239 }
240 createEndpoint(((com.sun.net.httpserver.HttpContext)serverContext).getPath());
241 ((HttpEndpoint) actualEndpoint).publish(serverContext);
242 }
243
244 public void publish(HttpContext serverContext) {
245 canPublish();
246 createEndpoint(serverContext.getPath());
247 ((HttpEndpoint) actualEndpoint).publish(serverContext);
248 }
249
250 public void stop() {
251 if (isPublished()) {
252 ((HttpEndpoint) actualEndpoint).stop();
253 actualEndpoint = null;
254 stopped = true;
255 }
256 }
257
258 public boolean isPublished() {
259 return actualEndpoint != null;
260 }
261
262 public List<Source> getMetadata() {
263 return metadata;
264 }
265
266 public void setMetadata(java.util.List<Source> metadata) {
267 if (isPublished()) {
268 throw new IllegalStateException("Cannot set Metadata. Endpoint is already published");
269 }
270 this.metadata = metadata;
271 }
272
273 public Executor getExecutor() {
274 return executor;
275 }
276
277 public void setExecutor(Executor executor) {
278 this.executor = executor;
279 }
280
281 public Map<String, Object> getProperties() {
282 return new HashMap<String, Object>(properties);
283 }
284
285 public void setProperties(Map<String, Object> map) {
286 this.properties = new HashMap<String, Object>(map);
287 }
288
289 /*
290 * Checks the permission of "publishEndpoint" before accessing HTTP classes.
291 * Also it checks if there is an available HTTP server implementation.
292 */
293 private void createEndpoint(String urlPattern) {
294 // Checks permission for "publishEndpoint"
295 SecurityManager sm = System.getSecurityManager();
296 if (sm != null) {
297 sm.checkPermission(ENDPOINT_PUBLISH_PERMISSION);
298 }
299
300 // See if HttpServer implementation is available
301 try {
302 Class.forName("com.sun.net.httpserver.HttpServer");
303 } catch (Exception e) {
304 throw new UnsupportedOperationException("Couldn't load light weight http server", e);
305 }
306 container = getContainer();
318 false
319 );
320 // Don't load HttpEndpoint class before as it may load HttpServer classes
321 actualEndpoint = new HttpEndpoint(executor, getAdapter(wse, urlPattern));
322 }
323
324 private <T> T getProperty(Class<T> type, String key) {
325 Object o = properties.get(key);
326 if (o == null) return null;
327 if (type.isInstance(o))
328 return type.cast(o);
329 else
330 throw new IllegalArgumentException("Property " + key + " has to be of type " + type); // i18n
331 }
332
333 /**
334 * Convert metadata sources using identity transform. So that we can
335 * reuse the Source object multiple times.
336 */
337 private List<SDDocumentSource> buildDocList() {
338 List<SDDocumentSource> r = new ArrayList<SDDocumentSource>();
339
340 if (metadata != null) {
341 for (Source source : metadata) {
342 try {
343 XMLStreamBufferResult xsbr = XmlUtil.identityTransform(source, new XMLStreamBufferResult());
344 String systemId = source.getSystemId();
345
346 r.add(SDDocumentSource.create(new URL(systemId), xsbr.getXMLStreamBuffer()));
347 } catch (TransformerException te) {
348 throw new ServerRtException("server.rt.err", te);
349 } catch (IOException te) {
350 throw new ServerRtException("server.rt.err", te);
351 } catch (SAXException e) {
352 throw new ServerRtException("server.rt.err", e);
353 } catch (ParserConfigurationException e) {
354 throw new ServerRtException("server.rt.err", e);
355 }
356 }
357 }
358
359 return r;
360 }
361
362 /**
363 * Gets wsdl from @WebService or @WebServiceProvider
364 */
365 private @Nullable SDDocumentSource getPrimaryWsdl(MetadataReader metadataReader) {
366 // Takes care of @WebService, @WebServiceProvider's wsdlLocation
367 EndpointFactory.verifyImplementorClass(implClass, metadataReader);
368 String wsdlLocation = EndpointFactory.getWsdlLocation(implClass, metadataReader);
369 if (wsdlLocation != null) {
370 ClassLoader cl = implClass.getClassLoader();
371 URL url = cl.getResource(wsdlLocation);
372 if (url != null) {
373 return SDDocumentSource.create(url);
374 }
375 return SDDocumentSource.create(implClass, wsdlLocation);
376 }
377 return null;
378 }
379
380 private void canPublish() {
381 if (isPublished()) {
382 throw new IllegalStateException(
383 "Cannot publish this endpoint. Endpoint has been already published.");
384 }
385 if (stopped) {
386 throw new IllegalStateException(
387 "Cannot publish this endpoint. Endpoint has been already stopped.");
388 }
389 }
390
391 public EndpointReference getEndpointReference(Element...referenceParameters) {
392 return getEndpointReference(W3CEndpointReference.class, referenceParameters);
393 }
394
395 public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, Element...referenceParameters) {
396 if (!isPublished()) {
397 throw new WebServiceException("Endpoint is not published yet");
398 }
399 return ((HttpEndpoint)actualEndpoint).getEndpointReference(clazz,referenceParameters);
400 }
401
402 @Override
403 public void setEndpointContext(EndpointContext ctxt) {
404 this.endpointContext = ctxt;
405 }
406
407 private HttpAdapter getAdapter(WSEndpoint endpoint, String urlPattern) {
408 HttpAdapterList adapterList = null;
409 if (endpointContext != null) {
410 if (endpointContext instanceof Component) {
411 adapterList = ((Component) endpointContext).getSPI(HttpAdapterList.class);
412 }
413
414 if (adapterList == null) {
441 for(Endpoint e : endpointContext.getEndpoints()) {
442 if (e.isPublished() && e != this) {
443 return ((EndpointImpl)e).container;
444 }
445 }
446 }
447 return new ServerContainer();
448 }
449
450 private static class InvokerImpl extends Invoker {
451 private javax.xml.ws.spi.Invoker spiInvoker;
452
453 InvokerImpl(javax.xml.ws.spi.Invoker spiInvoker) {
454 this.spiInvoker = spiInvoker;
455 }
456
457 @Override
458 public void start(@NotNull WSWebServiceContext wsc, @NotNull WSEndpoint endpoint) {
459 try {
460 spiInvoker.inject(wsc);
461 } catch (IllegalAccessException e) {
462 throw new WebServiceException(e);
463 } catch (InvocationTargetException e) {
464 throw new WebServiceException(e);
465 }
466 }
467
468 public Object invoke(@NotNull Packet p, @NotNull Method m, @NotNull Object... args) throws InvocationTargetException, IllegalAccessException {
469 return spiInvoker.invoke(m, args);
470 }
471 }
472 }
|
1 /*
2 * Copyright (c) 1997, 2017, 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
52 import javax.xml.parsers.ParserConfigurationException;
53
54 import java.io.IOException;
55 import java.net.URL;
56 import java.util.ArrayList;
57 import java.util.Collections;
58 import java.util.HashMap;
59 import java.util.List;
60 import java.util.Map;
61 import java.util.concurrent.Executor;
62 import java.lang.reflect.InvocationTargetException;
63 import java.lang.reflect.Method;
64
65 import org.xml.sax.EntityResolver;
66 import org.xml.sax.SAXException;
67 import org.w3c.dom.Element;
68
69
70 /**
71 * Implements {@link Endpoint}.
72 *
73 * This class accumulates the information necessary to create
74 * {@link WSEndpoint}, and then when {@link #publish} method
75 * is called it will be created.
76 *
77 * This object also allows accumulated information to be retrieved.
78 *
79 * @author Jitendra Kotamraju
80 */
81 public class EndpointImpl extends Endpoint {
82
83 private static final WebServicePermission ENDPOINT_PUBLISH_PERMISSION =
84 new WebServicePermission("publishEndpoint");
85
86 /**
87 * Once the service is published, this field will
88 * be set to the {@link HttpEndpoint} instance.
89 * <p/>
90 * But don't declare the type as {@link HttpEndpoint}
91 * to avoid static type dependency that cause the class loading to
92 * fail if the LW HTTP server doesn't exist.
93 */
94 private Object actualEndpoint;
95
96 // information accumulated for creating WSEndpoint
186 url = new URL(address);
187 } catch (MalformedURLException ex) {
188 throw new IllegalArgumentException("Cannot create URL for this address " + address);
189 }
190 if (!url.getProtocol().equals("http")) {
191 throw new IllegalArgumentException(url.getProtocol() + " protocol based address is not supported");
192 }
193 if (!url.getPath().startsWith("/")) {
194 throw new IllegalArgumentException("Incorrect WebService address=" + address +
195 ". The address's path should start with /");
196 }
197 endpointContext = ctxt;
198 actualEndpoint = new HttpEndpoint(null, getAdapter(wse, url.getPath()));
199 ((HttpEndpoint) actualEndpoint).publish(address);
200 binding = wse.getBinding();
201 implementor = null; // this violates the semantics, but hey, this is a backdoor.
202 implClass = null;
203 invoker = null;
204 }
205
206 @Override
207 public Binding getBinding() {
208 return binding;
209 }
210
211 @Override
212 public Object getImplementor() {
213 return implementor;
214 }
215
216 @Override
217 public void publish(String address) {
218 canPublish();
219 URL url;
220 try {
221 url = new URL(address);
222 } catch (MalformedURLException ex) {
223 throw new IllegalArgumentException("Cannot create URL for this address " + address);
224 }
225 if (!url.getProtocol().equals("http")) {
226 throw new IllegalArgumentException(url.getProtocol() + " protocol based address is not supported");
227 }
228 if (!url.getPath().startsWith("/")) {
229 throw new IllegalArgumentException("Incorrect WebService address=" + address +
230 ". The address's path should start with /");
231 }
232 createEndpoint(url.getPath());
233 ((HttpEndpoint) actualEndpoint).publish(address);
234 }
235
236 @Override
237 public void publish(Object serverContext) {
238 canPublish();
239 if (!com.sun.net.httpserver.HttpContext.class.isAssignableFrom(serverContext.getClass())) {
240 throw new IllegalArgumentException(serverContext.getClass() + " is not a supported context.");
241 }
242 createEndpoint(((com.sun.net.httpserver.HttpContext)serverContext).getPath());
243 ((HttpEndpoint) actualEndpoint).publish(serverContext);
244 }
245
246 @Override
247 public void publish(HttpContext serverContext) {
248 canPublish();
249 createEndpoint(serverContext.getPath());
250 ((HttpEndpoint) actualEndpoint).publish(serverContext);
251 }
252
253 @Override
254 public void stop() {
255 if (isPublished()) {
256 ((HttpEndpoint) actualEndpoint).stop();
257 actualEndpoint = null;
258 stopped = true;
259 }
260 }
261
262 @Override
263 public boolean isPublished() {
264 return actualEndpoint != null;
265 }
266
267 @Override
268 public List<Source> getMetadata() {
269 return metadata;
270 }
271
272 @Override
273 public void setMetadata(java.util.List<Source> metadata) {
274 if (isPublished()) {
275 throw new IllegalStateException("Cannot set Metadata. Endpoint is already published");
276 }
277 this.metadata = metadata;
278 }
279
280 @Override
281 public Executor getExecutor() {
282 return executor;
283 }
284
285 @Override
286 public void setExecutor(Executor executor) {
287 this.executor = executor;
288 }
289
290 @Override
291 public Map<String, Object> getProperties() {
292 return new HashMap<>(properties);
293 }
294
295 @Override
296 public void setProperties(Map<String, Object> map) {
297 this.properties = new HashMap<>(map);
298 }
299
300 /*
301 * Checks the permission of "publishEndpoint" before accessing HTTP classes.
302 * Also it checks if there is an available HTTP server implementation.
303 */
304 private void createEndpoint(String urlPattern) {
305 // Checks permission for "publishEndpoint"
306 SecurityManager sm = System.getSecurityManager();
307 if (sm != null) {
308 sm.checkPermission(ENDPOINT_PUBLISH_PERMISSION);
309 }
310
311 // See if HttpServer implementation is available
312 try {
313 Class.forName("com.sun.net.httpserver.HttpServer");
314 } catch (Exception e) {
315 throw new UnsupportedOperationException("Couldn't load light weight http server", e);
316 }
317 container = getContainer();
329 false
330 );
331 // Don't load HttpEndpoint class before as it may load HttpServer classes
332 actualEndpoint = new HttpEndpoint(executor, getAdapter(wse, urlPattern));
333 }
334
335 private <T> T getProperty(Class<T> type, String key) {
336 Object o = properties.get(key);
337 if (o == null) return null;
338 if (type.isInstance(o))
339 return type.cast(o);
340 else
341 throw new IllegalArgumentException("Property " + key + " has to be of type " + type); // i18n
342 }
343
344 /**
345 * Convert metadata sources using identity transform. So that we can
346 * reuse the Source object multiple times.
347 */
348 private List<SDDocumentSource> buildDocList() {
349 List<SDDocumentSource> r = new ArrayList<>();
350
351 if (metadata != null) {
352 for (Source source : metadata) {
353 try {
354 XMLStreamBufferResult xsbr = XmlUtil.identityTransform(source, new XMLStreamBufferResult());
355 String systemId = source.getSystemId();
356
357 r.add(SDDocumentSource.create(new URL(systemId), xsbr.getXMLStreamBuffer()));
358 } catch (TransformerException | IOException | SAXException | ParserConfigurationException te) {
359 throw new ServerRtException("server.rt.err", te);
360 }
361 }
362 }
363
364 return r;
365 }
366
367 /**
368 * Gets wsdl from @WebService or @WebServiceProvider
369 */
370 private @Nullable SDDocumentSource getPrimaryWsdl(MetadataReader metadataReader) {
371 // Takes care of @WebService, @WebServiceProvider's wsdlLocation
372 EndpointFactory.verifyImplementorClass(implClass, metadataReader);
373 String wsdlLocation = EndpointFactory.getWsdlLocation(implClass, metadataReader);
374 if (wsdlLocation != null) {
375 return SDDocumentSource.create(implClass, wsdlLocation);
376 }
377 return null;
378 }
379
380 private void canPublish() {
381 if (isPublished()) {
382 throw new IllegalStateException(
383 "Cannot publish this endpoint. Endpoint has been already published.");
384 }
385 if (stopped) {
386 throw new IllegalStateException(
387 "Cannot publish this endpoint. Endpoint has been already stopped.");
388 }
389 }
390
391 @Override
392 public EndpointReference getEndpointReference(Element...referenceParameters) {
393 return getEndpointReference(W3CEndpointReference.class, referenceParameters);
394 }
395
396 @Override
397 public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, Element...referenceParameters) {
398 if (!isPublished()) {
399 throw new WebServiceException("Endpoint is not published yet");
400 }
401 return ((HttpEndpoint)actualEndpoint).getEndpointReference(clazz,referenceParameters);
402 }
403
404 @Override
405 public void setEndpointContext(EndpointContext ctxt) {
406 this.endpointContext = ctxt;
407 }
408
409 private HttpAdapter getAdapter(WSEndpoint endpoint, String urlPattern) {
410 HttpAdapterList adapterList = null;
411 if (endpointContext != null) {
412 if (endpointContext instanceof Component) {
413 adapterList = ((Component) endpointContext).getSPI(HttpAdapterList.class);
414 }
415
416 if (adapterList == null) {
443 for(Endpoint e : endpointContext.getEndpoints()) {
444 if (e.isPublished() && e != this) {
445 return ((EndpointImpl)e).container;
446 }
447 }
448 }
449 return new ServerContainer();
450 }
451
452 private static class InvokerImpl extends Invoker {
453 private javax.xml.ws.spi.Invoker spiInvoker;
454
455 InvokerImpl(javax.xml.ws.spi.Invoker spiInvoker) {
456 this.spiInvoker = spiInvoker;
457 }
458
459 @Override
460 public void start(@NotNull WSWebServiceContext wsc, @NotNull WSEndpoint endpoint) {
461 try {
462 spiInvoker.inject(wsc);
463 } catch (IllegalAccessException | InvocationTargetException e) {
464 throw new WebServiceException(e);
465 }
466 }
467
468 @Override
469 public Object invoke(@NotNull Packet p, @NotNull Method m, @NotNull Object... args) throws InvocationTargetException, IllegalAccessException {
470 return spiInvoker.invoke(m, args);
471 }
472 }
473 }
|