CAMEL-8041: Camel commands should be reusable.

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

Branch: refs/heads/master
Commit: f5b76564b2d5ab2f78b6df4d72ae1aa756be091e
Parents: 7791d1f
Author: Claus Ibsen <davscl...@apache.org>
Authored: Thu Nov 13 09:42:46 2014 +0100
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Thu Nov 13 09:42:46 2014 +0100

----------------------------------------------------------------------
 .../camel/commands/AbstractContextCommand.java  |  18 +-
 .../camel/commands/AbstractRouteCommand.java    |   4 +-
 .../commands/BacklogTracerDumpCommand.java      | 118 ++++++++++++
 .../commands/BacklogTracerInfoCommand.java      |  51 ++++++
 .../commands/BacklogTracerStartCommand.java     |  59 ++++++
 .../commands/BacklogTracerStopCommand.java      |  45 +++++
 .../camel/commands/ComponentListCommand.java    | 183 +++++++++++++++++++
 .../camel/commands/ContextInfoCommand.java      |  21 +--
 .../camel/karaf/commands/BacklogTracerDump.java |  82 +--------
 .../camel/karaf/commands/BacklogTracerInfo.java |  28 +--
 .../karaf/commands/BacklogTracerStart.java      |  28 +--
 .../camel/karaf/commands/BacklogTracerStop.java |  22 +--
 12 files changed, 487 insertions(+), 172 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractContextCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractContextCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractContextCommand.java
index b796c65..7212b15 100644
--- 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractContextCommand.java
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractContextCommand.java
@@ -25,12 +25,12 @@ import org.apache.camel.CamelContext;
  */
 public abstract class AbstractContextCommand extends AbstractCamelCommand {
 
-    private String context;
+    String context;
 
     /**
      * @param context The name of the Camel context.
      */
-    protected AbstractContextCommand(String route, String context) {
+    protected AbstractContextCommand(String context) {
         this.context = context;
     }
 
@@ -46,20 +46,22 @@ public abstract class AbstractContextCommand extends 
AbstractCamelCommand {
         ClassLoader oldClassloader = 
Thread.currentThread().getContextClassLoader();
         
Thread.currentThread().setContextClassLoader(camelContext.getApplicationContextClassLoader());
         try {
-            performContextCommand(camelContext, out, err);
+            return performContextCommand(camelController, camelContext, out, 
err);
         } finally {
             Thread.currentThread().setContextClassLoader(oldClassloader);
         }
-        return null;
     }
 
     /**
      * Perform Context-specific command
      *
-     * @param camelContext non-null {@link CamelContext}
-     * @param out          the output printer stream
-     * @param err          the error print stream
+     * @param camelController the Camel controller
+     * @param camelContext    non-null {@link CamelContext}
+     * @param out             the output printer stream
+     * @param err             the error print stream
+     * @return response from command, or <tt>null</tt> if nothing to return
+     * @throws Exception is thrown if error executing command
      */
-    protected abstract void performContextCommand(CamelContext camelContext, 
PrintStream out, PrintStream err) throws Exception;
+    protected abstract Object performContextCommand(CamelController 
camelController, CamelContext camelContext, PrintStream out, PrintStream err) 
throws Exception;
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractRouteCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractRouteCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractRouteCommand.java
index 678f175..c9c75f7 100644
--- 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractRouteCommand.java
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractRouteCommand.java
@@ -59,7 +59,7 @@ public abstract class AbstractRouteCommand extends 
AbstractCamelCommand {
             ClassLoader oldClassloader = 
Thread.currentThread().getContextClassLoader();
             
Thread.currentThread().setContextClassLoader(camelContext.getApplicationContextClassLoader());
             try {
-                executeOnRoute(camelContext, camelRoute, out, err);
+                executeOnRoute(camelController, camelContext, camelRoute, out, 
err);
             } finally {
                 Thread.currentThread().setContextClassLoader(oldClassloader);
             }
@@ -68,7 +68,7 @@ public abstract class AbstractRouteCommand extends 
AbstractCamelCommand {
         return null;
     }
 
-    public abstract void executeOnRoute(CamelContext camelContext, Route 
camelRoute, PrintStream out, PrintStream err) throws Exception;
+    public abstract void executeOnRoute(CamelController camelController, 
CamelContext camelContext, Route camelRoute, PrintStream out, PrintStream err) 
throws Exception;
 
     /**
      * To sort the routes.

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerDumpCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerDumpCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerDumpCommand.java
new file mode 100644
index 0000000..42be1ff
--- /dev/null
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerDumpCommand.java
@@ -0,0 +1,118 @@
+/**
+ * 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.io.StringReader;
+import java.text.SimpleDateFormat;
+import java.util.List;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.api.management.mbean.BacklogTracerEventMessage;
+import org.apache.camel.processor.interceptor.BacklogTracer;
+import org.apache.camel.util.MessageDump;
+
+public class BacklogTracerDumpCommand extends AbstractContextCommand {
+
+    private String pattern;
+    private String format;
+    private Integer bodySize;
+
+    /**
+     * @param context  The name of the Camel context.
+     * @param pattern  To dump trace messages only for nodes or routes 
matching the given pattern (default is all)
+     * @param format   Format to use with the dump action (text or xml)
+     * @param bodySize To limit the body size when using text format
+     */
+    public BacklogTracerDumpCommand(String context, String pattern, String 
format, Integer bodySize) {
+        super(context);
+        this.pattern = pattern;
+        this.format = format;
+        this.bodySize = bodySize;
+    }
+
+    @Override
+    protected Object performContextCommand(CamelController camelController, 
CamelContext camelContext, PrintStream out, PrintStream err) throws Exception {
+        BacklogTracer backlogTracer = 
BacklogTracer.getBacklogTracer(camelContext);
+        if (backlogTracer == null) {
+            backlogTracer = (BacklogTracer) 
camelContext.getDefaultBacklogTracer();
+        }
+
+        if (format == null || "text".equals(format)) {
+            JAXBContext context = JAXBContext.newInstance(MessageDump.class);
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+            SimpleDateFormat sdf = new 
SimpleDateFormat(BacklogTracerEventMessage.TIMESTAMP_FORMAT);
+
+            List<BacklogTracerEventMessage> events;
+            if (pattern != null) {
+                events = backlogTracer.dumpTracedMessages(pattern);
+            } else {
+                events = backlogTracer.dumpAllTracedMessages();
+            }
+            for (BacklogTracerEventMessage event : events) {
+                MessageDump msg = (MessageDump) unmarshaller.unmarshal(new 
StringReader(event.getMessageAsXml()));
+                String breadcrumb = getBreadcrumbId(msg.getHeaders());
+
+                out.println("#" + event.getUid() + "\tTimestamp:\t" + 
sdf.format(event.getTimestamp()));
+                if (breadcrumb != null) {
+                    out.println("Breadcrumb: " + breadcrumb);
+                }
+                out.println("ExchangeId: " + event.getExchangeId());
+
+                if (event.getToNode() != null) {
+                    out.println("Route: " + event.getRouteId() + "\t--> " + 
event.getToNode());
+                } else {
+                    out.println("Route: " + event.getRouteId());
+                }
+
+                String body = msg.getBody().getValue();
+                if (bodySize != null && bodySize > 0) {
+                    if (body.length() > bodySize) {
+                        body = body.substring(0, bodySize);
+                    }
+                }
+                out.println(body);
+                out.println("");
+            }
+        } else if ("xml".equals(format)) {
+            if (pattern != null) {
+                out.println("BacklogTracer messages:\n" + 
backlogTracer.dumpTracedMessages(pattern));
+            } else {
+                out.println("BacklogTracer messages:\n" + 
backlogTracer.dumpAllTracedMessagesAsXml());
+            }
+            return null;
+        }
+
+        return null;
+    }
+
+    private static String getBreadcrumbId(List<MessageDump.Header> headers) {
+        if (headers == null || headers.isEmpty()) {
+            return null;
+        }
+        for (MessageDump.Header header : headers) {
+            if (header.getKey().equals(Exchange.BREADCRUMB_ID)) {
+                return header.getValue();
+            }
+        }
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerInfoCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerInfoCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerInfoCommand.java
new file mode 100644
index 0000000..d8cf50c
--- /dev/null
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerInfoCommand.java
@@ -0,0 +1,51 @@
+/**
+ * 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 org.apache.camel.CamelContext;
+import org.apache.camel.processor.interceptor.BacklogTracer;
+
+public class BacklogTracerInfoCommand extends AbstractContextCommand {
+
+    public BacklogTracerInfoCommand(String context) {
+        super(context);
+    }
+
+    @Override
+    protected Object performContextCommand(CamelController camelController, 
CamelContext camelContext, PrintStream out, PrintStream err) throws Exception {
+        BacklogTracer backlogTracer = 
BacklogTracer.getBacklogTracer(camelContext);
+        if (backlogTracer == null) {
+            backlogTracer = (BacklogTracer) 
camelContext.getDefaultBacklogTracer();
+        }
+
+        out.println("BacklogTracer context:\t\t" + camelContext.getName());
+        out.println("BacklogTracer enabled:\t\t" + backlogTracer.isEnabled());
+        out.println("BacklogTracer pattern:\t\t" + 
(backlogTracer.getTracePattern() != null ? backlogTracer.getTracePattern() : 
""));
+        out.println("BacklogTracer filter:\t\t" + 
(backlogTracer.getTraceFilter() != null ? backlogTracer.getTraceFilter() : ""));
+        out.println("BacklogTracer removeOnDump:\t" + 
backlogTracer.isRemoveOnDump());
+        out.println("BacklogTracer backlogSize:\t" + 
backlogTracer.getBacklogSize());
+        out.println("BacklogTracer tracerCount:\t" + 
backlogTracer.getTraceCounter());
+        out.println("BacklogTracer body...");
+        out.println("\tmaxChars:\t\t" + backlogTracer.getBodyMaxChars());
+        out.println("\tincludeFiles:\t\t" + 
backlogTracer.isBodyIncludeFiles());
+        out.println("\tincludeStreams:\t\t" + 
backlogTracer.isBodyIncludeStreams());
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerStartCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerStartCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerStartCommand.java
new file mode 100644
index 0000000..b8fb249
--- /dev/null
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerStartCommand.java
@@ -0,0 +1,59 @@
+/**
+ * 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 org.apache.camel.CamelContext;
+import org.apache.camel.processor.interceptor.BacklogTracer;
+
+public class BacklogTracerStartCommand extends AbstractContextCommand {
+
+    private String pattern;
+    private String filter;
+    private Integer backlogSize;
+    private Boolean removeOnDump;
+
+    public BacklogTracerStartCommand(String context, String pattern, String 
filter, Integer backlogSize, Boolean removeOnDump) {
+        super(context);
+        this.pattern = pattern;
+        this.filter = filter;
+        this.backlogSize = backlogSize;
+        this.removeOnDump = removeOnDump;
+    }
+
+    @Override
+    protected Object performContextCommand(CamelController camelController, 
CamelContext camelContext, PrintStream out, PrintStream err) throws Exception {
+        BacklogTracer backlogTracer = 
BacklogTracer.getBacklogTracer(camelContext);
+        if (backlogTracer == null) {
+            backlogTracer = (BacklogTracer) 
camelContext.getDefaultBacklogTracer();
+        }
+
+        backlogTracer.setEnabled(true);
+        if (backlogSize != null) {
+            backlogTracer.setBacklogSize(backlogSize);
+        }
+        if (removeOnDump != null) {
+            backlogTracer.setRemoveOnDump(removeOnDump);
+        }
+        backlogTracer.setTracePattern(pattern);
+        backlogTracer.setTraceFilter(filter);
+
+        out.println("BacklogTracer started on " + camelContext.getName() + " 
with size: " + backlogTracer.getBacklogSize());
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerStopCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerStopCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerStopCommand.java
new file mode 100644
index 0000000..0a24c86
--- /dev/null
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/BacklogTracerStopCommand.java
@@ -0,0 +1,45 @@
+/**
+ * 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 org.apache.camel.CamelContext;
+import org.apache.camel.processor.interceptor.BacklogTracer;
+
+public class BacklogTracerStopCommand extends AbstractContextCommand {
+
+    public BacklogTracerStopCommand(String context) {
+        super(context);
+    }
+
+    @Override
+    protected Object performContextCommand(CamelController camelController, 
CamelContext camelContext, PrintStream out, PrintStream err) throws Exception {
+        BacklogTracer backlogTracer = 
BacklogTracer.getBacklogTracer(camelContext);
+        if (backlogTracer == null) {
+            backlogTracer = (BacklogTracer) 
camelContext.getDefaultBacklogTracer();
+        }
+
+        // disable tracer and clear counter and the backlog queue
+        backlogTracer.setEnabled(false);
+        backlogTracer.resetTraceCounter();
+        backlogTracer.clear();
+        out.println("BacklogTracer stopped on " + camelContext.getName());
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ComponentListCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ComponentListCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ComponentListCommand.java
new file mode 100644
index 0000000..8f613c1
--- /dev/null
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ComponentListCommand.java
@@ -0,0 +1,183 @@
+/**
+ * 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;
+
+import org.apache.camel.CamelContext;
+
+public class ComponentListCommand extends AbstractContextCommand {
+
+    private static final String NAME_COLUMN_LABEL = "Name";
+    private static final String STATUS_COLUMN_LABEL = "Status";
+    private static final String MAVEN_COLUMN_LABEL = "Maven Coordinate";
+    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;
+
+    public ComponentListCommand(String context, boolean verbose) {
+        super(context);
+        this.verbose = verbose;
+    }
+
+    @Override
+    protected Object performContextCommand(CamelController camelController, 
CamelContext camelContext, PrintStream out, PrintStream err) throws Exception {
+        List<Map<String, String>> components = 
camelController.listComponents(context);
+
+        if (components == null || components.isEmpty()) {
+            return null;
+        }
+
+        final Map<String, Integer> columnWidths = 
computeColumnWidths(components);
+        final String headerFormat = buildFormatString(columnWidths, true, 
verbose);
+        final String rowFormat = buildFormatString(columnWidths, false, 
verbose);
+
+        if (verbose) {
+            out.println(String.format(headerFormat, NAME_COLUMN_LABEL, 
STATUS_COLUMN_LABEL, MAVEN_COLUMN_LABEL, DESCRIPTION_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "----", "------", 
"----------------", "-----------"));
+        } else {
+            out.println(String.format(headerFormat, NAME_COLUMN_LABEL, 
DESCRIPTION_COLUMN_LABEL));
+            out.println(String.format(headerFormat, "----", "-----------"));
+        }
+        for (final Map<String, String> component : components) {
+            if (verbose) {
+                String name = safeNull(component.get("name"));
+                String status = safeNull(component.get("status"));
+                String maven = "";
+                if (component.containsKey("groupId") && 
component.containsKey("artifactId") && component.containsKey("version")) {
+                    maven = component.get("groupId") + "/" + 
component.get("artifactId") + "/" + component.get("version");
+                }
+                String description = safeNull(component.get("description"));
+                out.println(String.format(rowFormat, name, status, maven, 
description));
+            } else {
+                String name = safeNull(component.get("name"));
+                String description = safeNull(component.get("description"));
+                out.println(String.format(rowFormat, name, description));
+            }
+        }
+
+        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 = 1;
+            int maxStatusLen = 1;
+            int maxMavenLen = 1;
+            int maxDescriptionLen = 1;
+
+            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 status = component.get("status");
+                if (status != null) {
+                    maxStatusLen = Math.max(maxStatusLen, status.length());
+                }
+                if (component.containsKey("groupId") && 
component.containsKey("artifactId") && component.containsKey("version")) {
+                    String mvn = component.get("groupId") + "/" + 
component.get("artifactId") + "/" + component.get("version");
+                    maxMavenLen = Math.max(maxMavenLen, mvn.length());
+                }
+                String description = component.get("description");
+                if (description != null) {
+                    maxDescriptionLen = Math.max(maxDescriptionLen, 
description.length());
+                }
+            }
+
+            final Map<String, Integer> retval = new Hashtable<String, 
Integer>(4);
+            retval.put(NAME_COLUMN_LABEL, maxNameLen);
+            retval.put(STATUS_COLUMN_LABEL, maxStatusLen);
+            retval.put(MAVEN_COLUMN_LABEL, maxMavenLen);
+            retval.put(DESCRIPTION_COLUMN_LABEL, maxDescriptionLen);
+
+            return retval;
+        }
+    }
+
+    private String buildFormatString(Map<String, Integer> columnWidths, 
boolean isHeader, boolean isVerbose) {
+        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 statusLen = Math.min(columnWidths.get(STATUS_COLUMN_LABEL) + 
columnWidthIncrement, getMaxColumnWidth());
+            int mavenLen = Math.min(columnWidths.get(MAVEN_COLUMN_LABEL) + 
columnWidthIncrement, getMaxColumnWidth());
+            int descriptionLen = 
Math.min(columnWidths.get(DESCRIPTION_COLUMN_LABEL) + columnWidthIncrement, 
getMaxColumnWidth());
+
+            nameLen = Math.max(MIN_COLUMN_WIDTH, nameLen);
+            statusLen = Math.max(MIN_COLUMN_WIDTH, statusLen);
+            mavenLen = Math.max(MIN_COLUMN_WIDTH, mavenLen);
+            // last row does not have min width
+
+            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(statusLen).append('.').append(statusLen).append('s').append(fieldPostamble).append('
 ');
+            
retval.append(fieldPreamble).append("%-").append(mavenLen).append('.').append(mavenLen).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 descriptionLen = 
Math.min(columnWidths.get(DESCRIPTION_COLUMN_LABEL) + columnWidthIncrement, 
getMaxColumnWidth());
+
+            nameLen = Math.max(MIN_COLUMN_WIDTH, nameLen);
+            // last row does not have min width
+
+            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(descriptionLen).append('.').append(descriptionLen).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/f5b76564/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
----------------------------------------------------------------------
diff --git 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
index 299d7f5..9df1f8a 100644
--- 
a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
+++ 
b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
@@ -36,18 +36,17 @@ import static 
org.apache.camel.util.UnitUtils.printUnitFromBytes;
 /**
  * Command to display detailed information about a given {@link 
org.apache.camel.CamelContext}.
  */
-public class ContextInfoCommand extends AbstractCamelCommand {
+public class ContextInfoCommand extends AbstractContextCommand {
 
     private StringEscape stringEscape;
-    private String name;
     private String mode;
 
     /**
-     * @param name The name of the Camel context
+     * @param context The name of the Camel context
      * @param mode Allows for different display modes (--verbose, etc)
      */
-    public ContextInfoCommand(String name, String mode) {
-        this.name = name;
+    public ContextInfoCommand(String context, String mode) {
+        super(context);
         this.mode = mode;
     }
 
@@ -59,15 +58,9 @@ public class ContextInfoCommand extends AbstractCamelCommand 
{
     }
 
     @Override
-    public Object execute(CamelController camelController, PrintStream out, 
PrintStream err) throws Exception {
-        CamelContext camelContext = camelController.getCamelContext(name);
+    protected Object performContextCommand(CamelController camelController, 
CamelContext camelContext, PrintStream out, PrintStream err) throws Exception {
 
-        if (camelContext == null) {
-            err.println("Camel context " + name + " not found.");
-            return null;
-        }
-
-        out.println(stringEscape.unescapeJava("\u001B[1m\u001B[33mCamel 
Context " + name + "\u001B[0m"));
+        out.println(stringEscape.unescapeJava("\u001B[1m\u001B[33mCamel 
Context " + context + "\u001B[0m"));
         out.println(stringEscape.unescapeJava("\tName: " + 
camelContext.getName()));
         out.println(stringEscape.unescapeJava("\tManagementName: " + 
camelContext.getManagementName()));
         out.println(stringEscape.unescapeJava("\tVersion: " + 
camelContext.getVersion()));
@@ -143,7 +136,7 @@ public class ContextInfoCommand extends 
AbstractCamelCommand {
         if (agent != null) {
             MBeanServer mBeanServer = agent.getMBeanServer();
 
-            Set<ObjectName> set = mBeanServer.queryNames(new 
ObjectName(agent.getMBeanObjectDomainName() + ":type=context,name=\"" + name + 
"\",*"), null);
+            Set<ObjectName> set = mBeanServer.queryNames(new 
ObjectName(agent.getMBeanObjectDomainName() + ":type=context,name=\"" + context 
+ "\",*"), null);
             Iterator<ObjectName> iterator = set.iterator();
             if (iterator.hasNext()) {
                 contextMBean = iterator.next();

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerDump.java
----------------------------------------------------------------------
diff --git 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerDump.java
 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerDump.java
index 429e0a5..c221165 100644
--- 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerDump.java
+++ 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerDump.java
@@ -16,17 +16,7 @@
  */
 package org.apache.camel.karaf.commands;
 
-import java.io.StringReader;
-import java.text.SimpleDateFormat;
-import java.util.List;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Unmarshaller;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.api.management.mbean.BacklogTracerEventMessage;
-import org.apache.camel.processor.interceptor.BacklogTracer;
-import org.apache.camel.util.MessageDump;
+import org.apache.camel.commands.BacklogTracerDumpCommand;
 import org.apache.felix.gogo.commands.Argument;
 import org.apache.felix.gogo.commands.Command;
 import org.apache.felix.gogo.commands.Option;
@@ -51,74 +41,8 @@ public class BacklogTracerDump extends CamelCommandSupport {
 
     @Override
     protected Object doExecute() throws Exception {
-        CamelContext camel = camelController.getCamelContext(context);
-        if (camel == null) {
-            System.err.println("CamelContext " + context + " not found.");
-            return null;
-        }
-
-        BacklogTracer backlogTracer = BacklogTracer.getBacklogTracer(camel);
-        if (backlogTracer == null) {
-            backlogTracer = (BacklogTracer) camel.getDefaultBacklogTracer();
-        }
-
-        if (format == null || "text".equals(format)) {
-            JAXBContext context = JAXBContext.newInstance(MessageDump.class);
-            Unmarshaller unmarshaller = context.createUnmarshaller();
-            SimpleDateFormat sdf = new 
SimpleDateFormat(BacklogTracerEventMessage.TIMESTAMP_FORMAT);
-
-            List<BacklogTracerEventMessage> events;
-            if (pattern != null) {
-                events = backlogTracer.dumpTracedMessages(pattern);
-            } else {
-                events = backlogTracer.dumpAllTracedMessages();
-            }
-            for (BacklogTracerEventMessage event : events) {
-                MessageDump msg = (MessageDump) unmarshaller.unmarshal(new 
StringReader(event.getMessageAsXml()));
-                String breadcrumb = getBreadcrumbId(msg.getHeaders());
-
-                System.out.println("#" + event.getUid() + "\tTimestamp:\t" + 
sdf.format(event.getTimestamp()));
-                if (breadcrumb != null) {
-                    System.out.println("Breadcrumb: " + breadcrumb);
-                }
-                System.out.println("ExchangeId: " + event.getExchangeId());
-
-                if (event.getToNode() != null) {
-                    System.out.println("Route: " + event.getRouteId() + "\t--> 
" + event.getToNode());
-                } else {
-                    System.out.println("Route: " + event.getRouteId());
-                }
-
-                String body = msg.getBody().getValue();
-                if (bodySize != null && bodySize > 0) {
-                    if (body.length() > bodySize) {
-                        body = body.substring(0, bodySize);
-                    }
-                }
-                System.out.println(body);
-                System.out.println("");
-            }
-        } else if ("xml".equals(format)) {
-            if (pattern != null) {
-                System.out.println("BacklogTracer messages:\n" + 
backlogTracer.dumpTracedMessages(pattern));
-            } else {
-                System.out.println("BacklogTracer messages:\n" + 
backlogTracer.dumpAllTracedMessagesAsXml());
-            }
-            return null;
-        }
-
-        return null;
+        BacklogTracerDumpCommand command = new 
BacklogTracerDumpCommand(context, pattern, format, bodySize);
+        return command.execute(camelController, System.out, System.err);
     }
 
-    private static String getBreadcrumbId(List<MessageDump.Header> headers) {
-        if (headers == null || headers.isEmpty()) {
-            return null;
-        }
-        for (MessageDump.Header header : headers) {
-            if (header.getKey().equals(Exchange.BREADCRUMB_ID)) {
-                return header.getValue();
-            }
-        }
-        return null;
-    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
----------------------------------------------------------------------
diff --git 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
index 7ef9af9..6bef670 100644
--- 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
+++ 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerInfo.java
@@ -16,8 +16,7 @@
  */
 package org.apache.camel.karaf.commands;
 
-import org.apache.camel.CamelContext;
-import org.apache.camel.processor.interceptor.BacklogTracer;
+import org.apache.camel.commands.BacklogTracerInfoCommand;
 import org.apache.felix.gogo.commands.Argument;
 import org.apache.felix.gogo.commands.Command;
 
@@ -32,28 +31,7 @@ public class BacklogTracerInfo extends CamelCommandSupport {
 
     @Override
     protected Object doExecute() throws Exception {
-        CamelContext camel = camelController.getCamelContext(context);
-        if (camel == null) {
-            System.err.println("CamelContext " + context + " not found.");
-            return null;
-        }
-
-        BacklogTracer backlogTracer = BacklogTracer.getBacklogTracer(camel);
-        if (backlogTracer == null) {
-            backlogTracer = (BacklogTracer) camel.getDefaultBacklogTracer();
-        }
-
-        System.out.println("BacklogTracer context:\t\t" + camel.getName());
-        System.out.println("BacklogTracer enabled:\t\t" + 
backlogTracer.isEnabled());
-        System.out.println("BacklogTracer pattern:\t\t" + 
(backlogTracer.getTracePattern() != null ? backlogTracer.getTracePattern() : 
""));
-        System.out.println("BacklogTracer filter:\t\t" + 
(backlogTracer.getTraceFilter() != null ? backlogTracer.getTraceFilter() : ""));
-        System.out.println("BacklogTracer removeOnDump:\t" + 
backlogTracer.isRemoveOnDump());
-        System.out.println("BacklogTracer backlogSize:\t" + 
backlogTracer.getBacklogSize());
-        System.out.println("BacklogTracer tracerCount:\t" + 
backlogTracer.getTraceCounter());
-        System.out.println("BacklogTracer body...");
-        System.out.println("\tmaxChars:\t\t" + 
backlogTracer.getBodyMaxChars());
-        System.out.println("\tincludeFiles:\t\t" + 
backlogTracer.isBodyIncludeFiles());
-        System.out.println("\tincludeStreams:\t\t" + 
backlogTracer.isBodyIncludeStreams());
-        return null;
+        BacklogTracerInfoCommand command = new 
BacklogTracerInfoCommand(context);
+        return command.execute(camelController, System.out, System.err);
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java
----------------------------------------------------------------------
diff --git 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java
 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java
index 4f88091..50d030c 100644
--- 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java
+++ 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStart.java
@@ -16,8 +16,7 @@
  */
 package org.apache.camel.karaf.commands;
 
-import org.apache.camel.CamelContext;
-import org.apache.camel.processor.interceptor.BacklogTracer;
+import org.apache.camel.commands.BacklogTracerStartCommand;
 import org.apache.felix.gogo.commands.Argument;
 import org.apache.felix.gogo.commands.Command;
 import org.apache.felix.gogo.commands.Option;
@@ -50,29 +49,8 @@ public class BacklogTracerStart extends CamelCommandSupport {
 
     @Override
     protected Object doExecute() throws Exception {
-        CamelContext camel = camelController.getCamelContext(context);
-        if (camel == null) {
-            System.err.println("CamelContext " + context + " not found.");
-            return null;
-        }
-
-        BacklogTracer backlogTracer = BacklogTracer.getBacklogTracer(camel);
-        if (backlogTracer == null) {
-            backlogTracer = (BacklogTracer) camel.getDefaultBacklogTracer();
-        }
-
-        backlogTracer.setEnabled(true);
-        if (backlogSize != null) {
-            backlogTracer.setBacklogSize(backlogSize);
-        }
-        if (removeOnDump != null) {
-            backlogTracer.setRemoveOnDump(removeOnDump);
-        }
-        backlogTracer.setTracePattern(pattern);
-        backlogTracer.setTraceFilter(filter);
-
-        System.out.println("BacklogTracer started on " + camel.getName() + " 
with size: " + backlogTracer.getBacklogSize());
-        return null;
+        BacklogTracerStartCommand command = new 
BacklogTracerStartCommand(context, pattern, filter, backlogSize, removeOnDump);
+        return command.execute(camelController, System.out, System.err);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f5b76564/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStop.java
----------------------------------------------------------------------
diff --git 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStop.java
 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStop.java
index d1d9d76..7ee56f8 100644
--- 
a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStop.java
+++ 
b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/BacklogTracerStop.java
@@ -16,8 +16,7 @@
  */
 package org.apache.camel.karaf.commands;
 
-import org.apache.camel.CamelContext;
-import org.apache.camel.processor.interceptor.BacklogTracer;
+import org.apache.camel.commands.BacklogTracerStopCommand;
 import org.apache.felix.gogo.commands.Argument;
 import org.apache.felix.gogo.commands.Command;
 
@@ -32,23 +31,8 @@ public class BacklogTracerStop extends CamelCommandSupport {
 
     @Override
     protected Object doExecute() throws Exception {
-        CamelContext camel = camelController.getCamelContext(context);
-        if (camel == null) {
-            System.err.println("CamelContext " + context + " not found.");
-            return null;
-        }
-
-        BacklogTracer backlogTracer = BacklogTracer.getBacklogTracer(camel);
-        if (backlogTracer == null) {
-            backlogTracer = (BacklogTracer) camel.getDefaultBacklogTracer();
-        }
-
-        // disable tracer and clear counter and the backlog queue
-        backlogTracer.setEnabled(false);
-        backlogTracer.resetTraceCounter();
-        backlogTracer.clear();
-        System.out.println("BacklogTracer stopped on " + camel.getName());
-        return null;
+        BacklogTracerStopCommand command = new 
BacklogTracerStopCommand(context);
+        return command.execute(camelController, System.out, System.err);
     }
 
 }

Reply via email to