You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2014/05/19 21:16:28 UTC

[5/5] git commit: Fix manual and command help generation

Fix manual and command help generation


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

Branch: refs/heads/master
Commit: 49aeec2b73d3227ba78fb6bef7e025aafced8577
Parents: 0cf070d
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon May 19 10:53:45 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon May 19 21:16:05 2014 +0200

----------------------------------------------------------------------
 manual/pom.xml                                  | 41 +---------
 .../WEB-INF/scalate/layouts/default.scaml       |  2 +-
 manual/src/main/webapp/manual.conf              |  2 +-
 pom.xml                                         |  6 +-
 .../commands/AbstractCommandHelpPrinter.java    | 85 ++++++++++++++++++++
 .../tooling/commands/CommandHelpPrinter.java    |  6 +-
 .../commands/DocBookCommandHelpPrinter.java     | 74 ++++++++++-------
 .../tooling/commands/GenerateHelpMojo.java      | 11 +--
 .../commands/UserConfCommandHelpPrinter.java    | 67 +++++++++------
 9 files changed, 186 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/manual/pom.xml
----------------------------------------------------------------------
diff --git a/manual/pom.xml b/manual/pom.xml
index db14ba7..768fd21 100644
--- a/manual/pom.xml
+++ b/manual/pom.xml
@@ -167,7 +167,7 @@
                     </dependency>
                     <dependency>
                         <groupId>org.apache.karaf.shell</groupId>
-                        <artifactId>org.apache.karaf.shell.console</artifactId>
+                        <artifactId>org.apache.karaf.shell.core</artifactId>
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
@@ -176,32 +176,17 @@
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
-                        <groupId>org.apache.karaf.log</groupId>
-                        <artifactId>org.apache.karaf.log.command</artifactId>
-                        <version>${project.version}</version>
-                    </dependency>
-                    <dependency>
                         <groupId>org.apache.karaf.obr</groupId>
                         <artifactId>org.apache.karaf.obr.core</artifactId>
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
-                        <groupId>org.apache.karaf.obr</groupId>
-                        <artifactId>org.apache.karaf.obr.command</artifactId>
-                        <version>${project.version}</version>
-                    </dependency>
-                    <dependency>
                         <groupId>org.apache.karaf.bundle</groupId>
                         <artifactId>org.apache.karaf.bundle.core</artifactId>
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
                         <groupId>org.apache.karaf.bundle</groupId>
-                        <artifactId>org.apache.karaf.bundle.command</artifactId>
-                        <version>${project.version}</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.apache.karaf.bundle</groupId>
                         <artifactId>org.apache.karaf.bundle.springstate</artifactId>
                         <version>${project.version}</version>
                     </dependency>
@@ -211,16 +196,6 @@
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
-                        <groupId>org.apache.karaf.service</groupId>
-                        <artifactId>org.apache.karaf.service.command</artifactId>
-                        <version>${project.version}</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.apache.karaf.system</groupId>
-                        <artifactId>org.apache.karaf.system.command</artifactId>
-                        <version>${project.version}</version>
-                    </dependency>
-                    <dependency>
                         <groupId>org.apache.karaf.system</groupId>
                         <artifactId>org.apache.karaf.system.core</artifactId>
                         <version>${project.version}</version>
@@ -232,32 +207,22 @@
                     </dependency>
                     <dependency>
                         <groupId>org.apache.karaf.web</groupId>
-                        <artifactId>org.apache.karaf.web.command</artifactId>
-                        <version>${project.version}</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.apache.karaf.web</groupId>
                         <artifactId>org.apache.karaf.web.core</artifactId>
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
                         <groupId>org.apache.karaf.wrapper</groupId>
-                        <artifactId>org.apache.karaf.wrapper.command</artifactId>
-                        <version>${project.version}</version>
-                    </dependency>
-                    <dependency>
-                        <groupId>org.apache.karaf.wrapper</groupId>
                         <artifactId>org.apache.karaf.wrapper.core</artifactId>
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
                         <groupId>org.apache.karaf.instance</groupId>
-                        <artifactId>org.apache.karaf.instance.command</artifactId>
+                        <artifactId>org.apache.karaf.instance.core</artifactId>
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>
                         <groupId>org.apache.karaf.diagnostic</groupId>
-                        <artifactId>org.apache.karaf.diagnostic.command</artifactId>
+                        <artifactId>org.apache.karaf.diagnostic.core</artifactId>
                         <version>${project.version}</version>
                     </dependency>
                     <dependency>

http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml b/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml
index c88ba58..e4f22cd 100644
--- a/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml
+++ b/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml
@@ -98,7 +98,7 @@
         %td#cell-3-2
           #footer
             #site-footer
-              &copy; 2008-2011 The Apache Software Foundation
+              &copy; 2008-2014 The Apache Software Foundation
               %br
               Apache Karaf, Karaf, Apache, the Apache feather logo, and the Apache Karaf project logo are trademarks of The Apache Software Foundation.
         %td#cell-3-3

http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/manual/src/main/webapp/manual.conf
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/manual.conf b/manual/src/main/webapp/manual.conf
index db428da..de21749 100644
--- a/manual/src/main/webapp/manual.conf
+++ b/manual/src/main/webapp/manual.conf
@@ -15,7 +15,7 @@ Users' Guide
 {div}
 
 {div:class=copyright-section}
-Copyright 2011 The Apache Software Foundation
+Copyright 2008-2014 The Apache Software Foundation
 
 The PDF format of the Karaf Manual has been generated by Prince XML (http://www.princexml.com).
 {div}

http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8aeb574..fe95af6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2250,9 +2250,9 @@
                                 <exclude>**/foo</exclude>
                                 <exclude>**/org.ops4j.pax.exam.TestContainerFactory</exclude>
                                 <!--manual resources -->
-                                <exclude>manual/**/*.css</exclude>
-                                <exclude>manual/**/*.ssp</exclude>
-                                <exclude>manual/**/*.conf</exclude>
+                                <exclude>**/*.css</exclude>
+                                <exclude>**/*.ssp</exclude>
+                                <exclude>**/*.conf</exclude>
                                 <!-- test manifests -->
                                 <exclude>**/*.mf</exclude>
                                 <!-- test json files -->

http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/AbstractCommandHelpPrinter.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/AbstractCommandHelpPrinter.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/AbstractCommandHelpPrinter.java
new file mode 100644
index 0000000..dee1eb9
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/AbstractCommandHelpPrinter.java
@@ -0,0 +1,85 @@
+/**
+ * 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.karaf.tooling.commands;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+
+public abstract class AbstractCommandHelpPrinter implements CommandHelpPrinter {
+
+    protected Argument replaceDefaultArgument(Field field, Argument argument) {
+        if (Argument.DEFAULT.equals(argument.name())) {
+            final Argument delegate = argument;
+            final String name = field.getName();
+            argument = new Argument() {
+                public String name() {
+                    return name;
+                }
+
+                public String description() {
+                    return delegate.description();
+                }
+
+                public boolean required() {
+                    return delegate.required();
+                }
+
+                public int index() {
+                    return delegate.index();
+                }
+
+                public boolean multiValued() {
+                    return delegate.multiValued();
+                }
+
+                public String valueToShowInHelp() {
+                    return delegate.valueToShowInHelp();
+                }
+
+                public Class<? extends Annotation> annotationType() {
+                    return delegate.annotationType();
+                }
+            };
+        }
+        return argument;
+    }
+
+    protected Object getDefaultValue(Action action, Field field) {
+        try {
+            field.setAccessible(true);
+            return field.get(action);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    protected String getDefaultValueString(Object o) {
+        if (o != null
+                && (!(o instanceof Boolean) || ((Boolean) o))
+                && (!(o instanceof Number) || ((Number) o).doubleValue() != 0.0)) {
+            return o.toString();
+        } else {
+            return null;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java
index 5fae3db..f255434 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java
@@ -22,19 +22,17 @@ import java.io.PrintStream;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.karaf.shell.commands.Action;
-import org.apache.karaf.shell.commands.meta.ActionMetaData;
+import org.apache.karaf.shell.api.action.Action;
 
 public interface CommandHelpPrinter {
     /**
      * Print help for a single action to the out stream
      * 
      * @param action
-     * @param actionMeta
      * @param out stream to write to
      * @param includeHelpOption include the help option in the doc
      */
-    void printHelp(Action action, ActionMetaData actionMeta, PrintStream out, boolean includeHelpOption);
+    void printHelp(Action action, PrintStream out, boolean includeHelpOption);
     
     /**
      * Print the overview of all given commands to the out stream 

http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java
index 7467b9a..d40841c 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java
@@ -21,38 +21,53 @@ package org.apache.karaf.tooling.commands;
 import java.io.PrintStream;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.karaf.shell.commands.Action;
-import org.apache.karaf.shell.commands.Argument;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.HelpOption;
-import org.apache.karaf.shell.commands.Option;
-import org.apache.karaf.shell.commands.meta.ActionMetaData;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.impl.action.command.HelpOption;
+
 
 /**
  * Prints documentation in docbook syntax
  */
-public class DocBookCommandHelpPrinter implements CommandHelpPrinter {
+public class DocBookCommandHelpPrinter extends AbstractCommandHelpPrinter {
 
     @Override
-    public void printHelp(Action action, ActionMetaData actionMeta, PrintStream out, boolean includeHelpOption) {
-
-        Map<Option, Field> optionsMap = actionMeta.getOptions();
-        Map<Argument, Field> argsMap = actionMeta.getArguments();
+    public void printHelp(Action action, PrintStream out, boolean includeHelpOption) {
         Command command = action.getClass().getAnnotation(Command.class);
-        List<Argument> arguments = new ArrayList<Argument>(argsMap.keySet());
-        Collections.sort(arguments, new Comparator<Argument>() {
-            public int compare(Argument o1, Argument o2) {
-                return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
+        Set<Option> options = new HashSet<>();
+        List<Argument> arguments = new ArrayList<Argument>();
+        Map<Argument, Field> argFields = new HashMap<>();
+        Map<Option, Field> optFields = new HashMap<>();
+        for (Class<?> type = action.getClass(); type != null; type = type.getSuperclass()) {
+            for (Field field : type.getDeclaredFields()) {
+                Option option = field.getAnnotation(Option.class);
+                if (option != null) {
+                    options.add(option);
+                }
+
+                Argument argument = field.getAnnotation(Argument.class);
+                if (argument != null) {
+                    argument = replaceDefaultArgument(field, argument);
+                    argFields.put(argument, field);
+                    int index = argument.index();
+                    while (arguments.size() <= index) {
+                        arguments.add(null);
+                    }
+                    if (arguments.get(index) != null) {
+                        throw new IllegalArgumentException("Duplicate argument index: " + index + " on Action " + action.getClass().getName());
+                    }
+                    arguments.set(index, argument);
+                }
             }
-        });
-        Set<Option> options = new HashSet<Option>(optionsMap.keySet());
+        }
         if (includeHelpOption)
             options.add(HelpOption.HELP);
 
@@ -92,10 +107,14 @@ public class DocBookCommandHelpPrinter implements CommandHelpPrinter {
                 out.println("      <td>" + argument.name() + "</td>");
                 String description = argument.description();
                 if (!argument.required()) {
-                    Object o = actionMeta.getDefaultValue(action, argument);
-                    String defaultValue = actionMeta.getDefaultValueString(o);
-                    if (defaultValue != null) {
-                        description += " (defaults to " + o.toString() + ")";
+                    if (argument.valueToShowInHelp() != null && argument.valueToShowInHelp().length() != 0) {
+                        if (Argument.DEFAULT_STRING.equals(argument.valueToShowInHelp())) {
+                            Object o = getDefaultValue(action, argFields.get(argument));
+                            String defaultValue = getDefaultValueString(o);
+                            if (defaultValue != null) {
+                                description += " (defaults to " + o.toString() + ")";
+                            }
+                        }
                     }
                 }
                 out.println("      <td>" + description + "</td>");
@@ -117,8 +136,8 @@ public class DocBookCommandHelpPrinter implements CommandHelpPrinter {
                 for (String alias : option.aliases()) {
                     opt += ", " + alias;
                 }
-                Object o = actionMeta.getDefaultValue(action, option);
-                String defaultValue = actionMeta.getDefaultValueString(o);
+                Object o = getDefaultValue(action, optFields.get(option));
+                String defaultValue = getDefaultValueString(o);
                 if (defaultValue != null) {
                     description += " (defaults to " + o.toString() + ")";
                 }
@@ -132,12 +151,11 @@ public class DocBookCommandHelpPrinter implements CommandHelpPrinter {
             out.println("  </section>");
         }
 
-        String desc = actionMeta.getDetailedDescription();
-        if (desc != null) {
+        if (command.detailedDescription().length() > 0) {
             out.println("  <section>");
             out.println("    <title>Details</title>");
             out.println("    <para>");
-            out.println(desc);
+            out.println(command.detailedDescription());
             out.println("    </para>");
             out.println("  </section>");
         }

http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
index 7416640..b75a766 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
@@ -30,10 +30,8 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.TreeSet;
 
-import org.apache.karaf.shell.commands.Action;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.meta.ActionMetaData;
-import org.apache.karaf.shell.commands.meta.ActionMetaDataFactory;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
 import org.apache.maven.artifact.DependencyResolutionRequiredException;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -118,8 +116,7 @@ public class GenerateHelpMojo extends AbstractMojo {
             for (Class<?> clazz : classes) {
                 try {
                     Action action = (Action) clazz.newInstance();
-                    ActionMetaData meta = new ActionMetaDataFactory().create(action.getClass());
-                    Command cmd = meta.getCommand();
+                    Command cmd = clazz.getAnnotation(Command.class);
 
                     // skip the *-help command
                     if (cmd.scope().equals("*")) continue;
@@ -127,7 +124,7 @@ public class GenerateHelpMojo extends AbstractMojo {
                     File output = new File(targetFolder, cmd.scope() + "-" + cmd.name() + "." + commandSuffix);
                     FileOutputStream outStream = new FileOutputStream(output);
                     PrintStream out = new PrintStream(outStream);
-                    helpPrinter.printHelp(action, meta, out, includeHelpOption);
+                    helpPrinter.printHelp(action, out, includeHelpOption);
                     out.close();
                     outStream.close();
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java
index 468386f..59f7bd9 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java
@@ -21,37 +21,53 @@ package org.apache.karaf.tooling.commands;
 import java.io.PrintStream;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.karaf.shell.commands.Action;
-import org.apache.karaf.shell.commands.Argument;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.HelpOption;
-import org.apache.karaf.shell.commands.Option;
-import org.apache.karaf.shell.commands.meta.ActionMetaData;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.impl.action.command.HelpOption;
+
 
 /**
  * Prints documentation in wiki syntax
  */
-public class UserConfCommandHelpPrinter implements CommandHelpPrinter {
+public class UserConfCommandHelpPrinter extends AbstractCommandHelpPrinter {
 
     @Override
-    public void printHelp(Action action, ActionMetaData actionMeta, PrintStream out, boolean includeHelpOption) {
-        Map<Option, Field> optionsMap = actionMeta.getOptions();
-        Map<Argument, Field> argsMap = actionMeta.getArguments();
-        Command command = actionMeta.getCommand();
-        List<Argument> arguments = new ArrayList<Argument>(argsMap.keySet());
-        Collections.sort(arguments, new Comparator<Argument>() {
-            public int compare(Argument o1, Argument o2) {
-                return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
+    public void printHelp(Action action, PrintStream out, boolean includeHelpOption) {
+        Command command = action.getClass().getAnnotation(Command.class);
+        Set<Option> options = new HashSet<>();
+        List<Argument> arguments = new ArrayList<Argument>();
+        Map<Argument, Field> argFields = new HashMap<>();
+        Map<Option, Field> optFields = new HashMap<>();
+        for (Class<?> type = action.getClass(); type != null; type = type.getSuperclass()) {
+            for (Field field : type.getDeclaredFields()) {
+                Option option = field.getAnnotation(Option.class);
+                if (option != null) {
+                    options.add(option);
+                }
+
+                Argument argument = field.getAnnotation(Argument.class);
+                if (argument != null) {
+                    argument = replaceDefaultArgument(field, argument);
+                    argFields.put(argument, field);
+                    int index = argument.index();
+                    while (arguments.size() <= index) {
+                        arguments.add(null);
+                    }
+                    if (arguments.get(index) != null) {
+                        throw new IllegalArgumentException("Duplicate argument index: " + index + " on Action " + action.getClass().getName());
+                    }
+                    arguments.set(index, argument);
+                }
             }
-        });
-        Set<Option> options = new HashSet<Option>(optionsMap.keySet());
+        }
         if (includeHelpOption)
             options.add(HelpOption.HELP);
 
@@ -83,8 +99,8 @@ public class UserConfCommandHelpPrinter implements CommandHelpPrinter {
             for (Argument argument : arguments) {
                 String description = argument.description();
                 if (!argument.required()) {
-                    Object o = actionMeta.getDefaultValue(action, argument);
-                    String defaultValue = actionMeta.getDefaultValueString(o);
+                    Object o = getDefaultValue(action, argFields.get(argument));
+                    String defaultValue = getDefaultValueString(o);
                     if (defaultValue != null) {
                         description += " (defaults to " + o.toString() + ")";
                     }
@@ -102,8 +118,8 @@ public class UserConfCommandHelpPrinter implements CommandHelpPrinter {
                 for (String alias : option.aliases()) {
                     opt += ", " + alias;
                 }
-                Object o = actionMeta.getDefaultValue(action, option);
-                String defaultValue = actionMeta.getDefaultValueString(o);
+                Object o = getDefaultValue(action, optFields.get(option));
+                String defaultValue = getDefaultValueString(o);
                 if (defaultValue != null) {
                     desc += " (defaults to " + defaultValue + ")";
                 }
@@ -111,10 +127,9 @@ public class UserConfCommandHelpPrinter implements CommandHelpPrinter {
             }
             out.println();
         }
-        String detailedDesc = actionMeta.getDetailedDescription();
-        if (detailedDesc != null) {
+        if (command.detailedDescription().length() > 0) {
             out.println("h2. Details");
-            out.println(detailedDesc);
+            out.println(command.detailedDescription());
         }
         out.println();
     }