package org.talend.esb.mep.requestcallback.beans;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.StringTokenizer;
import java.util.TreeMap;
public class JmsUriConfiguration {
public enum UriEncoding {
NONE, PARTIAL, FULL
}
private String variant = null;
private String destinationName = null;
private final NavigableMap<String, String> parameters = new TreeMap<String, String>();
private UriEncoding uriEncode = UriEncoding.PARTIAL;
private boolean validate = true;
public JmsUriConfiguration() {
super();
}
public String getVariant() {
return variant;
}
public void setVariant(String variant) {
if (variant == null) {
this.variant = null;
return;
}
if ("jndi".equalsIgnoreCase(variant)) {
this.variant = "jndi";
return;
}
if ("jndi-topic".equalsIgnoreCase(variant)) {
this.variant = "jndi-topic";
return;
}
if ("queue".equalsIgnoreCase(variant)) {
this.variant = "queue";
return;
}
if ("topic".equalsIgnoreCase(variant)) {
this.variant = "topic";
return;
}
if (validate) {
throw new IllegalArgumentException("Unknown JMS variant " + variant);
}
this.variant = variant;
}
public String getDestinationName() {
return destinationName;
}
public void setDestinationName(String destinationName) {
this.destinationName = destinationName;
}
@Deprecated
public boolean isEncode() {
return uriEncode != UriEncoding.NONE;
}
@Deprecated
public void setEncode(boolean encode) {
this.uriEncode = encode ? UriEncoding.PARTIAL : UriEncoding.NONE;
}
public UriEncoding getUriEncode() {
return uriEncode;
}
public void setUriEncode(UriEncoding uriEncode) {
this.uriEncode = uriEncode;
}
public void setUriEncode(String uriEncodeValue) {
this.uriEncode = toUriEncoding(uriEncodeValue);
}
public boolean isValidate() {
return validate;
}
public void setValidate(boolean validate) {
this.validate = validate;
}
public String getParameter(String name) {
return parameters.get(name);
}
public String putParameter(String name, String value) {
return parameters.put(name, value);
}
public NavigableMap<String, String> getParameters() {
return parameters;
}
public NavigableMap<String, String> getJndiEnvironmentParameters() {
return parameters.subMap("jndi-", false, "jndi.", false);
}
public void applyJmsUri(String jmsUri) {
if (jmsUri == null || jmsUri.length() == 0 || "jms://".equalsIgnoreCase(jmsUri)) {
return;
}
int ndx = extractPrefix(jmsUri);
ndx = extractVariant(jmsUri, ndx);
ndx = extractDestinationName(jmsUri, ndx);
ndx = extractParameters(jmsUri, ndx);
if (validate && ndx >= 0) {
throw new IllegalArgumentException("Fragment not supported in JMS URI ");
}
}
public void clear() {
variant = null;
destinationName = null;
parameters.clear();
}
public String toString() {
if (variant == null || variant.isEmpty()
|| destinationName == null || destinationName.isEmpty()) {
return "jms://";
}
final StringBuilder buf = new StringBuilder("jms:");
buf.append(variant).append(':').append(encode(destinationName));
if (!parameters.isEmpty()) {
buf.append('?');
boolean addDelimiter = false;
for (Entry<String, String> param : parameters.entrySet()) {
if (addDelimiter) {
buf.append('&');
} else {
addDelimiter = true;
}
buf.append(encode(param.getKey()));
final String value = param.getValue();
if (value != null && value.length() > 0) {
buf.append('=').append(encode(value));
}
}
}
return buf.toString();
}
public static UriEncoding toUriEncoding(String uriEncodeValue) {
if (uriEncodeValue == null) {
throw new IllegalArgumentException("Invalid URI encoding option value: null");
}
if ("none".equalsIgnoreCase(uriEncodeValue) ||
"false".equalsIgnoreCase(uriEncodeValue) ||
"no".equalsIgnoreCase(uriEncodeValue) ||
"n".equalsIgnoreCase(uriEncodeValue) ||
"off".equalsIgnoreCase(uriEncodeValue)) {
return UriEncoding.NONE;
}
if ("partial".equalsIgnoreCase(uriEncodeValue) ||
"true".equalsIgnoreCase(uriEncodeValue) ||
"yes".equalsIgnoreCase(uriEncodeValue) ||
"y".equalsIgnoreCase(uriEncodeValue) ||
"on".equalsIgnoreCase(uriEncodeValue)) {
return UriEncoding.PARTIAL;
}
if ("full".equalsIgnoreCase(uriEncodeValue)) {
return UriEncoding.FULL;
}
throw new IllegalArgumentException(
"Invalid URI encoding option value: " + uriEncodeValue + ". ");
}
private int extractPrefix(String jmsUri) {
final int strLen = jmsUri.length();
if (strLen < 4 || !"jms:".equalsIgnoreCase(jmsUri.substring(0, 4))) {
throw new IllegalArgumentException("Not a JMS URI: " + jmsUri);
}
return strLen == 4 ? -1 : 4;
}
private int extractVariant(String jmsUri, int startIndex) {
if (startIndex < 0) {
return -1;
}
final int endIndex = jmsUri.indexOf(':', startIndex);
final String v = endIndex < 0
? jmsUri.substring(startIndex)
: jmsUri.substring(startIndex, endIndex);
if (v.length() > 0) {
setVariant(v);
}
return currentEndIndex(endIndex, jmsUri.length());
}
private int extractDestinationName(String jmsUri, int startIndex) {
if (startIndex < 0) {
return -1;
}
final int strLen = jmsUri.length();
int bracketLevel = 0;
for (int endIndex = startIndex; endIndex < strLen; endIndex++) {
switch (jmsUri.charAt(endIndex)) {
case '?':
if (bracketLevel <= 0) {
final String dName = decode(jmsUri.substring(startIndex, endIndex));
if (dName.length() > 0) {
destinationName = dName;
}
return currentEndIndex(endIndex, strLen);
}
break;
case '(':
++bracketLevel;
break;
case ')':
--bracketLevel;
break;
default:
break;
}
}
final String dName = decode(jmsUri.substring(startIndex));
if (dName.length() > 0) {
destinationName = dName;
}
return -1;
}
private int extractParameters(String jmsUri, int startIndex) {
if (startIndex < 0) {
return -1;
}
final int endIndex = jmsUri.indexOf('#', startIndex);
final String queryString = endIndex < 0
? jmsUri.substring(startIndex)
: jmsUri.substring(startIndex, endIndex);
addParametersFromQueryString(queryString);
return currentEndIndex(endIndex, jmsUri.length());
}
private void addParametersFromQueryString(String queryString) {
if (queryString == null || queryString.length() == 0) {
return;
}
final StringTokenizer params = new StringTokenizer(queryString, "&", false);
while (params.hasMoreTokens()) {
final String rawEntry = params.nextToken();
final int ndx = rawEntry.indexOf('=');
if (ndx < 0) {
final String key = decode(rawEntry);
parameters.put(key, "");
} else {
final String key = decode(rawEntry.substring(0, ndx));
final String value = decode(rawEntry.substring(ndx + 1));
parameters.put(key, value);
}
}
}
private String decode(String enc) {
if (uriEncode == UriEncoding.NONE) {
return enc;
}
try {
return URLDecoder.decode(enc, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unexpected Exception: ", e);
}
}
private String encode(String enc) {
if (uriEncode == UriEncoding.NONE) {
return enc;
}
try {
String result = URLEncoder.encode(enc, "UTF-8");
return uriEncode == UriEncoding.FULL ? result : result.replace("%2F", "/").replace("%3A", ":").
replace("%28", "(").replace("%29", ")").replace("%2C", ",").replace("%3D", "=");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unexpected Exception: ", e);
}
}
private static int currentEndIndex(int markIndex, int strlen) {
if (markIndex < 0) {
return -1;
}
int rawResult = markIndex + 1;
return rawResult < strlen ? rawResult : -1;
}
}