/*
* Copyright 2005-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.soap.addressing.server;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.BeansException;
/**
* Implementation of the {@code EndpointMapping} interface to map from WS-Addressing {@code Action} Message
* Addressing Property to endpoint beans. Supports both mapping to bean instances and mapping to bean names.
*
* <p>The {@code endpointMap} property is suitable for populating the endpoint map with bean references, e.g. via the
* map element in XML bean definitions.
*
* <p>Mappings to bean names can be set via the {@code mappings} property, in a form accepted by the
* {@code java.util.Properties} class, like as follows:
* <pre>
* http://www.springframework.org/spring-ws/samples/airline/BookFlight=bookFlightEndpoint
* http://www.springframework.org/spring-ws/samples/airline/GetFlights=getFlightsEndpoint
* </pre>
* The syntax is WS_ADDRESSING_ACTION=ENDPOINT_BEAN_NAME.
*
* <p>If set, the {@link #setAddress(URI) address} property should be equal to the {@link
* org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo() destination} property of the
* incominging message. As such, it can be used to create multiple Endpoint References, by defining multiple
* {@code SimpleActionEndpointMapping} bean definitions with different {@code address} property values.
*
* @author Arjen Poutsma
* @see org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getAction()
* @since 1.5.0
*/
public class SimpleActionEndpointMapping extends AbstractActionEndpointMapping {
// contents will be copied over to endpointMap
private final Map<URI, Object> actionMap = new HashMap<URI, Object>();
private URI address;
/**
* Map action URIs to endpoint bean names. This is the typical way of configuring this EndpointMapping.
*
* @param mappings properties with URLs as keys and bean names as values
* @see #setActionMap(java.util.Map)
*/
public void setMappings(Properties mappings) throws URISyntaxException {
setActionMap(mappings);
}
/**
* Set a Map with action URIs as keys and handler beans (or handler bean names) as values. Convenient for population
* with bean references.
*
* @param actionMap map with action URIs as keys and beans as values
* @see #setMappings
*/
public void setActionMap(Map<?, Object> actionMap) throws URISyntaxException {
for (Map.Entry<?, Object> entry : actionMap.entrySet()) {
URI action;
if (entry.getKey() instanceof String) {
action = new URI((String) entry.getKey());
}
else if (entry.getKey() instanceof URI) {
action = (URI) entry.getKey();
}
else {
throw new IllegalArgumentException("Invalid key [" + entry.getKey() + "]; expected String or URI");
}
this.actionMap.put(action, entry.getValue());
}
}
/**
* Set the address property. If set, value of this property is compared to the {@link
* org.springframework.ws.soap.addressing.core.MessageAddressingProperties#getTo() destination} property of the
* incominging message.
*
* @param address the address URI
*/
public void setAddress(URI address) {
this.address = address;
}
@Override
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
registerEndpoints(actionMap);
}
/**
* Register all endpoints specified in the action map.
*
* @param actionMap Map with action URIs as keys and endppint beans or bean names as values
* @throws BeansException if an endpoint couldn't be registered
* @throws IllegalStateException if there is a conflicting endpoint registered
*/
protected void registerEndpoints(Map<URI, Object> actionMap) throws BeansException {
if (actionMap.isEmpty()) {
logger.warn("Neither 'actionMap' nor 'mappings' set on SimpleActionEndpointMapping");
}
else {
for (Map.Entry<URI, Object> entry : actionMap.entrySet()) {
URI action = entry.getKey();
Object endpoint = entry.getValue();
// Remove whitespace from endpoint bean name.
if (endpoint instanceof String) {
endpoint = ((String) endpoint).trim();
}
registerEndpoint(action, endpoint);
}
}
}
@Override
protected URI getEndpointAddress(Object endpoint) {
return address;
}
}