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 = "&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"));
+    }
+
 }

Reply via email to