You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2014/12/30 11:42:34 UTC

[18/29] camel git commit: CAMEL-7999: apt compiler to generate json schema documentation for the model, whcih we later use to enrich the xml xsd to include documentation. Work in progress.

CAMEL-7999: apt compiler to generate json schema documentation for the model, whcih we later use to enrich the xml xsd to include documentation. Work in progress.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/fe630137
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/fe630137
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/fe630137

Branch: refs/heads/master
Commit: fe6301375867250cab9b63788e4e9a155665d0ba
Parents: 81890fa
Author: Claus Ibsen <da...@apache.org>
Authored: Sat Dec 27 14:57:51 2014 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Tue Dec 30 10:56:44 2014 +0100

----------------------------------------------------------------------
 .../camel/catalog/CamelComponentCatalog.java    |  27 ++-
 .../catalog/DefaultCamelComponentCatalog.java   |  89 +++++++++-
 .../camel/commands/AbstractCamelController.java |  71 +++++++-
 .../apache/camel/commands/CamelController.java  |  19 ++-
 .../CatalogComponentLabelListCommand.java       | 165 ++++++++++++++++++
 .../camel/commands/CatalogLabelListCommand.java | 165 ------------------
 .../commands/CatalogModelLabelListCommand.java  | 165 ++++++++++++++++++
 .../camel/commands/CatalogModelListCommand.java | 171 +++++++++++++++++++
 .../catalog/CamelComponentCatalogTest.java      |   2 +-
 .../commands/catalog/CamelModelCatalogTest.java | 100 +++++++++++
 .../commands/CatalogComponentLabelList.java     |  35 ++++
 .../camel/karaf/commands/CatalogLabelList.java  |  35 ----
 .../karaf/commands/CatalogModelLabelList.java   |  35 ++++
 .../camel/karaf/commands/CatalogModelList.java  |  39 +++++
 .../OSGI-INF/blueprint/camel-commands.xml       |  12 +-
 .../maven/packaging/PrepareCatalogMojo.java     |  40 +++++
 16 files changed, 963 insertions(+), 207 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelComponentCatalog.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelComponentCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelComponentCatalog.java
index 7f23733..e522681 100644
--- a/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelComponentCatalog.java
+++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/CamelComponentCatalog.java
@@ -30,11 +30,29 @@ public interface CamelComponentCatalog {
     List<String> findComponentNames();
 
     /**
+     * Find all the model names from the Camel catalog
+     */
+    List<String> findModelNames();
+
+    /**
+     * Find all the model names from the Camel catalog that matches the label
+     */
+    List<String> findModelNames(String label);
+
+    /**
      * Find all the component names from the Camel catalog that matches the label
      */
     List<String> findComponentNames(String label);
 
     /**
+     * Returns the model information as JSon format.
+     *
+     * @param name the model name
+     * @return model details in JSon
+     */
+    String modelJSonSchema(String name);
+
+    /**
      * Returns the component information as JSon format.
      *
      * @param name the component name
@@ -43,9 +61,16 @@ public interface CamelComponentCatalog {
     String componentJSonSchema(String name);
 
     /**
+     * Find all the unique label names all the models are using.
+     *
+     * @return a set of all the labels.
+     */
+    Set<String> findModelLabels();
+
+    /**
      * Find all the unique label names all the components are using.
      *
      * @return a set of all the labels.
      */
-    Set<String> findLabels();
+    Set<String> findComponentLabels();
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelComponentCatalog.java
----------------------------------------------------------------------
diff --git a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelComponentCatalog.java b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelComponentCatalog.java
index d520967..805b0d1 100644
--- a/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelComponentCatalog.java
+++ b/platforms/catalog/src/main/java/org/apache/camel/catalog/DefaultCamelComponentCatalog.java
@@ -34,7 +34,9 @@ import java.util.regex.PatternSyntaxException;
  */
 public class DefaultCamelComponentCatalog implements CamelComponentCatalog {
 
+    private static final String MODELS_CATALOG = "org/apache/camel/catalog/models.properties";
     private static final String COMPONENTS_CATALOG = "org/apache/camel/catalog/components.properties";
+    private static final String MODEL_JSON = "org/apache/camel/catalog/models";
     private static final String COMPONENTS_JSON = "org/apache/camel/catalog/components";
 
     @Override
@@ -53,6 +55,51 @@ public class DefaultCamelComponentCatalog implements CamelComponentCatalog {
     }
 
     @Override
+    public List<String> findModelNames() {
+        List<String> names = new ArrayList<String>();
+
+        InputStream is = DefaultCamelComponentCatalog.class.getClassLoader().getResourceAsStream(MODELS_CATALOG);
+        if (is != null) {
+            try {
+                loadLines(is, names);
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+        return names;
+    }
+
+    @Override
+    public List<String> findModelNames(String filter) {
+        List<String> answer = new ArrayList<String>();
+
+        List<String> names = findModelNames();
+        for (String name : names) {
+            String json = modelJSonSchema(name);
+            if (json != null) {
+                List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("model", json, false);
+                for (Map<String, String> row : rows) {
+                    if (row.containsKey("label")) {
+                        String label = row.get("label");
+                        String[] parts = label.split(",");
+                        for (String part : parts) {
+                            try {
+                                if (part.equalsIgnoreCase(filter) || matchWildcard(part, filter) || part.matches(filter)) {
+                                    answer.add(name);
+                                }
+                            } catch (PatternSyntaxException e) {
+                                // ignore as filter is maybe not a pattern
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    @Override
     public List<String> findComponentNames(String filter) {
         List<String> answer = new ArrayList<String>();
 
@@ -83,6 +130,22 @@ public class DefaultCamelComponentCatalog implements CamelComponentCatalog {
     }
 
     @Override
+    public String modelJSonSchema(String name) {
+        String file = MODEL_JSON + "/" + name + ".json";
+
+        InputStream is = DefaultCamelComponentCatalog.class.getClassLoader().getResourceAsStream(file);
+        if (is != null) {
+            try {
+                return loadText(is);
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+
+        return null;
+    }
+
+    @Override
     public String componentJSonSchema(String name) {
         String file = COMPONENTS_JSON + "/" + name + ".json";
 
@@ -99,7 +162,31 @@ public class DefaultCamelComponentCatalog implements CamelComponentCatalog {
     }
 
     @Override
-    public Set<String> findLabels() {
+    public Set<String> findModelLabels() {
+        SortedSet<String> answer = new TreeSet<String>();
+
+        List<String> names = findModelNames();
+        for (String name : names) {
+            String json = modelJSonSchema(name);
+            if (json != null) {
+                List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("model", json, false);
+                for (Map<String, String> row : rows) {
+                    if (row.containsKey("label")) {
+                        String label = row.get("label");
+                        String[] parts = label.split(",");
+                        for (String part : parts) {
+                            answer.add(part);
+                        }
+                    }
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    @Override
+    public Set<String> findComponentLabels() {
         SortedSet<String> answer = new TreeSet<String>();
 
         List<String> names = findComponentNames();

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java
index deea95d..38fc810 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java
@@ -37,6 +37,51 @@ public abstract class AbstractCamelController implements CamelController {
     private CamelComponentCatalog catalog = new DefaultCamelComponentCatalog();
 
     @Override
+    public List<Map<String, String>> listModelsCatalog(String filter) throws Exception {
+        List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
+
+        if (filter != null) {
+            filter = RegexUtil.wildcardAsRegex(filter);
+        }
+
+        List<String> names = filter != null ? catalog.findModelNames(filter) : catalog.findModelNames();
+        for (String name : names) {
+            // load models json data, and parse it to gather the model meta-data
+            String json = catalog.modelJSonSchema(name);
+            List<Map<String, String>> rows = JsonSchemaHelper.parseJsonSchema("model", json, false);
+
+            String description = null;
+            String label = null;
+            String type = null;
+            for (Map<String, String> row : rows) {
+                if (row.containsKey("description")) {
+                    description = row.get("description");
+                } else if (row.containsKey("label")) {
+                    label = row.get("label");
+                } else if (row.containsKey("javaType")) {
+                    type = row.get("javaType");
+                }
+            }
+
+            Map<String, String> row = new HashMap<String, String>();
+            row.put("name", name);
+            if (description != null) {
+                row.put("description", description);
+            }
+            if (label != null) {
+                row.put("label", label);
+            }
+            if (type != null) {
+                row.put("type", type);
+            }
+
+            answer.add(row);
+        }
+
+        return answer;
+    }
+
+    @Override
     public List<Map<String, String>> listComponentsCatalog(String filter) throws Exception {
         List<Map<String, String>> answer = new ArrayList<Map<String, String>>();
 
@@ -106,10 +151,32 @@ public abstract class AbstractCamelController implements CamelController {
     }
 
     @Override
-    public Map<String, Set<String>> listLabelCatalog() throws Exception {
+    public Map<String, Set<String>> listModelsLabelCatalog() throws Exception {
+        Map<String, Set<String>> answer = new LinkedHashMap<String, Set<String>>();
+
+        Set<String> labels = catalog.findModelLabels();
+        for (String label : labels) {
+            List<Map<String, String>> models = listModelsCatalog(label);
+            if (!models.isEmpty()) {
+                Set<String> names = new LinkedHashSet<String>();
+                for (Map<String, String> info : models) {
+                    String name = info.get("name");
+                    if (name != null) {
+                        names.add(name);
+                    }
+                }
+                answer.put(label, names);
+            }
+        }
+
+        return answer;
+    }
+
+    @Override
+    public Map<String, Set<String>> listComponentsLabelCatalog() throws Exception {
         Map<String, Set<String>> answer = new LinkedHashMap<String, Set<String>>();
 
-        Set<String> labels = catalog.findLabels();
+        Set<String> labels = catalog.findComponentLabels();
         for (String label : labels) {
             List<Map<String, String>> components = listComponentsCatalog(label);
             if (!components.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
index 0065fdf..291cccf 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
@@ -218,6 +218,23 @@ public interface CamelController {
     List<Map<String, String>> listComponents(String camelContextName) throws Exception;
 
     /**
+     * Lists all models from the Camel models catalog
+     *
+     * @param filter optional filter to filter by labels
+     * @return a list of key/value pairs with model information
+     * @throws java.lang.Exception can be thrown
+     */
+    List<Map<String, String>> listModelsCatalog(String filter) throws Exception;
+
+    /**
+     * Lists all the labels from the Camel models catalog
+     *
+     * @return a map which key is the label, and the set is the models names that has the given label
+     * @throws java.lang.Exception can be thrown
+     */
+    Map<String, Set<String>> listModelsLabelCatalog() throws Exception;
+
+    /**
      * Lists all components from the Camel components catalog
      *
      * @param filter optional filter to filter by labels
@@ -232,6 +249,6 @@ public interface CamelController {
      * @return a map which key is the label, and the set is the component names that has the given label
      * @throws java.lang.Exception can be thrown
      */
-    Map<String, Set<String>> listLabelCatalog() throws Exception;
+    Map<String, Set<String>> listComponentsLabelCatalog() throws Exception;
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogComponentLabelListCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogComponentLabelListCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogComponentLabelListCommand.java
new file mode 100644
index 0000000..4cc2c3c
--- /dev/null
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogComponentLabelListCommand.java
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.commands;
+
+import java.io.PrintStream;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.util.CollectionStringBuffer;
+
+/**
+ * From the Camel catalog lists all the component labels.
+ */
+public class CatalogComponentLabelListCommand extends AbstractCamelCommand {
+
+    private static final String LABEL_COLUMN_LABEL = "Label";
+    private static final String NUMBER_COLUMN_LABEL = "#";
+    private static final String NAME_COLUMN_LABEL = "Name";
+
+    private static final int DEFAULT_COLUMN_WIDTH_INCREMENT = 0;
+    private static final String DEFAULT_FIELD_PREAMBLE = " ";
+    private static final String DEFAULT_FIELD_POSTAMBLE = " ";
+    private static final String DEFAULT_HEADER_PREAMBLE = " ";
+    private static final String DEFAULT_HEADER_POSTAMBLE = " ";
+    private static final int DEFAULT_FORMAT_BUFFER_LENGTH = 24;
+    // descriptions can be very long so clip by default after 120 chars
+    private static final int MAX_COLUMN_WIDTH = 120;
+    private static final int MIN_COLUMN_WIDTH = 12;
+    private static final int MIN_NUMBER_COLUMN_WIDTH = 6;
+
+    private boolean verbose;
+
+    public CatalogComponentLabelListCommand(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    @Override
+    public Object execute(CamelController camelController, PrintStream out, PrintStream err) throws Exception {
+        Map<String, Set<String>> labels = camelController.listComponentsLabelCatalog();
+
+        if (labels.isEmpty()) {
+            return null;
+        }
+
+        final Map<String, Integer> columnWidths = computeColumnWidths(labels);
+        final String headerFormat = buildFormatString(columnWidths, true);
+        final String rowFormat = buildFormatString(columnWidths, false);
+
+        if (verbose) {
+            out.println(String.format(headerFormat, LABEL_COLUMN_LABEL, NUMBER_COLUMN_LABEL, NAME_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "-----", "-", "----"));
+        } else {
+            out.println(String.format(headerFormat, LABEL_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "-----"));
+        }
+
+        for (Map.Entry<String, Set<String>> row : labels.entrySet()) {
+            if (verbose) {
+                String label = row.getKey();
+                String number = "" + row.getValue().size();
+                CollectionStringBuffer csb = new CollectionStringBuffer(", ");
+                for (String name : row.getValue()) {
+                    csb.append(name);
+                }
+                out.println(String.format(rowFormat, label, number, csb.toString()));
+            } else {
+                String label = row.getKey();
+                out.println(String.format(rowFormat, label));
+            }
+        }
+
+        return null;
+    }
+
+    private Map<String, Integer> computeColumnWidths(Map<String, Set<String>> labels) throws Exception {
+        if (labels == null) {
+            return null;
+        } else {
+            // some of the options is optional so we need to start from 1
+            int maxLabelLen = LABEL_COLUMN_LABEL.length();
+            int maxNameLen = NAME_COLUMN_LABEL.length();
+
+            int counter = 0;
+            CollectionStringBuffer csb = new CollectionStringBuffer(", ");
+            for (Map.Entry<String, Set<String>> entry : labels.entrySet()) {
+                String label = entry.getKey();
+                maxLabelLen = Math.max(maxLabelLen, label.length());
+                for (String name : entry.getValue()) {
+                    counter++;
+                    csb.append(name);
+                }
+            }
+            maxNameLen = Math.max(maxNameLen, csb.toString().length());
+            int maxMumberLen = ("" + counter).length();
+
+            final Map<String, Integer> retval = new Hashtable<String, Integer>();
+            retval.put(LABEL_COLUMN_LABEL, maxLabelLen);
+            retval.put(NUMBER_COLUMN_LABEL, maxMumberLen);
+            retval.put(NAME_COLUMN_LABEL, maxNameLen);
+
+            return retval;
+        }
+    }
+
+    private String buildFormatString(Map<String, Integer> columnWidths, boolean isHeader) {
+        final String fieldPreamble;
+        final String fieldPostamble;
+        final int columnWidthIncrement;
+
+        if (isHeader) {
+            fieldPreamble = DEFAULT_HEADER_PREAMBLE;
+            fieldPostamble = DEFAULT_HEADER_POSTAMBLE;
+        } else {
+            fieldPreamble = DEFAULT_FIELD_PREAMBLE;
+            fieldPostamble = DEFAULT_FIELD_POSTAMBLE;
+        }
+        columnWidthIncrement = DEFAULT_COLUMN_WIDTH_INCREMENT;
+
+        if (verbose) {
+            int labelLen = Math.min(columnWidths.get(LABEL_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
+            int numberLen = Math.min(columnWidths.get(NUMBER_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
+
+            labelLen = Math.max(MIN_COLUMN_WIDTH, labelLen);
+            numberLen = Math.max(MIN_NUMBER_COLUMN_WIDTH, numberLen);
+
+            final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+            retval.append(fieldPreamble).append("%-").append(labelLen).append('.').append(labelLen).append('s').append(fieldPostamble).append(' ');
+            retval.append(fieldPreamble).append("%-").append(numberLen).append('.').append(numberLen).append('s').append(fieldPostamble).append(' ');
+            // allow last to overlap
+            retval.append(fieldPreamble).append("%s").append(fieldPostamble).append(' ');
+            return retval.toString();
+        } else {
+            int labelLen = Math.min(columnWidths.get(LABEL_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
+            labelLen = Math.max(MIN_COLUMN_WIDTH, labelLen);
+
+            final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+            retval.append(fieldPreamble).append("%-").append(labelLen).append('.').append(labelLen).append('s').append(fieldPostamble).append(' ');
+            return retval.toString();
+        }
+    }
+
+    private int getMaxColumnWidth(boolean isHeader) {
+        if (!isHeader && verbose) {
+            return Integer.MAX_VALUE;
+        } else {
+            return MAX_COLUMN_WIDTH;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogLabelListCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogLabelListCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogLabelListCommand.java
deleted file mode 100644
index 57740d1..0000000
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogLabelListCommand.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.camel.commands;
-
-import java.io.PrintStream;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.camel.util.CollectionStringBuffer;
-
-/**
- * From the Camel catalog lists all the components.
- */
-public class CatalogLabelListCommand extends AbstractCamelCommand {
-
-    private static final String LABEL_COLUMN_LABEL = "Label";
-    private static final String NUMBER_COLUMN_LABEL = "#";
-    private static final String NAME_COLUMN_LABEL = "Name";
-
-    private static final int DEFAULT_COLUMN_WIDTH_INCREMENT = 0;
-    private static final String DEFAULT_FIELD_PREAMBLE = " ";
-    private static final String DEFAULT_FIELD_POSTAMBLE = " ";
-    private static final String DEFAULT_HEADER_PREAMBLE = " ";
-    private static final String DEFAULT_HEADER_POSTAMBLE = " ";
-    private static final int DEFAULT_FORMAT_BUFFER_LENGTH = 24;
-    // descriptions can be very long so clip by default after 120 chars
-    private static final int MAX_COLUMN_WIDTH = 120;
-    private static final int MIN_COLUMN_WIDTH = 12;
-    private static final int MIN_NUMBER_COLUMN_WIDTH = 6;
-
-    private boolean verbose;
-
-    public CatalogLabelListCommand(boolean verbose) {
-        this.verbose = verbose;
-    }
-
-    @Override
-    public Object execute(CamelController camelController, PrintStream out, PrintStream err) throws Exception {
-        Map<String, Set<String>> labels = camelController.listLabelCatalog();
-
-        if (labels.isEmpty()) {
-            return null;
-        }
-
-        final Map<String, Integer> columnWidths = computeColumnWidths(labels);
-        final String headerFormat = buildFormatString(columnWidths, true);
-        final String rowFormat = buildFormatString(columnWidths, false);
-
-        if (verbose) {
-            out.println(String.format(headerFormat, LABEL_COLUMN_LABEL, NUMBER_COLUMN_LABEL, NAME_COLUMN_LABEL));
-            out.println(String.format(headerFormat, "-----", "-", "----"));
-        } else {
-            out.println(String.format(headerFormat, LABEL_COLUMN_LABEL));
-            out.println(String.format(headerFormat, "-----"));
-        }
-
-        for (Map.Entry<String, Set<String>> row : labels.entrySet()) {
-            if (verbose) {
-                String label = row.getKey();
-                String number = "" + row.getValue().size();
-                CollectionStringBuffer csb = new CollectionStringBuffer(", ");
-                for (String name : row.getValue()) {
-                    csb.append(name);
-                }
-                out.println(String.format(rowFormat, label, number, csb.toString()));
-            } else {
-                String label = row.getKey();
-                out.println(String.format(rowFormat, label));
-            }
-        }
-
-        return null;
-    }
-
-    private Map<String, Integer> computeColumnWidths(Map<String, Set<String>> labels) throws Exception {
-        if (labels == null) {
-            return null;
-        } else {
-            // some of the options is optional so we need to start from 1
-            int maxLabelLen = LABEL_COLUMN_LABEL.length();
-            int maxNameLen = NAME_COLUMN_LABEL.length();
-
-            int counter = 0;
-            CollectionStringBuffer csb = new CollectionStringBuffer(", ");
-            for (Map.Entry<String, Set<String>> entry : labels.entrySet()) {
-                String label = entry.getKey();
-                maxLabelLen = Math.max(maxLabelLen, label.length());
-                for (String name : entry.getValue()) {
-                    counter++;
-                    csb.append(name);
-                }
-            }
-            maxNameLen = Math.max(maxNameLen, csb.toString().length());
-            int maxMumberLen = ("" + counter).length();
-
-            final Map<String, Integer> retval = new Hashtable<String, Integer>();
-            retval.put(LABEL_COLUMN_LABEL, maxLabelLen);
-            retval.put(NUMBER_COLUMN_LABEL, maxMumberLen);
-            retval.put(NAME_COLUMN_LABEL, maxNameLen);
-
-            return retval;
-        }
-    }
-
-    private String buildFormatString(Map<String, Integer> columnWidths, boolean isHeader) {
-        final String fieldPreamble;
-        final String fieldPostamble;
-        final int columnWidthIncrement;
-
-        if (isHeader) {
-            fieldPreamble = DEFAULT_HEADER_PREAMBLE;
-            fieldPostamble = DEFAULT_HEADER_POSTAMBLE;
-        } else {
-            fieldPreamble = DEFAULT_FIELD_PREAMBLE;
-            fieldPostamble = DEFAULT_FIELD_POSTAMBLE;
-        }
-        columnWidthIncrement = DEFAULT_COLUMN_WIDTH_INCREMENT;
-
-        if (verbose) {
-            int labelLen = Math.min(columnWidths.get(LABEL_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
-            int numberLen = Math.min(columnWidths.get(NUMBER_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
-
-            labelLen = Math.max(MIN_COLUMN_WIDTH, labelLen);
-            numberLen = Math.max(MIN_NUMBER_COLUMN_WIDTH, numberLen);
-
-            final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
-            retval.append(fieldPreamble).append("%-").append(labelLen).append('.').append(labelLen).append('s').append(fieldPostamble).append(' ');
-            retval.append(fieldPreamble).append("%-").append(numberLen).append('.').append(numberLen).append('s').append(fieldPostamble).append(' ');
-            // allow last to overlap
-            retval.append(fieldPreamble).append("%s").append(fieldPostamble).append(' ');
-            return retval.toString();
-        } else {
-            int labelLen = Math.min(columnWidths.get(LABEL_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
-            labelLen = Math.max(MIN_COLUMN_WIDTH, labelLen);
-
-            final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
-            retval.append(fieldPreamble).append("%-").append(labelLen).append('.').append(labelLen).append('s').append(fieldPostamble).append(' ');
-            return retval.toString();
-        }
-    }
-
-    private int getMaxColumnWidth(boolean isHeader) {
-        if (!isHeader && verbose) {
-            return Integer.MAX_VALUE;
-        } else {
-            return MAX_COLUMN_WIDTH;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogModelLabelListCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogModelLabelListCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogModelLabelListCommand.java
new file mode 100644
index 0000000..12f473b
--- /dev/null
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogModelLabelListCommand.java
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.commands;
+
+import java.io.PrintStream;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.util.CollectionStringBuffer;
+
+/**
+ * From the Camel catalog lists all the model labels.
+ */
+public class CatalogModelLabelListCommand extends AbstractCamelCommand {
+
+    private static final String LABEL_COLUMN_LABEL = "Label";
+    private static final String NUMBER_COLUMN_LABEL = "#";
+    private static final String NAME_COLUMN_LABEL = "Name";
+
+    private static final int DEFAULT_COLUMN_WIDTH_INCREMENT = 0;
+    private static final String DEFAULT_FIELD_PREAMBLE = " ";
+    private static final String DEFAULT_FIELD_POSTAMBLE = " ";
+    private static final String DEFAULT_HEADER_PREAMBLE = " ";
+    private static final String DEFAULT_HEADER_POSTAMBLE = " ";
+    private static final int DEFAULT_FORMAT_BUFFER_LENGTH = 24;
+    // descriptions can be very long so clip by default after 120 chars
+    private static final int MAX_COLUMN_WIDTH = 120;
+    private static final int MIN_COLUMN_WIDTH = 12;
+    private static final int MIN_NUMBER_COLUMN_WIDTH = 6;
+
+    private boolean verbose;
+
+    public CatalogModelLabelListCommand(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    @Override
+    public Object execute(CamelController camelController, PrintStream out, PrintStream err) throws Exception {
+        Map<String, Set<String>> labels = camelController.listModelsLabelCatalog();
+
+        if (labels.isEmpty()) {
+            return null;
+        }
+
+        final Map<String, Integer> columnWidths = computeColumnWidths(labels);
+        final String headerFormat = buildFormatString(columnWidths, true);
+        final String rowFormat = buildFormatString(columnWidths, false);
+
+        if (verbose) {
+            out.println(String.format(headerFormat, LABEL_COLUMN_LABEL, NUMBER_COLUMN_LABEL, NAME_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "-----", "-", "----"));
+        } else {
+            out.println(String.format(headerFormat, LABEL_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "-----"));
+        }
+
+        for (Map.Entry<String, Set<String>> row : labels.entrySet()) {
+            if (verbose) {
+                String label = row.getKey();
+                String number = "" + row.getValue().size();
+                CollectionStringBuffer csb = new CollectionStringBuffer(", ");
+                for (String name : row.getValue()) {
+                    csb.append(name);
+                }
+                out.println(String.format(rowFormat, label, number, csb.toString()));
+            } else {
+                String label = row.getKey();
+                out.println(String.format(rowFormat, label));
+            }
+        }
+
+        return null;
+    }
+
+    private Map<String, Integer> computeColumnWidths(Map<String, Set<String>> labels) throws Exception {
+        if (labels == null) {
+            return null;
+        } else {
+            // some of the options is optional so we need to start from 1
+            int maxLabelLen = LABEL_COLUMN_LABEL.length();
+            int maxNameLen = NAME_COLUMN_LABEL.length();
+
+            int counter = 0;
+            CollectionStringBuffer csb = new CollectionStringBuffer(", ");
+            for (Map.Entry<String, Set<String>> entry : labels.entrySet()) {
+                String label = entry.getKey();
+                maxLabelLen = Math.max(maxLabelLen, label.length());
+                for (String name : entry.getValue()) {
+                    counter++;
+                    csb.append(name);
+                }
+            }
+            maxNameLen = Math.max(maxNameLen, csb.toString().length());
+            int maxMumberLen = ("" + counter).length();
+
+            final Map<String, Integer> retval = new Hashtable<String, Integer>();
+            retval.put(LABEL_COLUMN_LABEL, maxLabelLen);
+            retval.put(NUMBER_COLUMN_LABEL, maxMumberLen);
+            retval.put(NAME_COLUMN_LABEL, maxNameLen);
+
+            return retval;
+        }
+    }
+
+    private String buildFormatString(Map<String, Integer> columnWidths, boolean isHeader) {
+        final String fieldPreamble;
+        final String fieldPostamble;
+        final int columnWidthIncrement;
+
+        if (isHeader) {
+            fieldPreamble = DEFAULT_HEADER_PREAMBLE;
+            fieldPostamble = DEFAULT_HEADER_POSTAMBLE;
+        } else {
+            fieldPreamble = DEFAULT_FIELD_PREAMBLE;
+            fieldPostamble = DEFAULT_FIELD_POSTAMBLE;
+        }
+        columnWidthIncrement = DEFAULT_COLUMN_WIDTH_INCREMENT;
+
+        if (verbose) {
+            int labelLen = Math.min(columnWidths.get(LABEL_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
+            int numberLen = Math.min(columnWidths.get(NUMBER_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
+
+            labelLen = Math.max(MIN_COLUMN_WIDTH, labelLen);
+            numberLen = Math.max(MIN_NUMBER_COLUMN_WIDTH, numberLen);
+
+            final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+            retval.append(fieldPreamble).append("%-").append(labelLen).append('.').append(labelLen).append('s').append(fieldPostamble).append(' ');
+            retval.append(fieldPreamble).append("%-").append(numberLen).append('.').append(numberLen).append('s').append(fieldPostamble).append(' ');
+            // allow last to overlap
+            retval.append(fieldPreamble).append("%s").append(fieldPostamble).append(' ');
+            return retval.toString();
+        } else {
+            int labelLen = Math.min(columnWidths.get(LABEL_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth(isHeader));
+            labelLen = Math.max(MIN_COLUMN_WIDTH, labelLen);
+
+            final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+            retval.append(fieldPreamble).append("%-").append(labelLen).append('.').append(labelLen).append('s').append(fieldPostamble).append(' ');
+            return retval.toString();
+        }
+    }
+
+    private int getMaxColumnWidth(boolean isHeader) {
+        if (!isHeader && verbose) {
+            return Integer.MAX_VALUE;
+        } else {
+            return MAX_COLUMN_WIDTH;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogModelListCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogModelListCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogModelListCommand.java
new file mode 100644
index 0000000..87d3c96
--- /dev/null
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CatalogModelListCommand.java
@@ -0,0 +1,171 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.commands;
+
+import java.io.PrintStream;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * From the Camel catalog lists all the models.
+ */
+public class CatalogModelListCommand extends AbstractCamelCommand {
+
+    private static final String NAME_COLUMN_LABEL = "Name";
+    private static final String LABEL_COLUMN_LABEL = "Label";
+    private static final String DESCRIPTION_COLUMN_LABEL = "Description";
+
+    private static final int DEFAULT_COLUMN_WIDTH_INCREMENT = 0;
+    private static final String DEFAULT_FIELD_PREAMBLE = " ";
+    private static final String DEFAULT_FIELD_POSTAMBLE = " ";
+    private static final String DEFAULT_HEADER_PREAMBLE = " ";
+    private static final String DEFAULT_HEADER_POSTAMBLE = " ";
+    private static final int DEFAULT_FORMAT_BUFFER_LENGTH = 24;
+    // descriptions can be very long so clip by default after 120 chars
+    private static final int MAX_COLUMN_WIDTH = 120;
+    private static final int MIN_COLUMN_WIDTH = 12;
+
+    private boolean verbose;
+    private String label;
+
+    public CatalogModelListCommand(boolean verbose, String label) {
+        this.verbose = verbose;
+        this.label = label;
+    }
+
+    @Override
+    public Object execute(CamelController camelController, PrintStream out, PrintStream err) throws Exception {
+        List<Map<String, String>> models = camelController.listModelsCatalog(label);
+
+        if (models == null || models.isEmpty()) {
+            return null;
+        }
+
+        final Map<String, Integer> columnWidths = computeColumnWidths(models);
+        final String headerFormat = buildFormatString(columnWidths, true);
+        final String rowFormat = buildFormatString(columnWidths, false);
+
+        if (verbose) {
+            out.println(String.format(headerFormat, NAME_COLUMN_LABEL, LABEL_COLUMN_LABEL, DESCRIPTION_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "----", "-----", "-----------"));
+        } else {
+            out.println(String.format(headerFormat, NAME_COLUMN_LABEL, LABEL_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "----", "-----"));
+        }
+        for (final Map<String, String> component : models) {
+            if (verbose) {
+                String name = safeNull(component.get("name"));
+                String label = safeNull(component.get("label"));
+                String description = safeNull(component.get("description"));
+                out.println(String.format(rowFormat, name, label, description));
+            } else {
+                String name = safeNull(component.get("name"));
+                String label = safeNull(component.get("label"));
+                out.println(String.format(rowFormat, name, label));
+            }
+        }
+
+        return null;
+    }
+
+    private Map<String, Integer> computeColumnWidths(final Iterable<Map<String, String>> components) throws Exception {
+        if (components == null) {
+            return null;
+        } else {
+            // some of the options is optional so we need to start from 1
+            int maxNameLen = NAME_COLUMN_LABEL.length();
+            int maxLabelLen = LABEL_COLUMN_LABEL.length();
+            int maxDescriptionLen = DESCRIPTION_COLUMN_LABEL.length();
+
+            for (final Map<String, String> component : components) {
+
+                // grab the information and compute max len
+                String name = component.get("name");
+                if (name != null) {
+                    maxNameLen = Math.max(maxNameLen, name.length());
+                }
+                String label = component.get("label");
+                if (label != null) {
+                    maxLabelLen = Math.max(maxLabelLen, label.length());
+                }
+                String description = component.get("description");
+                if (description != null) {
+                    maxDescriptionLen = Math.max(maxDescriptionLen, description.length());
+                }
+            }
+
+            final Map<String, Integer> retval = new Hashtable<String, Integer>(3);
+            retval.put(NAME_COLUMN_LABEL, maxNameLen);
+            retval.put(LABEL_COLUMN_LABEL, maxLabelLen);
+            retval.put(DESCRIPTION_COLUMN_LABEL, maxDescriptionLen);
+
+            return retval;
+        }
+    }
+
+    private String buildFormatString(Map<String, Integer> columnWidths, boolean isHeader) {
+        final String fieldPreamble;
+        final String fieldPostamble;
+        final int columnWidthIncrement;
+
+        if (isHeader) {
+            fieldPreamble = DEFAULT_HEADER_PREAMBLE;
+            fieldPostamble = DEFAULT_HEADER_POSTAMBLE;
+        } else {
+            fieldPreamble = DEFAULT_FIELD_PREAMBLE;
+            fieldPostamble = DEFAULT_FIELD_POSTAMBLE;
+        }
+        columnWidthIncrement = DEFAULT_COLUMN_WIDTH_INCREMENT;
+
+        if (verbose) {
+            int nameLen = Math.min(columnWidths.get(NAME_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+            int labelLen = Math.min(columnWidths.get(LABEL_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+            int descriptionLen = Math.min(columnWidths.get(DESCRIPTION_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+
+            nameLen = Math.max(MIN_COLUMN_WIDTH, nameLen);
+            labelLen = Math.max(MIN_COLUMN_WIDTH, labelLen);
+            descriptionLen = Math.max(MIN_COLUMN_WIDTH, descriptionLen);
+
+            final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+            retval.append(fieldPreamble).append("%-").append(nameLen).append('.').append(nameLen).append('s').append(fieldPostamble).append(' ');
+            retval.append(fieldPreamble).append("%-").append(labelLen).append('.').append(labelLen).append('s').append(fieldPostamble).append(' ');
+            retval.append(fieldPreamble).append("%-").append(descriptionLen).append('.').append(descriptionLen).append('s').append(fieldPostamble).append(' ');
+            return retval.toString();
+        } else {
+            int nameLen = Math.min(columnWidths.get(NAME_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+            int labelLen = Math.min(columnWidths.get(LABEL_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
+
+            nameLen = Math.max(MIN_COLUMN_WIDTH, nameLen);
+            labelLen = Math.max(MIN_COLUMN_WIDTH, labelLen);
+
+            final StringBuilder retval = new StringBuilder(DEFAULT_FORMAT_BUFFER_LENGTH);
+            retval.append(fieldPreamble).append("%-").append(nameLen).append('.').append(nameLen).append('s').append(fieldPostamble).append(' ');
+            retval.append(fieldPreamble).append("%-").append(labelLen).append('.').append(labelLen).append('s').append(fieldPostamble).append(' ');
+            return retval.toString();
+        }
+    }
+
+    private int getMaxColumnWidth() {
+        if (verbose) {
+            return Integer.MAX_VALUE;
+        } else {
+            return MAX_COLUMN_WIDTH;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelComponentCatalogTest.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelComponentCatalogTest.java b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelComponentCatalogTest.java
index d6b8067..95bd1dc 100644
--- a/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelComponentCatalogTest.java
+++ b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelComponentCatalogTest.java
@@ -111,7 +111,7 @@ public class CamelComponentCatalogTest {
     @Test
     public void testLabels() {
         CamelComponentCatalog catalog = new DefaultCamelComponentCatalog();
-        Set<String> labels = catalog.findLabels();
+        Set<String> labels = catalog.findComponentLabels();
 
         assertNotNull(labels);
 

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelModelCatalogTest.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelModelCatalogTest.java b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelModelCatalogTest.java
new file mode 100644
index 0000000..748c1e4
--- /dev/null
+++ b/platforms/commands/commands-core/src/test/java/org/apache/camel/commands/catalog/CamelModelCatalogTest.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.commands.catalog;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.camel.catalog.CamelComponentCatalog;
+import org.apache.camel.catalog.DefaultCamelComponentCatalog;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class CamelModelCatalogTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CamelModelCatalogTest.class);
+
+    @Test
+    public void testFindModelNames() {
+        CamelComponentCatalog catalog = new DefaultCamelComponentCatalog();
+        List<String> names = catalog.findModelNames();
+
+        assertNotNull(names);
+
+        LOG.info("Found {} names", names.size());
+        assertTrue("Should find some models", names.size() > 0);
+    }
+
+    @Test
+    public void testFindModelNamesFilter() {
+        CamelComponentCatalog catalog = new DefaultCamelComponentCatalog();
+        List<String> names = catalog.findModelNames("transformation");
+
+        assertNotNull(names);
+
+        LOG.info("Found {} names", names.size());
+        assertTrue("Should find some transformation models", names.size() > 0);
+    }
+
+    @Test
+    public void testFindModelNamesFilterWildcard() {
+        CamelComponentCatalog catalog = new DefaultCamelComponentCatalog();
+        List<String> names = catalog.findModelNames("t*");
+
+        assertNotNull(names);
+
+        LOG.info("Found {} names", names.size());
+        assertTrue("Should find some t* models", names.size() > 0);
+    }
+
+    @Test
+    public void testFindComponentNamesFilterNoMatch() {
+        CamelComponentCatalog catalog = new DefaultCamelComponentCatalog();
+        List<String> names = catalog.findModelNames("cannotmatchme");
+
+        assertNotNull(names);
+
+        assertTrue("Should not match any models", names.size() == 0);
+    }
+
+    @Test
+    public void testCoreComponentJson() {
+        CamelComponentCatalog catalog = new DefaultCamelComponentCatalog();
+        String json = catalog.modelJSonSchema("split");
+
+        assertNotNull(json);
+        LOG.info(json);
+
+        assertTrue("Should find to split", json.contains("split"));
+    }
+
+    @Test
+    public void testLabels() {
+        CamelComponentCatalog catalog = new DefaultCamelComponentCatalog();
+        Set<String> labels = catalog.findModelLabels();
+
+        assertNotNull(labels);
+
+        assertTrue("Should find labels", labels.size() > 0);
+        assertTrue("Should find transformation label", labels.contains("transformation"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogComponentLabelList.java
----------------------------------------------------------------------
diff --git a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogComponentLabelList.java b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogComponentLabelList.java
new file mode 100644
index 0000000..cc0e331
--- /dev/null
+++ b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogComponentLabelList.java
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.karaf.commands;
+
+import org.apache.camel.commands.CatalogComponentLabelListCommand;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "camel", name = "catalog-component-label-list", description = "Lists all Camel component labels from the Camel catalog.")
+public class CatalogComponentLabelList extends CamelCommandSupport {
+
+    @Option(name = "--verbose", aliases = "-v", description = "Verbose output which shows more information",
+            required = false, multiValued = false, valueToShowInHelp = "false")
+    boolean verbose;
+
+    protected Object doExecute() throws Exception {
+        CatalogComponentLabelListCommand command = new CatalogComponentLabelListCommand(verbose);
+        return command.execute(camelController, System.out, System.err);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogLabelList.java
----------------------------------------------------------------------
diff --git a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogLabelList.java b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogLabelList.java
deleted file mode 100644
index 382d6c6..0000000
--- a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogLabelList.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.camel.karaf.commands;
-
-import org.apache.camel.commands.CatalogLabelListCommand;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.felix.gogo.commands.Option;
-
-@Command(scope = "camel", name = "catalog-label-list", description = "Lists all Camel component labels from the Camel catalog.")
-public class CatalogLabelList extends CamelCommandSupport {
-
-    @Option(name = "--verbose", aliases = "-v", description = "Verbose output which shows more information",
-            required = false, multiValued = false, valueToShowInHelp = "false")
-    boolean verbose;
-
-    protected Object doExecute() throws Exception {
-        CatalogLabelListCommand command = new CatalogLabelListCommand(verbose);
-        return command.execute(camelController, System.out, System.err);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogModelLabelList.java
----------------------------------------------------------------------
diff --git a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogModelLabelList.java b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogModelLabelList.java
new file mode 100644
index 0000000..46fb20d
--- /dev/null
+++ b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogModelLabelList.java
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.karaf.commands;
+
+import org.apache.camel.commands.CatalogModelLabelListCommand;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "camel", name = "catalog-eip-label-list", description = "Lists all Camel EIP labels from the Camel catalog.")
+public class CatalogModelLabelList extends CamelCommandSupport {
+
+    @Option(name = "--verbose", aliases = "-v", description = "Verbose output which shows more information",
+            required = false, multiValued = false, valueToShowInHelp = "false")
+    boolean verbose;
+
+    protected Object doExecute() throws Exception {
+        CatalogModelLabelListCommand command = new CatalogModelLabelListCommand(verbose);
+        return command.execute(camelController, System.out, System.err);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogModelList.java
----------------------------------------------------------------------
diff --git a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogModelList.java b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogModelList.java
new file mode 100644
index 0000000..6eac2b0
--- /dev/null
+++ b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/CatalogModelList.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.camel.karaf.commands;
+
+import org.apache.camel.commands.CatalogModelListCommand;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
+
+@Command(scope = "camel", name = "catalog-eip-list", description = "Lists all Camel EIPs from the Camel catalog.")
+public class CatalogModelList extends CamelCommandSupport {
+
+    @Option(name = "--verbose", aliases = "-v", description = "Verbose output which shows more information",
+            required = false, multiValued = false, valueToShowInHelp = "false")
+    boolean verbose;
+
+    @Option(name = "--label", aliases = "-l", description = "To filter EIPs by their label(s), such as transformation",
+            required = false, multiValued = false)
+    String label;
+
+    protected Object doExecute() throws Exception {
+        CatalogModelListCommand command = new CatalogModelListCommand(verbose, label);
+        return command.execute(camelController, System.out, System.err);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
----------------------------------------------------------------------
diff --git a/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml b/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
index 02db00a..2900df9 100644
--- a/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
+++ b/platforms/karaf/commands/src/main/resources/OSGI-INF/blueprint/camel-commands.xml
@@ -203,7 +203,17 @@
       </action>
     </command>
     <command name="camel/catalog-label-list">
-      <action class="org.apache.camel.karaf.commands.CatalogLabelList">
+      <action class="org.apache.camel.karaf.commands.CatalogComponentLabelList">
+        <property name="camelController" ref="camelController"/>
+      </action>
+    </command>
+    <command name="camel/catalog-eip-list">
+      <action class="org.apache.camel.karaf.commands.CatalogModelList">
+        <property name="camelController" ref="camelController"/>
+      </action>
+    </command>
+    <command name="camel/catalog-eip-label-list">
+      <action class="org.apache.camel.karaf.commands.CatalogModelLabelList">
         <property name="camelController" ref="camelController"/>
       </action>
     </command>

http://git-wip-us.apache.org/repos/asf/camel/blob/fe630137/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
index 92c0ed3..0dbab08 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
@@ -198,6 +198,8 @@ public class PrepareCatalogMojo extends AbstractMojo {
         } catch (IOException e) {
             throw new MojoFailureException("Error writing to file " + all);
         }
+
+        printModelsReport(jsonFiles, duplicateJsonFiles, missingLabels, usedLabels);
     }
 
     protected void executeComponents() throws MojoExecutionException, MojoFailureException {
@@ -328,6 +330,44 @@ public class PrepareCatalogMojo extends AbstractMojo {
         printComponentsReport(jsonFiles, duplicateJsonFiles, missingComponents, missingUriPaths, missingLabels, usedLabels);
     }
 
+    private void printModelsReport(Set<File> json, Set<File> duplicate, Set<File> missingLabels, Map<String, Set<String>> usedLabels) {
+        getLog().info("================================================================================");
+
+        getLog().info("");
+        getLog().info("Camel model catalog report");
+        getLog().info("");
+        getLog().info("\tModels found: " + json.size());
+        for (File file : json) {
+            getLog().info("\t\t" + asComponentName(file));
+        }
+        if (!duplicate.isEmpty()) {
+            getLog().info("");
+            getLog().warn("\tDuplicate models detected: " + duplicate.size());
+            for (File file : duplicate) {
+                getLog().warn("\t\t" + asComponentName(file));
+            }
+        }
+        if (!missingLabels.isEmpty()) {
+            getLog().info("");
+            getLog().warn("\tMissing labels detected: " + missingLabels.size());
+            for (File file : missingLabels) {
+                getLog().warn("\t\t" + asComponentName(file));
+            }
+        }
+        if (!usedLabels.isEmpty()) {
+            getLog().info("");
+            getLog().info("\tUsed labels: " + usedLabels.size());
+            for (Map.Entry<String, Set<String>> entry : usedLabels.entrySet()) {
+                getLog().info("\t\t" + entry.getKey() + ":");
+                for (String name : entry.getValue()) {
+                    getLog().info("\t\t\t" + name);
+                }
+            }
+        }
+        getLog().info("");
+        getLog().info("================================================================================");
+    }
+
     private void printComponentsReport(Set<File> json, Set<File> duplicate, Set<File> missing, Set<File> missingUriPaths,
                                        Set<File> missingLabels, Map<String, Set<String>> usedLabels) {
         getLog().info("================================================================================");