Search in sources :

Example 1 with CommandLineTool

use of com.unboundid.util.CommandLineTool in project ldapsdk by pingidentity.

the class GenerateToolUsage method generateHTMLIndexPage.

/**
 * Generates an HTML index page for the provided set of tools.
 *
 * @param  toolClasses  A list of classes that provide command-line tool
 *                      functionality.
 *
 * @throws  BuildException  If a problem is encountered while generating the
 *                          index page.
 */
private void generateHTMLIndexPage(final List<Class<? extends CommandLineTool>> toolClasses) {
    final File outputFile = new File(outputDirectory, "index.html");
    try (final PrintWriter w = new PrintWriter(outputFile)) {
        w.println("<!DOCTYPE HTML PUBLIC " + "\"-//W3C//DTD HTML 4.01 Transitional//EN\" " + "\"http://www.w3.org/TR/html4/loose.dtd\">");
        w.println("<html>");
        w.println("  <head>");
        w.println("    <title>Available Commmand-Line Tools</title>");
        w.println("    <meta http-equiv=\"Content-Type\" " + "content=\"text/html; charset=utf-8\">");
        w.println("    <link rel=\"stylesheet\" " + "href=\"../unboundid.css\" type=\"text/css\">");
        w.println("    <link rel=\"shortcut icon\" " + "href=\"../images/favicon.ico\">");
        w.println("  </head>");
        w.println();
        w.println("  <body>");
        w.println("    <h1>Available Command-Line Tools</h1>");
        w.println("    <p>The following command-line tools are provided with " + "the UnboundID LDAP SDK for Java.  Click on each tool name " + "for usage information for that tool.</p>");
        final TreeMap<String, CommandLineTool> toolMap = new TreeMap<>();
        for (final Class<? extends CommandLineTool> toolClass : toolClasses) {
            final ByteArrayOutputStream out = new ByteArrayOutputStream();
            final CommandLineTool t = Launcher.getToolInstance(toolClass, out, out);
            toolMap.put(t.getToolName(), t);
        }
        for (final CommandLineTool t : toolMap.values()) {
            w.println();
            w.println("    <h3><a href=\"" + t.getToolName() + ".html\">" + t.getToolName() + "</a></h3>");
            w.println("    <p>" + htmlEscape(t.getToolDescription()) + "</p>");
        }
        w.println("  </body>");
        w.println("</html>");
    } catch (final Exception e) {
        throw new BuildException("Error creating the HTML index page:  " + StaticUtils.getExceptionMessage(e), e);
    }
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) BuildException(org.apache.tools.ant.BuildException) TreeMap(java.util.TreeMap) File(java.io.File) CommandLineTool(com.unboundid.util.CommandLineTool) BuildException(org.apache.tools.ant.BuildException) PrintWriter(java.io.PrintWriter)

Example 2 with CommandLineTool

use of com.unboundid.util.CommandLineTool in project ldapsdk by pingidentity.

the class GenerateToolUsage method execute.

/**
 * Generates usage information for each of the tools provided with the LDAP
 * SDK.
 *
 * @throws  BuildException  If a problem occurs while generating the usage
 *                          information.
 */
@Override()
public void execute() throws BuildException {
    final List<Class<? extends CommandLineTool>> toolClasses = Launcher.getToolClasses();
    for (final Class<? extends CommandLineTool> c : toolClasses) {
        try {
            generateTextUsage(c);
            generateHTMLUsage(c);
        } catch (final Exception e) {
            throw new BuildException("Error creating plain-text usage information for tool class " + c.getName() + ":  " + StaticUtils.getExceptionMessage(e), e);
        }
    }
    generateHTMLIndexPage(toolClasses);
}
Also used : BuildException(org.apache.tools.ant.BuildException) CommandLineTool(com.unboundid.util.CommandLineTool) BuildException(org.apache.tools.ant.BuildException)

Example 3 with CommandLineTool

use of com.unboundid.util.CommandLineTool in project ldapsdk by pingidentity.

the class GenerateToolUsage method generateTextUsage.

/**
 * Generates plain-text usage information for the specified command-line tool.
 *
 * @param  c  The command-line tool class for which to obtain usage
 *            information.
 *
 * @throws  Exception  If an unexpected problem occurs.
 */
private void generateTextUsage(final Class<? extends CommandLineTool> c) throws Exception {
    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    final CommandLineTool t = Launcher.getToolInstance(c, out, out);
    final ArgumentParser p = t.createArgumentParser();
    final File outputFile = new File(outputDirectory, t.getToolName() + ".txt");
    try (final PrintWriter w = new PrintWriter(outputFile)) {
        if (p.hasSubCommands()) {
            w.println("The " + t.getToolName() + " Command-Line Tool");
            w.println();
            w.println("Global Usage:");
            w.println();
            w.println(p.getUsageString(79));
            writeExamples(w, t.getToolName(), null, t.getExampleUsages());
            w.println();
            w.println();
            w.println();
            w.println("Available Subcommands:");
            final List<SubCommand> subCommands = p.getSubCommands();
            if (anySubcommandsHaveMultipleNames(subCommands)) {
                for (final SubCommand sc : subCommands) {
                    final List<String> names = sc.getNames(false);
                    if (!names.isEmpty()) {
                        w.println();
                        final Iterator<String> nameIterator = names.iterator();
                        w.println("* " + nameIterator.next());
                        while (nameIterator.hasNext()) {
                            w.println("  " + nameIterator.next());
                        }
                    }
                }
            } else {
                for (final SubCommand sc : subCommands) {
                    w.println("* " + sc.getPrimaryName());
                }
            }
            for (final SubCommand sc : p.getSubCommands()) {
                w.println();
                w.println();
                w.println();
                w.println("Usage for subcommand " + sc.getPrimaryName() + ':');
                w.println();
                w.println(sc.getArgumentParser().getUsageString(79));
                writeExamples(w, t.getToolName(), sc.getPrimaryName(), sc.getExampleUsages());
            }
        } else {
            w.println("Usage for " + t.getToolName() + ":");
            w.println();
            w.println(p.getUsageString(79));
            writeExamples(w, t.getToolName(), null, t.getExampleUsages());
        }
    }
}
Also used : SubCommand(com.unboundid.util.args.SubCommand) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ArgumentParser(com.unboundid.util.args.ArgumentParser) File(java.io.File) CommandLineTool(com.unboundid.util.CommandLineTool) PrintWriter(java.io.PrintWriter)

Example 4 with CommandLineTool

use of com.unboundid.util.CommandLineTool in project ldapsdk by pingidentity.

the class ArgumentParser method handlePropertiesFile.

/**
 * Reads the contents of the specified properties file and updates the
 * configured arguments as appropriate.
 *
 * @param  propertiesFile       The properties file to process.
 * @param  skipFinalValidation  A flag that indicates whether to skip final
 *                              validation because a qualifying usage argument
 *                              was provided.
 *
 * @throws  ArgumentException  If a problem is encountered while examining the
 *                             properties file, or while trying to assign a
 *                             property value to a corresponding argument.
 */
private void handlePropertiesFile(@NotNull final File propertiesFile, @NotNull final AtomicBoolean skipFinalValidation) throws ArgumentException {
    final String propertiesFilePath = propertiesFile.getAbsolutePath();
    InputStream inputStream = null;
    final BufferedReader reader;
    try {
        inputStream = new FileInputStream(propertiesFile);
        // Handle the case in which the properties file may be encrypted.
        final List<char[]> cachedPasswords;
        final PrintStream err;
        final PrintStream out;
        final CommandLineTool tool = commandLineTool;
        if (tool == null) {
            cachedPasswords = Collections.emptyList();
            out = System.out;
            err = System.err;
        } else {
            cachedPasswords = tool.getPasswordFileReader().getCachedEncryptionPasswords();
            out = tool.getOut();
            err = tool.getErr();
        }
        final ObjectPair<InputStream, char[]> encryptionData = ToolUtils.getPossiblyPassphraseEncryptedInputStream(inputStream, cachedPasswords, true, INFO_PARSER_PROMPT_FOR_PROP_FILE_ENC_PW.get(propertiesFile.getAbsolutePath()), ERR_PARSER_WRONG_PROP_FILE_ENC_PW.get(propertiesFile.getAbsolutePath()), out, err);
        inputStream = encryptionData.getFirst();
        if ((tool != null) && (encryptionData.getSecond() != null)) {
            tool.getPasswordFileReader().addToEncryptionPasswordCache(encryptionData.getSecond());
        }
        // Handle the case in which the properties file may be compressed.
        inputStream = ToolUtils.getPossiblyGZIPCompressedInputStream(inputStream);
        // The java.util.Properties specification states that properties files
        // should be read using the ISO 8859-1 character set, and that characters
        // that cannot be encoded in that format should be represented using
        // Unicode escapes that start with a backslash, a lowercase letter "u",
        // and four hexadecimal digits.  To provide compatibility with the Java
        // Properties file format (except we also support the same property
        // appearing multiple times), we will also use that encoding and will
        // support Unicode escape sequences.
        reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.ISO_8859_1));
    } catch (final Exception e) {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (final Exception e2) {
                Debug.debugException(e2);
            }
        }
        Debug.debugException(e);
        throw new ArgumentException(ERR_PARSER_CANNOT_OPEN_PROP_FILE.get(propertiesFilePath, StaticUtils.getExceptionMessage(e)), e);
    }
    try {
        // Read all of the lines of the file, ignoring comments and unwrapping
        // properties that span multiple lines.
        boolean lineIsContinued = false;
        int lineNumber = 0;
        final ArrayList<ObjectPair<Integer, StringBuilder>> propertyLines = new ArrayList<>(10);
        while (true) {
            String line;
            try {
                line = reader.readLine();
                lineNumber++;
            } catch (final Exception e) {
                Debug.debugException(e);
                throw new ArgumentException(ERR_PARSER_ERROR_READING_PROP_FILE.get(propertiesFilePath, StaticUtils.getExceptionMessage(e)), e);
            }
            // expect a previous line to have been continued, then this is an error.
            if (line == null) {
                if (lineIsContinued) {
                    throw new ArgumentException(ERR_PARSER_PROP_FILE_MISSING_CONTINUATION.get((lineNumber - 1), propertiesFilePath));
                }
                break;
            }
            // See if the line has any leading whitespace, and if so then trim it
            // off.  If there is leading whitespace, then make sure that we expect
            // the previous line to be continued.
            final int initialLength = line.length();
            line = StaticUtils.trimLeading(line);
            final boolean hasLeadingWhitespace = (line.length() < initialLength);
            if (hasLeadingWhitespace && (!lineIsContinued)) {
                throw new ArgumentException(ERR_PARSER_PROP_FILE_UNEXPECTED_LEADING_SPACE.get(propertiesFilePath, lineNumber));
            }
            // we didn't expect the previous line to be continued.
            if ((line.isEmpty()) || line.startsWith("#")) {
                if (lineIsContinued) {
                    throw new ArgumentException(ERR_PARSER_PROP_FILE_MISSING_CONTINUATION.get((lineNumber - 1), propertiesFilePath));
                }
                continue;
            }
            // See if the line ends with a backslash and if so then trim it off.
            final boolean hasTrailingBackslash = line.endsWith("\\");
            if (line.endsWith("\\")) {
                line = line.substring(0, (line.length() - 1));
            }
            // to it.  Otherwise, add it as a new line.
            if (lineIsContinued) {
                propertyLines.get(propertyLines.size() - 1).getSecond().append(line);
            } else {
                propertyLines.add(new ObjectPair<>(lineNumber, new StringBuilder(line)));
            }
            lineIsContinued = hasTrailingBackslash;
        }
        // Parse all of the lines into a map of identifiers and their
        // corresponding values.
        propertiesFileUsed = propertiesFile;
        if (propertyLines.isEmpty()) {
            return;
        }
        final HashMap<String, ArrayList<String>> propertyMap = new HashMap<>(StaticUtils.computeMapCapacity(propertyLines.size()));
        for (final ObjectPair<Integer, StringBuilder> p : propertyLines) {
            lineNumber = p.getFirst();
            final String line = handleUnicodeEscapes(propertiesFilePath, lineNumber, p.getSecond());
            final int equalPos = line.indexOf('=');
            if (equalPos <= 0) {
                throw new ArgumentException(ERR_PARSER_MALFORMED_PROP_LINE.get(propertiesFilePath, lineNumber, line));
            }
            final String propertyName = line.substring(0, equalPos).trim();
            final String propertyValue = line.substring(equalPos + 1).trim();
            if (propertyValue.isEmpty()) {
                // The property doesn't have a value, so we can ignore it.
                continue;
            }
            // An argument can have multiple identifiers, and we will allow any of
            // them to be used to reference it.  To deal with this, we'll map the
            // argument identifier to its corresponding argument and then use the
            // preferred identifier for that argument in the map.  The same applies
            // to subcommand names.
            boolean prefixedWithToolName = false;
            boolean prefixedWithSubCommandName = false;
            Argument a = getNamedArgument(propertyName);
            if (a == null) {
                // Check to see if that was the case.
                if (propertyName.startsWith(commandName + '.')) {
                    prefixedWithToolName = true;
                    String basePropertyName = propertyName.substring(commandName.length() + 1);
                    a = getNamedArgument(basePropertyName);
                    if (a == null) {
                        final int periodPos = basePropertyName.indexOf('.');
                        if (periodPos > 0) {
                            final String subCommandName = basePropertyName.substring(0, periodPos);
                            if ((selectedSubCommand != null) && selectedSubCommand.hasName(subCommandName)) {
                                prefixedWithSubCommandName = true;
                                basePropertyName = basePropertyName.substring(periodPos + 1);
                                a = selectedSubCommand.getArgumentParser().getNamedArgument(basePropertyName);
                            }
                        } else if (selectedSubCommand != null) {
                            a = selectedSubCommand.getArgumentParser().getNamedArgument(basePropertyName);
                        }
                    }
                } else if (selectedSubCommand != null) {
                    a = selectedSubCommand.getArgumentParser().getNamedArgument(propertyName);
                }
            }
            if (a == null) {
                // either case, we'll ignore it.
                continue;
            }
            final String canonicalPropertyName;
            if (prefixedWithToolName) {
                if (prefixedWithSubCommandName) {
                    canonicalPropertyName = commandName + '.' + selectedSubCommand.getPrimaryName() + '.' + a.getIdentifierString();
                } else {
                    canonicalPropertyName = commandName + '.' + a.getIdentifierString();
                }
            } else {
                canonicalPropertyName = a.getIdentifierString();
            }
            ArrayList<String> valueList = propertyMap.get(canonicalPropertyName);
            if (valueList == null) {
                valueList = new ArrayList<>(5);
                propertyMap.put(canonicalPropertyName, valueList);
            }
            valueList.add(propertyValue);
        }
        // Iterate through all of the named arguments for the argument parser and
        // see if we should use the properties to assign values to any of the
        // arguments that weren't provided on the command line.
        setArgsFromPropertiesFile(propertyMap, false, skipFinalValidation);
        // arguments.
        if (selectedSubCommand != null) {
            setArgsFromPropertiesFile(propertyMap, true, skipFinalValidation);
        }
    } finally {
        try {
            reader.close();
        } catch (final Exception e) {
            Debug.debugException(e);
        }
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) CommandLineTool(com.unboundid.util.CommandLineTool) PrintStream(java.io.PrintStream) InputStreamReader(java.io.InputStreamReader) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) FileInputStream(java.io.FileInputStream) IOException(java.io.IOException) BufferedReader(java.io.BufferedReader) ObjectPair(com.unboundid.util.ObjectPair)

Example 5 with CommandLineTool

use of com.unboundid.util.CommandLineTool in project ldapsdk by pingidentity.

the class LauncherTestCase method testGetToolInstance.

/**
 * Tests to ensure that it's possible to get an instance of all of the
 * defined tools.
 *
 * @throws  Exception  If an unexpected problem occurs.
 */
@Test()
public void testGetToolInstance() throws Exception {
    for (final Class<?> c : Launcher.getToolClasses()) {
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        final ByteArrayOutputStream err = new ByteArrayOutputStream();
        final CommandLineTool tool = Launcher.getToolInstance(c, out, err);
        assertNotNull(tool);
    }
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) CommandLineTool(com.unboundid.util.CommandLineTool) Test(org.testng.annotations.Test)

Aggregations

CommandLineTool (com.unboundid.util.CommandLineTool)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 File (java.io.File)3 PrintWriter (java.io.PrintWriter)3 ArgumentParser (com.unboundid.util.args.ArgumentParser)2 SubCommand (com.unboundid.util.args.SubCommand)2 BuildException (org.apache.tools.ant.BuildException)2 ObjectPair (com.unboundid.util.ObjectPair)1 BufferedReader (java.io.BufferedReader)1 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 InputStreamReader (java.io.InputStreamReader)1 PrintStream (java.io.PrintStream)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 TreeMap (java.util.TreeMap)1 Test (org.testng.annotations.Test)1