All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.unboundid.ldap.sdk.unboundidds.tools.OIDLookup Maven / Gradle / Ivy

/*
 * Copyright 2020 Ping Identity Corporation
 * All Rights Reserved.
 */
/*
 * Copyright 2020 Ping Identity Corporation
 *
 * Licensed 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.
 */
/*
 * Copyright (C) 2020 Ping Identity Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see .
 */
package com.unboundid.ldap.sdk.unboundidds.tools;



import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.TreeMap;

import com.unboundid.ldap.sdk.InternalSDKHelper;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.Version;
import com.unboundid.ldap.sdk.schema.Schema;
import com.unboundid.util.ColumnFormatter;
import com.unboundid.util.CommandLineTool;
import com.unboundid.util.Debug;
import com.unboundid.util.FormattableColumn;
import com.unboundid.util.HorizontalAlignment;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.OIDRegistry;
import com.unboundid.util.OIDRegistryItem;
import com.unboundid.util.OutputFormat;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import com.unboundid.util.args.ArgumentException;
import com.unboundid.util.args.ArgumentParser;
import com.unboundid.util.args.BooleanArgument;
import com.unboundid.util.args.FileArgument;
import com.unboundid.util.args.StringArgument;

import static com.unboundid.ldap.sdk.unboundidds.tools.ToolMessages.*;



/**
 * This class provides a command-line tool that can be used to search the OID
 * registry to retrieve information an item with a specified OID or name.
 * 
*
* NOTE: This class, and other classes within the * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only * supported for use against Ping Identity, UnboundID, and * Nokia/Alcatel-Lucent 8661 server products. These classes provide support * for proprietary functionality or for external specifications that are not * considered stable or mature enough to be guaranteed to work in an * interoperable way with other types of LDAP servers. *
*/ @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) public final class OIDLookup extends CommandLineTool { /** * The column at which long lines of output should be wrapped. */ private static final int WRAP_COLUMN = StaticUtils.TERMINAL_WIDTH_COLUMNS - 1; /** * The output format value that indicates that output should be generated as * comma-separated values. */ @NotNull private static final String OUTPUT_FORMAT_CSV = "csv"; /** * The output format value that indicates that output should be generated as * comma-separated values. */ @NotNull private static final String OUTPUT_FORMAT_JSON = "json"; /** * The output format value that indicates that output should be generated as * multi-line text. */ @NotNull private static final String OUTPUT_FORMAT_MULTI_LINE = "multi-line"; /** * The output format value that indicates that output should be generated as * tab-delimited text. */ @NotNull private static final String OUTPUT_FORMAT_TAB_DELIMITED = "tab-delimited"; // The argument parser used by this tool. @Nullable private ArgumentParser parser; // The argument used to request terse output. @Nullable private BooleanArgument terseArg; // The argument used to specify the path to an LDAP schema to use to augment // the default OID registry. @Nullable private FileArgument schemaPathArg; // The argument used to specify the output format. @Nullable private StringArgument outputFormatArg; /** * Invokes this tool with the provided set of command-line arguments. * * @param args The set of command-line arguments provided to this program. */ public static void main(@NotNull final String... args) { final ResultCode resultCode = main(System.out, System.err, args); if (resultCode != ResultCode.SUCCESS) { System.exit(resultCode.intValue()); } } /** * Invokes this tool with the provided set of command-line arguments. * * @param out The output stream to use for standard output. It may be * {@code null} if standard output should be suppressed. * @param err The output stream to use for standard error. It may be * {@code null} if standard error should be suppressed. * @param args The set of command-line arguments provided to this program. * * @return A result code that indicates whether processing was successful. */ @NotNull() public static ResultCode main(@Nullable final OutputStream out, @Nullable final OutputStream err, @NotNull final String... args) { final OIDLookup tool = new OIDLookup(out, err); return tool.runTool(args); } /** * Creates an instance of this tool with the provided standard output and * error streams. * * @param out The output stream to use for standard output. It may be * {@code null} if standard output should be suppressed. * @param err The output stream to use for standard error. It may be * {@code null} if standard error should be suppressed. */ public OIDLookup(@Nullable final OutputStream out, @Nullable final OutputStream err) { super(out, err); parser = null; terseArg = null; schemaPathArg = null; outputFormatArg = null; } /** * {@inheritDoc} */ @Override() @NotNull() public String getToolName() { return "oid-lookup"; } /** * {@inheritDoc} */ @Override() @NotNull() public String getToolDescription() { return INFO_OID_LOOKUP_TOOL_DESC_1.get(); } /** * {@inheritDoc} */ @Override() @NotNull() public List getAdditionalDescriptionParagraphs() { return Collections.singletonList(INFO_OID_LOOKUP_TOOL_DESC_2.get()); } /** * {@inheritDoc} */ @Override() @NotNull() public String getToolVersion() { return Version.NUMERIC_VERSION_STRING; } /** * {@inheritDoc} */ @Override() public int getMinTrailingArguments() { return 0; } /** * {@inheritDoc} */ @Override() public int getMaxTrailingArguments() { return 1; } /** * {@inheritDoc} */ @Override() @NotNull() public String getTrailingArgumentsPlaceholder() { return INFO_OID_LOOKUP_TRAILING_ARG_PLACEHOLDER.get(); } /** * {@inheritDoc} */ @Override() public boolean supportsInteractiveMode() { return true; } /** * {@inheritDoc} */ @Override() public boolean defaultsToInteractiveMode() { return false; } /** * {@inheritDoc} */ @Override() public boolean supportsPropertiesFile() { return true; } /** * {@inheritDoc} */ @Override() protected boolean supportsOutputFile() { return true; } /** * {@inheritDoc} */ @Override() protected boolean logToolInvocationByDefault() { return false; } /** * {@inheritDoc} */ @Override() public void addToolArguments(@NotNull final ArgumentParser parser) throws ArgumentException { this.parser = parser; schemaPathArg = new FileArgument(null, "schema-path", false, 0, null, INFO_OID_LOOKUP_ARG_DESC_SCHEMA_PATH.get(), true, true, false, false); schemaPathArg.addLongIdentifier("schemaPath", true); schemaPathArg.addLongIdentifier("schema-file", true); schemaPathArg.addLongIdentifier("schemaFile", true); schemaPathArg.addLongIdentifier("schema-directory", true); schemaPathArg.addLongIdentifier("schemaDirectory", true); schemaPathArg.addLongIdentifier("schema-dir", true); schemaPathArg.addLongIdentifier("schemaDir", true); schemaPathArg.addLongIdentifier("schema", true); parser.addArgument(schemaPathArg); outputFormatArg = new StringArgument(null, "output-format", false, 1, INFO_OID_LOOKUP_ARG_PLACEHOLDER_OUTPUT_FORMAT.get(), INFO_OID_LOOKUP_ARG_DESC_OUTPUT_FORMAT.get(), StaticUtils.setOf( OUTPUT_FORMAT_CSV, OUTPUT_FORMAT_JSON, OUTPUT_FORMAT_MULTI_LINE, OUTPUT_FORMAT_TAB_DELIMITED), OUTPUT_FORMAT_MULTI_LINE); outputFormatArg.addLongIdentifier("outputFormat", true); outputFormatArg.addLongIdentifier("format", true); parser.addArgument(outputFormatArg); terseArg = new BooleanArgument(null, "terse", 1, INFO_OID_LOOKUP_ARG_DESC_TERSE.get()); parser.addArgument(terseArg); } /** * {@inheritDoc} */ @Override() @NotNull() public ResultCode doToolProcessing() { // Get a reference to the default OID registry. OIDRegistry oidRegistry = OIDRegistry.getDefault(); // If any schema paths were provided, then read the schema(s) and use that // to augment the default OID registry. If not, and if this tool is running // from a Ping Identity Directory Server installation, then see if we can // use its default schema. List schemaPaths = Collections.emptyList(); if ((schemaPathArg != null) && (schemaPathArg.isPresent())) { schemaPaths = schemaPathArg.getValues(); } else { try { final File instanceRoot = InternalSDKHelper.getPingIdentityServerRoot(); if (instanceRoot != null) { final File instanceRootSchemaDir = StaticUtils.constructPath(instanceRoot, "config", "schema"); if (new File(instanceRootSchemaDir, "00-core.ldif").exists()) { schemaPaths = Collections.singletonList(instanceRootSchemaDir); } } } catch (final Throwable t) { // This is fine. We're just not running with access to a Ping Identity // Directory Server. } } if (! schemaPaths.isEmpty()) { try { oidRegistry = augmentOIDRegistry(oidRegistry, schemaPaths); } catch (final LDAPException e) { Debug.debugException(e); wrapErr(0, WRAP_COLUMN, e.getMessage()); return e.getResultCode(); } } // See if there is a search string. If so, then identify the appropriate // set of matching OID registry items. Otherwise, just grab everything in // the OID registry. final Collection matchingItems; if ((parser != null) && (! parser.getTrailingArguments().isEmpty())) { matchingItems = new ArrayList<>(); final String searchString = parser.getTrailingArguments().get(0).toLowerCase(); for (final OIDRegistryItem item : oidRegistry.getItems().values()) { if (itemMatchesSearchString(item, searchString)) { matchingItems.add(item); } } } else { matchingItems = oidRegistry.getItems().values(); } // If there weren't any matches, then display a message if appropriate. boolean json = false; ColumnFormatter columnFormatter = null; if ((outputFormatArg != null) && outputFormatArg.isPresent()) { final String outputFormat = outputFormatArg.getValue(); if (outputFormat != null) { if (outputFormat.equalsIgnoreCase(OUTPUT_FORMAT_CSV)) { columnFormatter = new ColumnFormatter(false, null, OutputFormat.CSV, null, new FormattableColumn(1, HorizontalAlignment.LEFT, "OID"), new FormattableColumn(1, HorizontalAlignment.LEFT, "Name"), new FormattableColumn(1, HorizontalAlignment.LEFT, "Type"), new FormattableColumn(1, HorizontalAlignment.LEFT, "Origin"), new FormattableColumn(1, HorizontalAlignment.LEFT, "URL")); } else if (outputFormat.equalsIgnoreCase(OUTPUT_FORMAT_JSON)) { json = true; } else if (outputFormat.equalsIgnoreCase(OUTPUT_FORMAT_TAB_DELIMITED)) { columnFormatter = new ColumnFormatter(false, null, OutputFormat.TAB_DELIMITED_TEXT, null, new FormattableColumn(1, HorizontalAlignment.LEFT, "OID"), new FormattableColumn(1, HorizontalAlignment.LEFT, "Name"), new FormattableColumn(1, HorizontalAlignment.LEFT, "Type"), new FormattableColumn(1, HorizontalAlignment.LEFT, "Origin"), new FormattableColumn(1, HorizontalAlignment.LEFT, "URL")); } } } final int numMatches = matchingItems.size(); switch (numMatches) { case 0: wrapComment(WARN_OID_LOOKUP_NO_MATCHES.get()); return ResultCode.NO_RESULTS_RETURNED; case 1: wrapComment(INFO_OID_LOOKUP_ONE_MATCH.get()); break; default: wrapComment(INFO_OID_LOOKUP_MULTIPLE_MATCHES.get(numMatches)); break; } if (columnFormatter != null) { for (final String line : columnFormatter.getHeaderLines(false)) { out(line); } } for (final OIDRegistryItem item : matchingItems) { if (json) { out(item.asJSONObject().toSingleLineString()); } else if (columnFormatter != null) { out(columnFormatter.formatRow(item.getOID(), item.getName(), item.getType(), item.getOrigin(), item.getURL())); } else { out(); out(INFO_OID_LOOKUP_OUTPUT_LINE_OID.get(item.getOID())); out(INFO_OID_LOOKUP_OUTPUT_LINE_NAME.get(item.getName())); out(INFO_OID_LOOKUP_OUTPUT_LINE_TYPE.get(item.getType())); final String origin = item.getOrigin(); if (origin != null) { out(INFO_OID_LOOKUP_OUTPUT_LINE_ORIGIN.get(origin)); } final String url = item.getURL(); if (url != null) { out(INFO_OID_LOOKUP_OUTPUT_LINE_URL.get(url)); } } } return ResultCode.SUCCESS; } /** * Retrieves a copy of the provided OID registry that has been augmented with * information read from a specified set of schema files. * * @param registry The OID registry to be augmented. * @param schemaPaths The paths containing the schema information to use to * augment the default registry. * * @return The augmented OID registry. * * @throws LDAPException If a problem occurs while trying to read and parse * the schema. */ @NotNull() private static OIDRegistry augmentOIDRegistry( @NotNull final OIDRegistry registry, @NotNull final List schemaPaths) throws LDAPException { OIDRegistry oidRegistry = registry; for (final File schemaPath : schemaPaths) { if (schemaPath.isFile()) { oidRegistry = augmentOIDRegistry(oidRegistry, schemaPath); } else if (schemaPath.isDirectory()) { final File[] files = schemaPath.listFiles(); if (files != null) { final TreeMap fileMap = new TreeMap<>(); for (final File f : files) { fileMap.put(f.getName(), f); } for (final File f : fileMap.values()) { oidRegistry = augmentOIDRegistry(oidRegistry, f); } } } } return oidRegistry; } /** * Retrieves a copy of the provided OID registry that has been augmented with * information read from the specified schema file. * * @param registry The OID registry to be augmented. * @param schemaFile The file from which to read the schema elements. * * @return The augmented OID registry. * * @throws LDAPException If a problem occurs while trying to read and parse * the schema. */ @NotNull() private static OIDRegistry augmentOIDRegistry( @NotNull final OIDRegistry registry, @NotNull final File schemaFile) throws LDAPException { final Schema schema; try { schema = Schema.getSchema(schemaFile); } catch (final Exception e) { Debug.debugException(e); throw new LDAPException(ResultCode.LOCAL_ERROR, ERR_OID_LOOKUP_CANNOT_GET_SCHEMA_FROM_FILE.get( schemaFile.getAbsolutePath(), StaticUtils.getExceptionMessage(e)), e); } if (schema == null) { return registry; } else { return registry.withSchema(schema); } } /** * Determines whether the provided OID registry item matches the given search * string. * * @param item The item for which to make the determination. * @param searchString The search string to match against the item. * * @return {@code true} if the provided item matches the given search string, * or {@code false} if not. */ private static boolean itemMatchesSearchString( @NotNull final OIDRegistryItem item, @NotNull final String searchString) { final String oid = StaticUtils.toLowerCase(item.getOID()); if ((oid != null) && oid.contains(searchString)) { return true; } final String name = StaticUtils.toLowerCase(item.getName()); if ((name != null) && name.contains(searchString)) { return true; } final String type = StaticUtils.toLowerCase(item.getType()); if ((type != null) && type.contains(searchString)) { return true; } final String origin = StaticUtils.toLowerCase(item.getOrigin()); if ((origin != null) && origin.contains(searchString)) { return true; } final String url = StaticUtils.toLowerCase(item.getURL()); return ((url != null) && url.contains(searchString)); } /** * Writes a wrapped version of the provided message with each line preceded * by "# " to indicate that it is a comment. No output will be written if the * tool is running in terse mode. * * @param message The message to write as a comment. */ private void wrapComment(@NotNull final String message) { final boolean terse = ((terseArg != null) && terseArg.isPresent()); if (! terse) { for (final String line : StaticUtils.wrapLine(message, (WRAP_COLUMN - 2))) { out("# ", line); } } } /** * {@inheritDoc} */ @Override() @NotNull() public LinkedHashMap getExampleUsages() { final LinkedHashMap examples = new LinkedHashMap<>(); examples.put( StaticUtils.NO_STRINGS, INFO_OID_LOOKUP_EXAMPLE_1.get()); examples.put( new String[] { "--output-format", "json", "2.5.4.3" }, INFO_OID_LOOKUP_EXAMPLE_2.get()); return examples; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy