Search in sources :

Example 26 with CliCommand

use of org.springframework.roo.shell.CliCommand in project spring-roo by spring-projects.

the class HelpServiceImpl method obtainHelp.

/**
 * If the given pattern matches several commands, i.e. "web mvc"
 * or empty, this method writes to {@link #LOGGER} the list of
 * commands (command index) which names start with the given pattern.
 *
 * If the given pattern matches with only one command, this method
 * writes to {@link #LOGGER} the full info about that command.
 *
 * @param pattern
 */
public void obtainHelp(String pattern) {
    synchronized (mutex) {
        if (pattern == null) {
            pattern = "";
        }
        Template helpTemplate;
        // Create the data-model for Freemarker engine.
        Map<String, Object> fmContext = new HashMap<String, Object>();
        fmContext.put("LINE_SEPARATOR", IOUtils.LINE_SEPARATOR);
        fmContext.put("CMD_MAX_LENGTH", CMD_MAX_LENGTH);
        fmContext.put("OPT_MAX_LENGTH", OPT_MAX_LENGTH);
        // Get the methods annotated with @CliCommand that matches the pattern
        final Collection<MethodTarget> matchingTargets = locateTargets(pattern, false, false);
        try {
            // In that case the full command help will be rendered.
            if (matchingTargets.size() == 1) {
                helpTemplate = new Template("cmdTemplate", new StringReader(cmdTemplateStr), new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS));
                // Single command help
                final MethodTarget methodTarget = matchingTargets.iterator().next();
                // Argument conversion time
                final Annotation[][] parameterAnnotations = methodTarget.getMethod().getParameterAnnotations();
                // Offer specified help
                final CliCommand cmd = methodTarget.getMethod().getAnnotation(CliCommand.class);
                Validate.notNull(cmd, "CliCommand not found");
                // The command has options, those method arguments annotated with @CliOption
                if (parameterAnnotations.length > 0) {
                    // Synopsis
                    fmContext.put("synopsis", justify(cmd.value(), CMD_HELP_LEFT_PAD, LINE_MAX_LENGTH));
                    // Description
                    fmContext.put("description", justify(cmd.help(), CMD_HELP_LEFT_PAD, LINE_MAX_LENGTH));
                    // Options
                    Map<String, List<String>> options = new TreeMap<String, List<String>>();
                    fmContext.put("options", options);
                    // method arguments annotated with the @CliOption annotation
                    for (final Annotation[] annotations : parameterAnnotations) {
                        CliOption cliOption = null;
                        for (final Annotation a : annotations) {
                            if (a instanceof CliOption) {
                                cliOption = (CliOption) a;
                                for (final String option : cliOption.key()) {
                                    String dashOption = "--".concat(option);
                                    // Note justification should be done in the Freemarker template,
                                    // but it is easier to do it here and adjust both justifications
                                    // (cmd name and cmd help) depending on the cmd name length
                                    String optStr = StringUtils.repeat(" ", CMD_HELP_LEFT_PAD) + (dashOption.length() <= OPT_MAX_LENGTH ? StringUtils.rightPad(dashOption, OPT_MAX_LENGTH) : dashOption);
                                    // Add as left padding the cmd length to avoid overwrite the command on the left
                                    // +1 to add an empty char (space) between the command and the description
                                    options.put(optStr, justify(cliOption.help(), CMD_HELP_LEFT_PAD + OPT_MAX_LENGTH, LINE_MAX_LENGTH));
                                }
                            }
                        }
                    }
                } else // The command hasn't options, usually methods without arguments
                {
                    // Synopsis
                    fmContext.put("synopsis", justify(cmd.value(), CMD_HELP_LEFT_PAD, LINE_MAX_LENGTH));
                    // Description
                    fmContext.put("description", justify(cmd.help(), CMD_HELP_LEFT_PAD, LINE_MAX_LENGTH));
                }
            } else // There are several commands that matches the pattern. Example: "web mvc"
            // In that case only a list of command names and descriptions will be rendered.
            {
                helpTemplate = new Template("cmdIndexTemplate", new StringReader(cmdIndexTemplateStr), new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS));
                // Create the list of commands that start with the given token.
                // Note that empty token will cause all commands will be rendered.
                Map<String, List<String>> cmdList = new TreeMap<String, List<String>>();
                // method annotation @CliCommand
                for (final MethodTarget mt : matchingTargets) {
                    final CliCommand cmd = mt.getMethod().getAnnotation(CliCommand.class);
                    if (cmd != null) {
                        for (final String value : cmd.value()) {
                            // Note justification should be done in the Freemarker template,
                            // but it is easier to do it here and adjust both justifications
                            // (cmd name and cmd help) depending on the cmd name length
                            String cmdStr = StringUtils.repeat(" ", CMD_INDEX_LEFT_PAD) + (value.length() <= CMD_MAX_LENGTH ? StringUtils.rightPad(value, CMD_MAX_LENGTH) : value);
                            // Add as left padding the cmd length to avoid overwrite the command on the left
                            // +1 to add an empty char (space) between the command and the description
                            cmdList.put(cmdStr, justify(cmd.help(), CMD_INDEX_LEFT_PAD + CMD_MAX_LENGTH, LINE_MAX_LENGTH));
                        }
                    }
                }
                // Add the command list to the Freemarker context
                fmContext.put("commands", cmdList);
            }
            // Merge data-model with template
            Writer strWriter = new StringWriter();
            helpTemplate.process(fmContext, strWriter);
            LOGGER.info(strWriter.toString());
        } catch (TemplateException e) {
            LOGGER.log(Level.SEVERE, "Help engine internal error!", e);
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, "Help engine internal error!", e);
        }
        LOGGER.warning("** Type 'hint' (without the quotes) and hit ENTER " + "for step-by-step guidance **" + LINE_SEPARATOR);
    }
}
Also used : MethodTarget(org.springframework.roo.shell.MethodTarget) Configuration(freemarker.template.Configuration) HashMap(java.util.HashMap) TemplateException(freemarker.template.TemplateException) IOException(java.io.IOException) TreeMap(java.util.TreeMap) Annotation(java.lang.annotation.Annotation) Template(freemarker.template.Template) CliOption(org.springframework.roo.shell.CliOption) StringWriter(java.io.StringWriter) StringReader(java.io.StringReader) CliCommand(org.springframework.roo.shell.CliCommand) List(java.util.List) ArrayList(java.util.ArrayList) Writer(java.io.Writer) StringWriter(java.io.StringWriter)

Aggregations

CliCommand (org.springframework.roo.shell.CliCommand)26 ClassOrInterfaceTypeDetails (org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails)12 ArrayList (java.util.ArrayList)4 PGPPublicKeyRing (org.bouncycastle.openpgp.PGPPublicKeyRing)4 IOException (java.io.IOException)3 Pom (org.springframework.roo.project.maven.Pom)3 TemplateException (freemarker.template.TemplateException)2 Annotation (java.lang.annotation.Annotation)2 Method (java.lang.reflect.Method)2 HashMap (java.util.HashMap)2 TreeMap (java.util.TreeMap)2 InvalidSyntaxException (org.osgi.framework.InvalidSyntaxException)2 ServiceReference (org.osgi.framework.ServiceReference)2 JavaPackage (org.springframework.roo.model.JavaPackage)2 CliOption (org.springframework.roo.shell.CliOption)2 CommandMarker (org.springframework.roo.shell.CommandMarker)2 MethodTarget (org.springframework.roo.shell.MethodTarget)2 Configuration (freemarker.template.Configuration)1 Template (freemarker.template.Template)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1