CAMEL-8509: camel-catalog - Add api to parse endpoint uri and reverse
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/62b53d0b Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/62b53d0b Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/62b53d0b Branch: refs/heads/camel-2.15.x Commit: 62b53d0b7d047dd79204ee3bbc8d0153d11b32a7 Parents: b8ecc4a Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Mar 19 10:50:13 2015 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Mar 19 10:50:31 2015 +0100 ---------------------------------------------------------------------- .../camel/catalog/DefaultCamelCatalog.java | 120 +++++++++++++++++-- .../apache/camel/catalog/JSonSchemaHelper.java | 60 +++++++++- .../org/apache/camel/catalog/URISupport.java | 14 +++ .../apache/camel/catalog/CamelCatalogTest.java | 38 ++++++ 4 files changed, 219 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/62b53d0b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java index 321b035..58e2069 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelCatalog.java @@ -22,6 +22,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -32,7 +33,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import static org.apache.camel.catalog.JSonSchemaHelper.getPropertyDefaultValue; +import static org.apache.camel.catalog.JSonSchemaHelper.isPropertyRequired; import static org.apache.camel.catalog.URISupport.createQueryString; +import static org.apache.camel.catalog.URISupport.stripQuery; /** * Default {@link CamelCatalog}. @@ -464,23 +468,80 @@ public class DefaultCamelCatalog implements CamelCatalog { throw new IllegalArgumentException("Endpoint with scheme " + scheme + " has no syntax defined in the json schema"); } - // grab the json schema for the endpoint properties - // rows = JSonSchemaHelper.parseJsonSchema("properties", json, true); + // parse the syntax and find the same group in the uri + Matcher matcher = SYNTAX_PATTERN.matcher(syntax); + List<String> word = new ArrayList<String>(); + while (matcher.find() ) { + String s = matcher.group(1); + if (!scheme.equals(s)) { + word.add(s); + } + } + + String uriPath = stripQuery(uri); + + Matcher matcher2 = SYNTAX_PATTERN.matcher(uriPath); + List<String> word2 = new ArrayList<String>(); + while (matcher2.find() ) { + String s = matcher2.group(1); + if (!scheme.equals(s)) { + word2.add(s); + } + } + + rows = JSonSchemaHelper.parseJsonSchema("properties", json, true); + + boolean defaultValueAdded = false; // now parse the uri to know which part isw what + Map<String, String> options = new LinkedHashMap<String, String>(); + + // word contains the syntax path elements + Iterator<String> it = word2.iterator(); + for (int i = 0; i < word.size(); i++) { + String key = word.get(i); + + boolean allOptions = word.size() == word2.size(); + boolean required = isPropertyRequired(rows, key); + String defaultValue = getPropertyDefaultValue(rows, key); + + // we have all options so no problem + if (allOptions) { + String value = it.next(); + options.put(key, value); + } else { + // we have a little problem as we do not not have all options + if (!required) { + String value = defaultValue; + options.put(key, value); + defaultValueAdded = true; + } else { + String value = it.next(); + options.put(key, value); + } + } + } + Map<String, String> answer = new LinkedHashMap<String, String>(); - // parse the syntax and find the same group in the uri + // remove all options which are using default values and are not required + for (Map.Entry<String, String> entry : options.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); - Matcher matcher = SYNTAX_PATTERN.matcher(syntax); - Matcher matcher2 = SYNTAX_PATTERN.matcher(uri); - while (matcher.find() && matcher2.find()) { - String word = matcher.group(1); - String word2 = matcher2.group(1); - // skip the scheme as we know that already - if (!scheme.equals(word)) { - answer.put(word, word2); + if (defaultValueAdded) { + boolean required = isPropertyRequired(rows, key); + String defaultValue = getPropertyDefaultValue(rows, key); + + if (!required && defaultValue != null) { + if (defaultValue.equals(value)) { + continue; + } + } } + + // we should keep this in the answer + answer.put(key, value); } // now parse the uri parameters @@ -553,6 +614,8 @@ public class DefaultCamelCatalog implements CamelCatalog { throw new IllegalArgumentException("Endpoint with scheme " + scheme + " has no syntax defined in the json schema"); } + String originalSyntax = syntax; + // build at first according to syntax Map<String, String> copy = new HashMap<String, String>(); for (Map.Entry<String, String> entry : properties.entrySet()) { @@ -565,7 +628,40 @@ public class DefaultCamelCatalog implements CamelCatalog { } } - StringBuilder sb = new StringBuilder(syntax); + rows = JSonSchemaHelper.parseJsonSchema("properties", json, true); + + // the tokens between the options in the path + String[] tokens = syntax.split("\\w+"); + + // parse the syntax into each options + Matcher matcher = SYNTAX_PATTERN.matcher(originalSyntax); + List<String> options = new ArrayList<String>(); + while (matcher.find() ) { + String s = matcher.group(1); + options.add(s); + } + + // parse the syntax into each options + Matcher matcher2 = SYNTAX_PATTERN.matcher(syntax); + List<String> options2 = new ArrayList<String>(); + while (matcher2.find() ) { + String s = matcher2.group(1); + options2.add(s); + } + + // build the endpoint + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < options.size(); i++) { + String key = options.get(i); + String key2 = options2.get(i); + String token = tokens[i]; + + // was the option provided? + if (i == 0 || properties.containsKey(key)) { + sb.append(token); + sb.append(key2); + } + } if (!copy.isEmpty()) { sb.append('?'); String query = createQueryString(copy); http://git-wip-us.apache.org/repos/asf/camel/blob/62b53d0b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java index a1c5fb8..f9f628a 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/JSonSchemaHelper.java @@ -25,7 +25,8 @@ import java.util.regex.Pattern; public final class JSonSchemaHelper { - private static final Pattern PATTERN = Pattern.compile("\"(.+?)\""); + private static final Pattern PATTERN = Pattern.compile("\"(.+?)\"|\\[(.+)\\]"); + private static final String QUOT = """; private JSonSchemaHelper() { } @@ -60,6 +61,9 @@ public final class JSonSchemaHelper { break; } + // need to safe encode \" so we can parse the line + line = line.replaceAll("\"\\\\\"\"", '"' + QUOT + '"'); + Map<String, String> row = new LinkedHashMap<String, String>(); Matcher matcher = PATTERN.matcher(line); @@ -75,6 +79,18 @@ public final class JSonSchemaHelper { key = matcher.group(1); } else { String value = matcher.group(1); + if (value == null) { + value = matcher.group(2); + // its an enum so strip out " and trim spaces after comma + value = value.replaceAll("\"", ""); + value = value.replaceAll(", ", ","); + } + if (value != null) { + value = value.trim(); + // decode + value = value.replaceAll(QUOT, "\""); + value = decodeJson(value); + } row.put(key, value); // reset key = null; @@ -88,4 +104,46 @@ public final class JSonSchemaHelper { return answer; } + private static String decodeJson(String value) { + // json encodes a \ as \\ so we need to decode from \\ back to \ + if ("\\\\".equals(value)) { + value = "\\"; + } + return value; + } + + public static boolean isPropertyRequired(List<Map<String, String>> rows, String name) { + for (Map<String, String> row : rows) { + boolean required = false; + boolean found = false; + if (row.containsKey("name")) { + found = name.equals(row.get("name")); + } + if (row.containsKey("required")) { + required = "true".equals(row.get("required")); + } + if (found) { + return required; + } + } + return false; + } + + public static String getPropertyDefaultValue(List<Map<String, String>> rows, String name) { + for (Map<String, String> row : rows) { + String defaultValue = null; + boolean found = false; + if (row.containsKey("name")) { + found = name.equals(row.get("name")); + } + if (row.containsKey("defaultValue")) { + defaultValue = row.get("defaultValue"); + } + if (found) { + return defaultValue; + } + } + return null; + } + } http://git-wip-us.apache.org/repos/asf/camel/blob/62b53d0b/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java index 9876568..ea62581 100644 --- a/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java +++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/URISupport.java @@ -41,6 +41,20 @@ public final class URISupport { } /** + * Strips the query parameters from the uri + * + * @param uri the uri + * @return the uri without the query parameter + */ + public static String stripQuery(String uri) { + int idx = uri.indexOf('?'); + if (idx > -1) { + uri = uri.substring(0, idx); + } + return uri; + } + + /** * Parses the query parameters of the uri (eg the query part). * * @param uri the uri http://git-wip-us.apache.org/repos/asf/camel/blob/62b53d0b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java ---------------------------------------------------------------------- diff --git a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java index 93c179f..3e2913d 100644 --- a/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java +++ b/platforms/catalog/src/test/java/org/apache/camel/catalog/CamelCatalogTest.java @@ -104,6 +104,25 @@ public class CamelCatalogTest extends TestCase { } @Test + public void testAsEndpointUriMapJms() throws Exception { + Map<String, String> map = new HashMap<String, String>(); + map.put("destinationType", "queue"); + map.put("destinationName", "foo"); + + String uri = catalog.asEndpointUri("jms", map); + assertEquals("jms:queue:foo", uri); + } + + @Test + public void testAsEndpointUriMapJmsRequiredOnly() throws Exception { + Map<String, String> map = new HashMap<String, String>(); + map.put("destinationName", "foo"); + + String uri = catalog.asEndpointUri("jms", map); + assertEquals("jms:foo", uri); + } + + @Test public void testAsEndpointUriJson() throws Exception { String json = loadText(CamelCatalogTest.class.getClassLoader().getResourceAsStream("sample.json")); String uri = catalog.asEndpointUri("ftp", json); @@ -122,4 +141,23 @@ public class CamelCatalogTest extends TestCase { assertEquals("5000", map.get("connectTimeout")); } + @Test + public void testEndpointPropertiesJms() throws Exception { + Map<String, String> map = catalog.endpointProperties("jms:queue:foo"); + assertNotNull(map); + assertEquals(2, map.size()); + + assertEquals("queue", map.get("destinationType")); + assertEquals("foo", map.get("destinationName")); + } + + @Test + public void testEndpointPropertiesJmsRequired() throws Exception { + Map<String, String> map = catalog.endpointProperties("jms:foo"); + assertNotNull(map); + assertEquals(1, map.size()); + + assertEquals("foo", map.get("destinationName")); + } + }