package org.talend.esb.mep.requestcallback.beans; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.namespace.QName; import javax.xml.ws.Dispatch; import javax.xml.ws.Endpoint; import org.apache.cxf.common.logging.LogUtils; import org.apache.cxf.endpoint.Client; import org.apache.cxf.jaxws.DispatchImpl; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; import org.apache.cxf.message.Message; import org.apache.cxf.service.model.EndpointInfo; import org.springframework.beans.factory.InitializingBean; import org.talend.esb.mep.requestcallback.feature.CallContext; import org.talend.esb.mep.requestcallback.feature.Configuration; public class JmsUriConfigurator implements InitializingBean { private static final Logger LOGGER = LogUtils.getL7dLogger(JmsUriConfigurator.class); private QName serviceName; private QName endpointName; private String configurationPrefix; private String workPrefix; private Configuration configuration; private String presetJmsAddress; private String variant; private String defaultVariant; private String destinationName; private String defaultDestinationName; private Map<?, ?> parameters; private Map<?, ?> defaultParameters; private String jmsAddress; private JmsUriConfiguration.UriEncoding encodeURI = JmsUriConfiguration.UriEncoding.PARTIAL; public JmsUriConfigurator() { super(); } public static JmsUriConfigurator create(Endpoint endpoint) { if (!(endpoint instanceof EndpointImpl)) { return null; } final EndpointImpl ep = (EndpointImpl) endpoint; final QName serviceName = ep.getServiceName(); if (serviceName == null) { return null; } final QName endpointName = ep.getEndpointName(); final String portName = endpointName == null ? null : endpointName.getLocalPart(); JmsUriConfigurator result = new JmsUriConfigurator(); result.setConfigurationPrefix(portName); result.setServiceName(serviceName); return result; } public static JmsUriConfigurator create(JaxWsServerFactoryBean factory) { if (factory == null) { return null; } final QName serviceName = factory.getServiceName(); if (serviceName == null) { return null; } final QName endpointName = factory.getEndpointName(); final String portName = endpointName == null ? null : endpointName.getLocalPart(); JmsUriConfigurator result = new JmsUriConfigurator(); result.setConfigurationPrefix(portName); result.setServiceName(serviceName); return result; } public static JmsUriConfigurator create(Dispatch<?> dispatch) { if (!(dispatch instanceof DispatchImpl<?>)) { return null; } DispatchImpl<?> dsp = (DispatchImpl<?>) dispatch; Client cl = dsp.getClient(); final QName serviceName; try { serviceName = cl.getEndpoint().getService().getName(); } catch (Exception e) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.log(Level.FINER, "Exception caught: ", e); } return null; } if (serviceName == null) { return null; } EndpointInfo endpointInfo; QName endpointName; String endpointAddress; try { endpointInfo = cl.getEndpoint().getEndpointInfo(); endpointName = endpointInfo.getName(); endpointAddress = endpointInfo.getAddress(); } catch (Exception e) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.log(Level.FINER, "Exception caught: ", e); } endpointInfo = null; endpointName = null; endpointAddress = null; } final String portName = endpointName == null ? null : endpointName.getLocalPart(); JmsUriConfigurator result = new JmsUriConfigurator(); result.setConfigurationPrefix(portName); result.setServiceName(serviceName); if (endpointAddress != null && endpointAddress.startsWith("jms:")) { result.setPresetJmsAddress(endpointAddress); } return result; } public <T> Dispatch<T> configureDispatch(Dispatch<T> dispatch) { if (!(dispatch instanceof DispatchImpl<?>) || (serviceName == null && configuration == null)) { return null; } final DispatchImpl<?> di = (DispatchImpl<?>) dispatch; final Client cl = di.getClient(); try { String jmsAddr = getJmsAddress(); cl.getRequestContext().put(Message.ENDPOINT_ADDRESS, jmsAddr); cl.getEndpoint().getEndpointInfo().setAddress(jmsAddr); } catch (Exception e) { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.log(Level.FINER, "Exception caught: ", e); } return null; } return dispatch; } public String getPresetJmsAddress() { return presetJmsAddress; } public void setPresetJmsAddress(String presetJmsAddress) { this.presetJmsAddress = presetJmsAddress; } public String getVariant() { return variant; } public void setVariant(String variant) { this.variant = variant; } public String getDefaultVariant() { return defaultVariant; } public void setDefaultVariant(String defaultVariant) { this.defaultVariant = defaultVariant; } public String getDestinationName() { return destinationName; } public void setDestinationName(String destinationName) { this.destinationName = destinationName; } public String getDefaultDestinationName() { return defaultDestinationName; } public void setDefaultDestinationName(String defaultDestinationName) { this.defaultDestinationName = defaultDestinationName; } public Map<?, ?> getParameters() { return parameters; } public void setParameters(Map<?, ?> parameters) { this.parameters = parameters; } public Map<?, ?> getDefaultParameters() { return defaultParameters; } public void setDefaultParameters(Map<?, ?> defaultParameters) { this.defaultParameters = defaultParameters; } public String getJmsAddress() { if (jmsAddress == null) { jmsAddress = createJmsAddress(); } return jmsAddress; } public String resetJmsAddress() { String result = jmsAddress; jmsAddress = null; return result; } public JmsUriConfiguration createJmsUriConfiguration() { if (configuration == null) { configuration = CallContext.resolveConfiguration(serviceName); } final JmsUriConfiguration jmsConfig = new JmsUriConfiguration(); String prop = getProperty("encodeURI"); if (nonzero(prop)) { try { setEncodeURI(prop); } catch (IllegalArgumentException e) { // ignore - incorrect value leaves default } } jmsConfig.setUriEncode(encodeURI); if (nonzero(defaultVariant)) { jmsConfig.setVariant(defaultVariant); } if (nonzero(defaultDestinationName)) { jmsConfig.setDestinationName(defaultDestinationName); } copyParams(defaultParameters, jmsConfig); prop = getProperty("jmsAddress"); if (nonzero(prop)) { jmsConfig.applyJmsUri(prop); } prop = getProperty("variant"); if (nonzero(prop)) { jmsConfig.setVariant(prop); } prop = getProperty("destinationName"); if (nonzero(prop)) { jmsConfig.setDestinationName(prop); } addConfigParamsTo(jmsConfig); if (nonzero(presetJmsAddress)) { jmsConfig.applyJmsUri(presetJmsAddress); } if (nonzero(variant)) { jmsConfig.setVariant(variant); } if (nonzero(destinationName)) { jmsConfig.setDestinationName(destinationName); } copyParams(parameters, jmsConfig); return jmsConfig; } public String createJmsAddress() { return createJmsUriConfiguration().toString(); } public QName getServiceName() { return serviceName; } public void setServiceName(String serviceName) { this.serviceName = validQName(serviceName); } public void setServiceName(QName serviceName) { this.serviceName = validQName(serviceName); } public QName getEndpointName() { return endpointName; } public void setEndpointName(String endpointName) { this.endpointName = validQName(endpointName); setConfigurationPrefix(); } public void setEndpointName(QName endpointName) { this.endpointName = validQName(endpointName); setConfigurationPrefix(); } public String getConfigurationPrefix() { return configurationPrefix; } public void setConfigurationPrefix(String configurationPrefix) { this.configurationPrefix = configurationPrefix; this.workPrefix = nonzero(configurationPrefix) ? configurationPrefix + "." : null; } public Configuration getConfiguration() { return configuration; } public void setConfiguration(Configuration configuration) { this.configuration = configuration; } public boolean isEncodeURI() { return encodeURI != JmsUriConfiguration.UriEncoding.NONE; } public void setEncodeURI(boolean encodeURIValue) { this.encodeURI = encodeURIValue ? JmsUriConfiguration.UriEncoding.PARTIAL : JmsUriConfiguration.UriEncoding.NONE; } public void setEncodeURI(String encodeURIValue) { encodeURI = JmsUriConfiguration.toUriEncoding(encodeURIValue); } @Override public void afterPropertiesSet() throws Exception { jmsAddress = createJmsAddress(); } private void setConfigurationPrefix() { setConfigurationPrefix( endpointName == null ? null : endpointName.getLocalPart()); } private String getProperty(String key) { String result = null; if (workPrefix != null) { result = configuration.getProperty(workPrefix + key); } return result == null ? configuration.getProperty(key) : result; } private void addConfigParamsTo(JmsUriConfiguration target) { if (nonzero(configuration)) { final Map<String, String> params = target.getParameters(); final List<String> excludes = new LinkedList<String>(); excludes.add("variant"); excludes.add("destinationName"); excludes.add("jmsAddress"); excludes.add("nonJmsAddress"); excludes.add("encodeURI"); if (workPrefix != null) { excludes.add(workPrefix + "variant"); excludes.add(workPrefix + "destinationName"); excludes.add(workPrefix + "jmsAddress"); excludes.add(workPrefix + "nonJmsAddress"); excludes.add(workPrefix + "encodeURI"); } for (Entry<String, Object> e : configuration.entrySet()) { final Object value = e.getValue(); if (value == null) { continue; } final String key = validKey(e.getKey(), excludes); if (key != null) { params.put((String) key, value.toString()); } } } } private String validKey(String sample, List<String> excludes) { if (sample == null || sample.length() == 0) { return null; } for (String exclude : excludes) { if (sample.equals(exclude)) { return null; } } final int ndx = sample.indexOf('.'); if (ndx < 0) { return sample; } if (workPrefix != null && sample.startsWith(workPrefix)) { final String s = sample.substring(workPrefix.length()); final int n = s.indexOf('.'); if (n >= 0) { return null; } excludes.add(s); return s; } return null; } private static void copyParams(Map<?, ?> source, JmsUriConfiguration target) { if (nonzero(source)) { final Map<String, String> params = target.getParameters(); for (Entry<?, ?> e : source.entrySet()) { final Object key = e.getKey(); final Object value = e.getValue(); if ((key instanceof String) && (value != null)) { params.put((String) key, value.toString()); } } } } private static boolean nonzero(String string) { return string != null && string.length() > 0; } private static boolean nonzero(Map<?, ?> map) { return map != null && !map.isEmpty(); } private static QName validQName(String value) { if (value == null) { return null; } if (value.startsWith("{")) { final int ndx = value.indexOf('}', 1); if (ndx < 0) { return null; } return new QName( value.substring(1, ndx), value.substring(ndx + 1)); } final int cndx = value.indexOf(':'); if (cndx < 0) { return new QName(value); } return new QName(value.substring(cndx + 1)); } private static QName validQName(QName qname) { if (qname == null) { return null; } if (nonzero(qname.getNamespaceURI())) { return qname; } return validQName(qname.getLocalPart()); } }