001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.remoting.jaxws;
018:
019: import java.util.LinkedHashSet;
020: import java.util.Map;
021: import java.util.Set;
022: import java.util.concurrent.Executor;
023:
024: import javax.jws.WebService;
025: import javax.xml.ws.Endpoint;
026:
027: import org.springframework.beans.factory.BeanFactory;
028: import org.springframework.beans.factory.BeanFactoryAware;
029: import org.springframework.beans.factory.DisposableBean;
030: import org.springframework.beans.factory.ListableBeanFactory;
031: import org.springframework.core.task.TaskExecutor;
032: import org.springframework.core.task.support.ConcurrentExecutorAdapter;
033:
034: /**
035: * Simple exporter for JAX-WS services, autodetecting annotation service beans
036: * (through the JAX-WS {@link javax.jws.WebService} annotation) and exporting
037: * them with a configured base address (by default "http://localhost:8080/").
038: * The full address for each service will consist of the base address with
039: * the service name appended (e.g. "http://localhost:8080/OrderService").
040: *
041: * <p>Note that this exporter will only work if the JAX-WS runtime actually
042: * supports publishing with an address argument, i.e. if the JAX-WS runtime
043: * ships an internal HTTP server. This is the case with the JAX-WS runtime
044: * that's inclued in Sun's JDK 1.6 but not with the standalone JAX-WS 2.1 RI.
045: *
046: * @author Juergen Hoeller
047: * @since 2.5
048: * @see javax.xml.ws.Endpoint#publish(String, Object)
049: */
050: public class SimpleJaxWsServiceExporter implements BeanFactoryAware,
051: DisposableBean {
052:
053: public static final String DEFAULT_BASE_ADDRESS = "http://localhost:8080/";
054:
055: private String baseAddress = DEFAULT_BASE_ADDRESS;
056:
057: private Executor executor;
058:
059: private Map<String, Object> endpointProperties;
060:
061: private final Set<Endpoint> publishedEndpoints = new LinkedHashSet<Endpoint>();
062:
063: /**
064: * Set the base address for exported services.
065: * Default is "http://localhost:8080/".
066: * <p>For each actual publication address, the service name will be
067: * appended to this base address. E.g. service name "OrderService"
068: * -> "http://localhost:8080/OrderService".
069: * @see javax.xml.ws.Endpoint#publish(String)
070: * @see javax.jws.WebService#serviceName()
071: */
072: public void setBaseAddress(String baseAddress) {
073: this .baseAddress = baseAddress;
074: }
075:
076: /**
077: * Set the JDK concurrent executor to use for dispatching incoming requests
078: * to exported service instances.
079: * @see javax.xml.ws.Endpoint#setExecutor
080: */
081: public void setExecutor(Executor executor) {
082: this .executor = executor;
083: }
084:
085: /**
086: * Set the Spring TaskExecutor to use for dispatching incoming requests
087: * to exported service instances.
088: * @see javax.xml.ws.Endpoint#setExecutor
089: */
090: public void setTaskExecutor(TaskExecutor executor) {
091: this .executor = new ConcurrentExecutorAdapter(executor);
092: }
093:
094: /**
095: * Set the property bag for the endpoint, including properties such as
096: * "javax.xml.ws.wsdl.service" or "javax.xml.ws.wsdl.port"
097: * @see javax.xml.ws.Endpoint#setProperties
098: * @see javax.xml.ws.Endpoint#WSDL_SERVICE
099: * @see javax.xml.ws.Endpoint#WSDL_PORT
100: */
101: public void setEndpointProperties(
102: Map<String, Object> endpointProperties) {
103: this .endpointProperties = endpointProperties;
104: }
105:
106: /**
107: * Obtains all web service beans and publishes them as JAX-WS endpoints.
108: */
109: public void setBeanFactory(BeanFactory beanFactory) {
110: if (!(beanFactory instanceof ListableBeanFactory)) {
111: throw new IllegalStateException(
112: "SimpleJaxWsServiceExporter requires a ListableBeanFactory");
113: }
114: ListableBeanFactory lbf = (ListableBeanFactory) beanFactory;
115: String[] beanNames = lbf.getBeanNamesForType(Object.class,
116: false, false);
117: for (String beanName : beanNames) {
118: Class<?> type = lbf.getType(beanName);
119: WebService annotation = type
120: .getAnnotation(WebService.class);
121: if (annotation != null) {
122: Endpoint endpoint = Endpoint.create(lbf
123: .getBean(beanName));
124: if (this .executor != null) {
125: endpoint.setExecutor(this .executor);
126: }
127: if (this .endpointProperties != null) {
128: endpoint.setProperties(this .endpointProperties);
129: }
130: String fullAddress = this .baseAddress
131: + annotation.serviceName();
132: endpoint.publish(fullAddress);
133: this .publishedEndpoints.add(endpoint);
134: }
135: }
136: }
137:
138: /**
139: * Stops all published endpoints, taking the web services offline.
140: */
141: public void destroy() {
142: for (Endpoint endpoint : this.publishedEndpoints) {
143: endpoint.stop();
144: }
145: }
146:
147: }
|