| | |
| | | import com.forgerock.opendj.cli.SubCommand; |
| | | import com.forgerock.opendj.cli.SubCommandArgumentParser; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class provides a command-line tool which enables |
| | | * administrators to configure the Directory Server. |
| | | * This class provides a command-line tool which enables administrators to configure the Directory Server. |
| | | */ |
| | | public final class DSConfig extends ConsoleApplication { |
| | | |
| | | /** The logger */ |
| | | /** The logger. */ |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | /** The name of this tool. */ |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public MenuResult<Integer> invoke(ConsoleApplication app) |
| | | throws ClientException { |
| | | public MenuResult<Integer> invoke(ConsoleApplication app) throws ClientException { |
| | | try { |
| | | MenuResult<Integer> result = handler.run(app, factory); |
| | | |
| | | if (result.isQuit()) { |
| | | return result; |
| | | } else { |
| | | if (result.isSuccess() && isInteractive() && |
| | | handler.isCommandBuilderUseful()) |
| | | { |
| | | if (result.isSuccess() && isInteractive() && handler.isCommandBuilderUseful()) { |
| | | printCommandBuilder(getCommandBuilder(handler)); |
| | | } |
| | | // Success or cancel. |
| | |
| | | * @param sh |
| | | * The option set-prop sub-command. |
| | | */ |
| | | public SubMenuCallback(ConsoleApplication app, RelationDefinition<?, ?> rd, |
| | | CreateSubCommandHandler<?, ?> ch, DeleteSubCommandHandler dh, |
| | | ListSubCommandHandler lh, SetPropSubCommandHandler sh) { |
| | | public SubMenuCallback(ConsoleApplication app, RelationDefinition<?, ?> rd, CreateSubCommandHandler<?, ?> ch, |
| | | DeleteSubCommandHandler dh, ListSubCommandHandler lh, SetPropSubCommandHandler sh) { |
| | | LocalizableMessage userFriendlyName = rd.getUserFriendlyName(); |
| | | |
| | | LocalizableMessage userFriendlyPluralName = null; |
| | | if (rd instanceof InstantiableRelationDefinition<?,?>) { |
| | | InstantiableRelationDefinition<?, ?> ir = |
| | | (InstantiableRelationDefinition<?, ?>) rd; |
| | | InstantiableRelationDefinition<?, ?> ir = (InstantiableRelationDefinition<?, ?>) rd; |
| | | userFriendlyPluralName = ir.getUserFriendlyPluralName(); |
| | | } else if (rd instanceof SetRelationDefinition<?,?>) { |
| | | SetRelationDefinition<?, ?> sr = |
| | | (SetRelationDefinition<?, ?>) rd; |
| | | SetRelationDefinition<?, ?> sr = (SetRelationDefinition<?, ?>) rd; |
| | | userFriendlyPluralName = sr.getUserFriendlyPluralName(); |
| | | } |
| | | |
| | | final MenuBuilder<Integer> builder = new MenuBuilder<Integer>(app); |
| | | |
| | | builder.setTitle(INFO_DSCFG_HEADING_COMPONENT_MENU_TITLE |
| | | .get(userFriendlyName)); |
| | | builder.setTitle(INFO_DSCFG_HEADING_COMPONENT_MENU_TITLE.get(userFriendlyName)); |
| | | builder.setPrompt(INFO_DSCFG_HEADING_COMPONENT_MENU_PROMPT.get()); |
| | | |
| | | if (lh != null) { |
| | | final SubCommandHandlerMenuCallback callback = |
| | | new SubCommandHandlerMenuCallback(lh); |
| | | final SubCommandHandlerMenuCallback callback = new SubCommandHandlerMenuCallback(lh); |
| | | if (userFriendlyPluralName != null) { |
| | | builder.addNumberedOption( |
| | | INFO_DSCFG_OPTION_COMPONENT_MENU_LIST_PLURAL |
| | | .get(userFriendlyPluralName), callback); |
| | | builder.addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_LIST_PLURAL.get(userFriendlyPluralName), |
| | | callback); |
| | | } else { |
| | | builder |
| | | .addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_LIST_SINGULAR |
| | | .get(userFriendlyName), callback); |
| | | builder.addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_LIST_SINGULAR.get(userFriendlyName), |
| | | callback); |
| | | } |
| | | } |
| | | |
| | | if (ch != null) { |
| | | final SubCommandHandlerMenuCallback callback = |
| | | new SubCommandHandlerMenuCallback(ch); |
| | | builder.addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_CREATE |
| | | .get(userFriendlyName), callback); |
| | | final SubCommandHandlerMenuCallback callback = new SubCommandHandlerMenuCallback(ch); |
| | | builder.addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_CREATE.get(userFriendlyName), callback); |
| | | } |
| | | |
| | | if (sh != null) { |
| | | final SubCommandHandlerMenuCallback callback = |
| | | new SubCommandHandlerMenuCallback(sh); |
| | | final SubCommandHandlerMenuCallback callback = new SubCommandHandlerMenuCallback(sh); |
| | | if (userFriendlyPluralName != null) { |
| | | builder.addNumberedOption( |
| | | INFO_DSCFG_OPTION_COMPONENT_MENU_MODIFY_PLURAL |
| | | .get(userFriendlyName), callback); |
| | | builder.addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_MODIFY_PLURAL.get(userFriendlyName), |
| | | callback); |
| | | } else { |
| | | builder.addNumberedOption( |
| | | INFO_DSCFG_OPTION_COMPONENT_MENU_MODIFY_SINGULAR |
| | | .get(userFriendlyName), callback); |
| | | builder.addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_MODIFY_SINGULAR.get(userFriendlyName), |
| | | callback); |
| | | } |
| | | } |
| | | |
| | | if (dh != null) { |
| | | final SubCommandHandlerMenuCallback callback = |
| | | new SubCommandHandlerMenuCallback(dh); |
| | | builder.addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_DELETE |
| | | .get(userFriendlyName), callback); |
| | | final SubCommandHandlerMenuCallback callback = new SubCommandHandlerMenuCallback(dh); |
| | | builder.addNumberedOption(INFO_DSCFG_OPTION_COMPONENT_MENU_DELETE.get(userFriendlyName), callback); |
| | | } |
| | | |
| | | builder.addBackOption(true); |
| | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final MenuResult<Integer> invoke(ConsoleApplication app) |
| | | throws ClientException { |
| | | public final MenuResult<Integer> invoke(ConsoleApplication app) throws ClientException { |
| | | try { |
| | | app.println(); |
| | | app.println(); |
| | |
| | | } |
| | | |
| | | /** |
| | | * The type name which will be used for the most generic managed |
| | | * object types when they are instantiable and intended for |
| | | * customization only. |
| | | * The type name which will be used for the most generic managed object types when they are instantiable and |
| | | * intended for customization only. |
| | | */ |
| | | public static final String CUSTOM_TYPE = "custom"; |
| | | |
| | | /** |
| | | * The type name which will be used for the most generic managed |
| | | * object types when they are instantiable and not intended for |
| | | * customization. |
| | | * The type name which will be used for the most generic managed object types when they are instantiable and not |
| | | * intended for customization. |
| | | */ |
| | | public static final String GENERIC_TYPE = "generic"; |
| | | |
| | |
| | | private int sessionEquivalentOperationNumber = 0; |
| | | |
| | | /** |
| | | * Provides the command-line arguments to the main application for |
| | | * processing. |
| | | * Provides the command-line arguments to the main application for processing. |
| | | * |
| | | * @param args |
| | | * The set of command-line arguments provided to this |
| | | * program. |
| | | * The set of command-line arguments provided to this program. |
| | | */ |
| | | public static void main(String[] args) { |
| | | int exitCode = main(args, System.out, System.err); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Provides the command-line arguments to the main application for |
| | | * processing and returns the exit code as an integer. |
| | | * Provides the command-line arguments to the main application for processing and returns the exit code as an |
| | | * integer. |
| | | * |
| | | * @param args |
| | | * The set of command-line arguments provided to this |
| | | * program. |
| | | * The set of command-line arguments provided to this program. |
| | | * @param outStream |
| | | * The output stream for standard output. |
| | | * @param errStream |
| | | * The output stream for standard error. |
| | | * @return Zero to indicate that the program completed successfully, |
| | | * or non-zero to indicate that an error occurred. |
| | | * @return Zero to indicate that the program completed successfully, or non-zero to indicate that an error occurred. |
| | | */ |
| | | public static int main(String[] args, OutputStream outStream, |
| | | OutputStream errStream) |
| | | { |
| | | public static int main(String[] args, OutputStream outStream, OutputStream errStream) { |
| | | final DSConfig app = new DSConfig(System.in, outStream, errStream); |
| | | app.sessionStartTime = System.currentTimeMillis(); |
| | | /* |
| | | * FIXME: obtain path info from system properties. |
| | | */ |
| | | if (!ConfigurationFramework.getInstance().isInitialized()) |
| | | { |
| | | try |
| | | { |
| | | if (!ConfigurationFramework.getInstance().isInitialized()) { |
| | | try { |
| | | ConfigurationFramework.getInstance().initialize(); |
| | | } |
| | | catch (ConfigException e) |
| | | { |
| | | } catch (ConfigException e) { |
| | | app.println(e.getMessageObject()); |
| | | return ReturnCode.ERROR_INITIALIZING_SERVER.get(); |
| | | } |
| | |
| | | private BooleanArgument advancedModeArgument; |
| | | |
| | | /** |
| | | * The factory which the application should use to retrieve its management |
| | | * context. |
| | | * The factory which the application should use to retrieve its management context. |
| | | */ |
| | | private LDAPManagementContextFactory factory = null; |
| | | |
| | | /** |
| | | * Flag indicating whether or not the global arguments have already been |
| | | * initialized. |
| | | * Flag indicating whether or not the global arguments have already been initialized. |
| | | */ |
| | | private boolean globalArgumentsInitialized = false; |
| | | |
| | |
| | | private SubCommandHandlerFactory handlerFactory = null; |
| | | |
| | | /** Mapping of sub-commands to their implementations. */ |
| | | private final Map<SubCommand, SubCommandHandler> handlers = |
| | | new HashMap<SubCommand, SubCommandHandler>(); |
| | | private final Map<SubCommand, SubCommandHandler> handlers = new HashMap<SubCommand, SubCommandHandler>(); |
| | | |
| | | /** Indicates whether or not a sub-command was provided. */ |
| | | private boolean hasSubCommand = true; |
| | |
| | | private BooleanArgument noPromptArgument; |
| | | |
| | | /** |
| | | * The argument that the user must set to display the equivalent |
| | | * non-interactive mode argument. |
| | | * The argument that the user must set to display the equivalent non-interactive mode argument. |
| | | */ |
| | | private BooleanArgument displayEquivalentArgument; |
| | | |
| | | /** |
| | | * The argument that allows the user to dump the equivalent non-interactive |
| | | * command to a file. |
| | | * The argument that allows the user to dump the equivalent non-interactive command to a file. |
| | | */ |
| | | private StringArgument equivalentCommandFileArgument; |
| | | |
| | |
| | | private StringArgument propertiesFileArgument; |
| | | |
| | | /** |
| | | * The argument which should be used to indicate that we will not look for |
| | | * properties file. |
| | | * The argument which should be used to indicate that we will not look for properties file. |
| | | */ |
| | | private BooleanArgument noPropertiesFileArgument; |
| | | |
| | |
| | | private DSConfig(InputStream in, OutputStream out, OutputStream err) { |
| | | super(new PrintStream(out), new PrintStream(err)); |
| | | |
| | | this.parser = new SubCommandArgumentParser(getClass().getName(), |
| | | INFO_DSCFG_TOOL_DESCRIPTION.get(), false); |
| | | this.parser = new SubCommandArgumentParser(getClass().getName(), INFO_DSCFG_TOOL_DESCRIPTION.get(), false); |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isAdvancedMode() { |
| | | return advancedModeArgument.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isInteractive() { |
| | | return !noPromptArgument.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isMenuDrivenMode() { |
| | | return !hasSubCommand; |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isQuiet() { |
| | | return quietArgument.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isScriptFriendly() { |
| | | return scriptFriendlyArgument.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public boolean isVerbose() { |
| | | return verboseArgument.isPresent(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** Displays the provided message followed by a help usage reference. */ |
| | | private void displayMessageAndUsageReference(LocalizableMessage message) { |
| | | println(message); |
| | |
| | | println(parser.getHelpUsageReference()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Registers the global arguments with the argument parser. |
| | | * |
| | | * @throws ArgumentException |
| | | * If a global argument could not be registered. |
| | | */ |
| | | private void initializeGlobalArguments(String[] args) |
| | | throws ArgumentException { |
| | | private void initializeGlobalArguments(String[] args) throws ArgumentException { |
| | | if (!globalArgumentsInitialized) { |
| | | |
| | | verboseArgument = CommonArguments.getVerbose(); |
| | |
| | | advancedModeArgument = CommonArguments.getAdvancedMode(); |
| | | showUsageArgument = CommonArguments.getShowUsage(); |
| | | |
| | | batchFileArgument = new StringArgument(OPTION_LONG_BATCH_FILE_PATH, |
| | | OPTION_SHORT_BATCH_FILE_PATH, OPTION_LONG_BATCH_FILE_PATH, |
| | | false, false, true, INFO_BATCH_FILE_PATH_PLACEHOLDER.get(), |
| | | null, null, |
| | | INFO_DESCRIPTION_BATCH_FILE_PATH.get()); |
| | | batchFileArgument = new StringArgument(OPTION_LONG_BATCH_FILE_PATH, OPTION_SHORT_BATCH_FILE_PATH, |
| | | OPTION_LONG_BATCH_FILE_PATH, false, false, true, INFO_BATCH_FILE_PATH_PLACEHOLDER.get(), null, |
| | | null, INFO_DESCRIPTION_BATCH_FILE_PATH.get()); |
| | | |
| | | displayEquivalentArgument = new BooleanArgument( |
| | | OPTION_LONG_DISPLAY_EQUIVALENT, |
| | | null, OPTION_LONG_DISPLAY_EQUIVALENT, |
| | | INFO_DSCFG_DESCRIPTION_DISPLAY_EQUIVALENT.get()); |
| | | displayEquivalentArgument = new BooleanArgument(OPTION_LONG_DISPLAY_EQUIVALENT, null, |
| | | OPTION_LONG_DISPLAY_EQUIVALENT, INFO_DSCFG_DESCRIPTION_DISPLAY_EQUIVALENT.get()); |
| | | |
| | | equivalentCommandFileArgument = new StringArgument( |
| | | OPTION_LONG_EQUIVALENT_COMMAND_FILE_PATH, null, |
| | | OPTION_LONG_EQUIVALENT_COMMAND_FILE_PATH, false, false, true, |
| | | INFO_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DSCFG_DESCRIPTION_EQUIVALENT_COMMAND_FILE_PATH.get()); |
| | | equivalentCommandFileArgument = new StringArgument(OPTION_LONG_EQUIVALENT_COMMAND_FILE_PATH, null, |
| | | OPTION_LONG_EQUIVALENT_COMMAND_FILE_PATH, false, false, true, INFO_PATH_PLACEHOLDER.get(), null, |
| | | null, INFO_DSCFG_DESCRIPTION_EQUIVALENT_COMMAND_FILE_PATH.get()); |
| | | |
| | | propertiesFileArgument = new StringArgument("propertiesFilePath", |
| | | null, OPTION_LONG_PROP_FILE_PATH, |
| | | false, false, true, INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | propertiesFileArgument = new StringArgument("propertiesFilePath", null, OPTION_LONG_PROP_FILE_PATH, false, |
| | | false, true, INFO_PROP_FILE_PATH_PLACEHOLDER.get(), null, null, |
| | | INFO_DESCRIPTION_PROP_FILE_PATH.get()); |
| | | |
| | | noPropertiesFileArgument = new BooleanArgument( |
| | | "noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | noPropertiesFileArgument = new BooleanArgument("noPropertiesFileArgument", null, OPTION_LONG_NO_PROP_FILE, |
| | | INFO_DESCRIPTION_NO_PROP_FILE.get()); |
| | | |
| | | // Register the global arguments. |
| | | |
| | | ArgumentGroup toolOptionsGroup = new ArgumentGroup( |
| | | INFO_DSCFG_DESCRIPTION_OPTIONS_ARGS.get(), 2); |
| | | ArgumentGroup toolOptionsGroup = new ArgumentGroup(INFO_DSCFG_DESCRIPTION_OPTIONS_ARGS.get(), 2); |
| | | parser.addGlobalArgument(advancedModeArgument, toolOptionsGroup); |
| | | |
| | | parser.addGlobalArgument(showUsageArgument); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Registers the sub-commands with the argument parser. This method |
| | | * uses the administration framework introspection APIs to determine |
| | | * the overall structure of the command-line. |
| | | * Registers the sub-commands with the argument parser. This method uses the administration framework introspection |
| | | * APIs to determine the overall structure of the command-line. |
| | | * |
| | | * @throws ArgumentException |
| | | * If a sub-command could not be created. |
| | |
| | | } |
| | | }; |
| | | |
| | | Map<Tag, SortedSet<SubCommand>> groups = |
| | | new TreeMap<Tag, SortedSet<SubCommand>>(); |
| | | Map<Tag, SortedSet<SubCommand>> groups = new TreeMap<Tag, SortedSet<SubCommand>>(); |
| | | SortedSet<SubCommand> allSubCommands = new TreeSet<SubCommand>(c); |
| | | for (SubCommandHandler handler : handlerFactory |
| | | .getAllSubCommandHandlers()) { |
| | | for (SubCommandHandler handler : handlerFactory.getAllSubCommandHandlers()) { |
| | | SubCommand sc = handler.getSubCommand(); |
| | | |
| | | handlers.put(sc, handler); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided command-line arguments and makes the |
| | | * appropriate changes to the Directory Server configuration. |
| | | * Parses the provided command-line arguments and makes the appropriate changes to the Directory Server |
| | | * configuration. |
| | | * |
| | | * @param args |
| | | * The command-line arguments provided to this program. |
| | | * @return The exit code from the configuration processing. A |
| | | * nonzero value indicates that there was some kind of |
| | | * @return The exit code from the configuration processing. A nonzero value indicates that there was some kind of |
| | | * problem during the configuration processing. |
| | | */ |
| | | private int run(String[] args) { |
| | |
| | | } |
| | | |
| | | ConnectionFactoryProvider cfp = null; |
| | | try |
| | | { |
| | | cfp = |
| | | new ConnectionFactoryProvider(parser, this, |
| | | CliConstants.DEFAULT_ROOT_USER_DN, |
| | | try { |
| | | cfp = new ConnectionFactoryProvider(parser, this, CliConstants.DEFAULT_ROOT_USER_DN, |
| | | CliConstants.DEFAULT_ADMINISTRATION_CONNECTOR_PORT, true, null); |
| | | cfp.setIsAnAdminConnection(); |
| | | |
| | | // Parse the command-line arguments provided to this program. |
| | | parser.parseArguments(args); |
| | | checkForConflictingArguments(); |
| | | } |
| | | catch (ArgumentException ae) |
| | | { |
| | | displayMessageAndUsageReference(ERR_ERROR_PARSING_ARGS.get(ae |
| | | .getMessage())); |
| | | } catch (ArgumentException ae) { |
| | | displayMessageAndUsageReference(ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); |
| | | return ReturnCode.CONFLICTING_ARGS.get(); |
| | | } |
| | | |
| | |
| | | |
| | | // Check that we can write on the provided path where we write the |
| | | // equivalent non-interactive commands. |
| | | if (equivalentCommandFileArgument.isPresent()) |
| | | { |
| | | if (equivalentCommandFileArgument.isPresent()) { |
| | | final String file = equivalentCommandFileArgument.getValue(); |
| | | if (!canWrite(file)) |
| | | { |
| | | if (!canWrite(file)) { |
| | | println(ERR_DSCFG_CANNOT_WRITE_EQUIVALENT_COMMAND_LINE_FILE.get(file)); |
| | | return ReturnCode.ERROR_UNEXPECTED.get(); |
| | | } |
| | | else |
| | | { |
| | | if (new File(file).isDirectory()) |
| | | { |
| | | } else { |
| | | if (new File(file).isDirectory()) { |
| | | println(ERR_DSCFG_EQUIVALENT_COMMAND_LINE_FILE_DIRECTORY.get(file)); |
| | | return ReturnCode.ERROR_UNEXPECTED.get(); |
| | | } |
| | |
| | | } |
| | | // Creates the management context factory which is based on the connection |
| | | // provider factory and an authenticated connection factory. |
| | | try |
| | | { |
| | | try { |
| | | factory = new LDAPManagementContextFactory(cfp); |
| | | } |
| | | catch (ArgumentException e) |
| | | { |
| | | displayMessageAndUsageReference(ERR_ERROR_PARSING_ARGS |
| | | .get(e.getMessage())); |
| | | } catch (ArgumentException e) { |
| | | displayMessageAndUsageReference(ERR_ERROR_PARSING_ARGS.get(e.getMessage())); |
| | | return ReturnCode.CONFLICTING_ARGS.get(); |
| | | } |
| | | |
| | | // Checks the version - if upgrade required, the tool is unusable |
| | | /*try |
| | | { |
| | | BuildVersion.checkVersionMismatch(); |
| | | } |
| | | catch (ConfigException e) |
| | | { |
| | | println(e.getMessageObject()); |
| | | return ReturnCode.ERROR_USER_DATA.get(); |
| | | }*/ |
| | | /* |
| | | * try { BuildVersion.checkVersionMismatch(); } catch (ConfigException e) { println(e.getMessageObject()); |
| | | * return ReturnCode.ERROR_USER_DATA.get(); } |
| | | */ |
| | | |
| | | // Handle batch file if any |
| | | if (batchFileArgument.isPresent()) { |
| | |
| | | // Top-level interactive mode. |
| | | retCode = runInteractiveMode(); |
| | | } else { |
| | | LocalizableMessage message = ERR_ERROR_PARSING_ARGS |
| | | .get(ERR_DSCFG_ERROR_MISSING_SUBCOMMAND.get()); |
| | | LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ERR_DSCFG_ERROR_MISSING_SUBCOMMAND.get()); |
| | | displayMessageAndUsageReference(message); |
| | | retCode = ReturnCode.ERROR_USER_DATA.get(); |
| | | } |
| | |
| | | return retCode; |
| | | } |
| | | |
| | | private void checkForConflictingArguments() throws ArgumentException |
| | | { |
| | | private void checkForConflictingArguments() throws ArgumentException { |
| | | if (quietArgument.isPresent() && verboseArgument.isPresent()) { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get(quietArgument |
| | | .getLongIdentifier(), verboseArgument.getLongIdentifier()); |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get(quietArgument.getLongIdentifier(), |
| | | verboseArgument.getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (batchFileArgument.isPresent() && !noPromptArgument.isPresent()) { |
| | | final LocalizableMessage message = |
| | | ERR_DSCFG_ERROR_QUIET_AND_INTERACTIVE_INCOMPATIBLE.get( |
| | | batchFileArgument.getLongIdentifier(), noPromptArgument |
| | | .getLongIdentifier()); |
| | | final LocalizableMessage message = ERR_DSCFG_ERROR_QUIET_AND_INTERACTIVE_INCOMPATIBLE.get( |
| | | batchFileArgument.getLongIdentifier(), noPromptArgument.getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (quietArgument.isPresent() && !noPromptArgument.isPresent()) { |
| | | final LocalizableMessage message = ERR_DSCFG_ERROR_QUIET_AND_INTERACTIVE_INCOMPATIBLE.get( |
| | | quietArgument.getLongIdentifier(), noPromptArgument |
| | | .getLongIdentifier()); |
| | | quietArgument.getLongIdentifier(), noPromptArgument.getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (scriptFriendlyArgument.isPresent() && verboseArgument.isPresent()) { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get(scriptFriendlyArgument |
| | | .getLongIdentifier(), verboseArgument.getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (noPropertiesFileArgument.isPresent() |
| | | && propertiesFileArgument.isPresent()) |
| | | { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( |
| | | noPropertiesFileArgument.getLongIdentifier(), |
| | | propertiesFileArgument.getLongIdentifier()); |
| | | scriptFriendlyArgument.getLongIdentifier(), verboseArgument.getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | if (noPropertiesFileArgument.isPresent() && propertiesFileArgument.isPresent()) { |
| | | final LocalizableMessage message = ERR_TOOL_CONFLICTING_ARGS.get( |
| | | noPropertiesFileArgument.getLongIdentifier(), propertiesFileArgument.getLongIdentifier()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** Run the top-level interactive console. */ |
| | | private int runInteractiveMode() { |
| | | |
| | | ConsoleApplication app = this; |
| | | |
| | | // Build menu structure. |
| | | final Comparator<RelationDefinition<?, ?>> c = |
| | | new Comparator<RelationDefinition<?, ?>>() { |
| | | final Comparator<RelationDefinition<?, ?>> c = new Comparator<RelationDefinition<?, ?>>() { |
| | | |
| | | @Override |
| | | public int compare(RelationDefinition<?, ?> rd1, |
| | | RelationDefinition<?, ?> rd2) { |
| | | public int compare(RelationDefinition<?, ?> rd1, RelationDefinition<?, ?> rd2) { |
| | | final String s1 = rd1.getUserFriendlyName().toString(); |
| | | final String s2 = rd2.getUserFriendlyName().toString(); |
| | | |
| | |
| | | } |
| | | }; |
| | | |
| | | final Set<RelationDefinition<?, ?>> relations = |
| | | new TreeSet<RelationDefinition<?, ?>>(c); |
| | | final Map<RelationDefinition<?, ?>, CreateSubCommandHandler<?, ?>> createHandlers = |
| | | new HashMap<RelationDefinition<?, ?>, CreateSubCommandHandler<?, ?>>(); |
| | | final Map<RelationDefinition<?, ?>, DeleteSubCommandHandler> deleteHandlers = |
| | | new HashMap<RelationDefinition<?, ?>, DeleteSubCommandHandler>(); |
| | | final Map<RelationDefinition<?, ?>, ListSubCommandHandler> listHandlers = |
| | | new HashMap<RelationDefinition<?, ?>, ListSubCommandHandler>(); |
| | | final Map<RelationDefinition<?, ?>, GetPropSubCommandHandler> getPropHandlers = |
| | | new HashMap<RelationDefinition<?, ?>, GetPropSubCommandHandler>(); |
| | | final Map<RelationDefinition<?, ?>, SetPropSubCommandHandler> setPropHandlers = |
| | | new HashMap<RelationDefinition<?, ?>, SetPropSubCommandHandler>(); |
| | | final Set<RelationDefinition<?, ?>> relations = new TreeSet<RelationDefinition<?, ?>>(c); |
| | | |
| | | final Map<RelationDefinition<?, ?>, CreateSubCommandHandler<?, ?>> createHandlers |
| | | = new HashMap<RelationDefinition<?, ?>, CreateSubCommandHandler<?, ?>>(); |
| | | |
| | | for (final CreateSubCommandHandler<?, ?> ch : handlerFactory |
| | | .getCreateSubCommandHandlers()) { |
| | | final Map<RelationDefinition<?, ?>, DeleteSubCommandHandler> deleteHandlers |
| | | = new HashMap<RelationDefinition<?, ?>, DeleteSubCommandHandler>(); |
| | | |
| | | final Map<RelationDefinition<?, ?>, ListSubCommandHandler> listHandlers |
| | | = new HashMap<RelationDefinition<?, ?>, ListSubCommandHandler>(); |
| | | |
| | | final Map<RelationDefinition<?, ?>, GetPropSubCommandHandler> getPropHandlers |
| | | = new HashMap<RelationDefinition<?, ?>, GetPropSubCommandHandler>(); |
| | | |
| | | final Map<RelationDefinition<?, ?>, SetPropSubCommandHandler> setPropHandlers |
| | | = new HashMap<RelationDefinition<?, ?>, SetPropSubCommandHandler>(); |
| | | |
| | | for (final CreateSubCommandHandler<?, ?> ch : handlerFactory.getCreateSubCommandHandlers()) { |
| | | relations.add(ch.getRelationDefinition()); |
| | | createHandlers.put(ch.getRelationDefinition(), ch); |
| | | } |
| | | |
| | | for (final DeleteSubCommandHandler dh : handlerFactory |
| | | .getDeleteSubCommandHandlers()) { |
| | | for (final DeleteSubCommandHandler dh : handlerFactory.getDeleteSubCommandHandlers()) { |
| | | relations.add(dh.getRelationDefinition()); |
| | | deleteHandlers.put(dh.getRelationDefinition(), dh); |
| | | } |
| | | |
| | | for (final ListSubCommandHandler lh : |
| | | handlerFactory.getListSubCommandHandlers()) { |
| | | for (final ListSubCommandHandler lh : handlerFactory.getListSubCommandHandlers()) { |
| | | relations.add(lh.getRelationDefinition()); |
| | | listHandlers.put(lh.getRelationDefinition(), lh); |
| | | } |
| | | |
| | | for (final GetPropSubCommandHandler gh : handlerFactory |
| | | .getGetPropSubCommandHandlers()) { |
| | | for (final GetPropSubCommandHandler gh : handlerFactory.getGetPropSubCommandHandlers()) { |
| | | relations.add(gh.getRelationDefinition()); |
| | | getPropHandlers.put(gh.getRelationDefinition(), gh); |
| | | } |
| | | |
| | | for (final SetPropSubCommandHandler sh : handlerFactory |
| | | .getSetPropSubCommandHandlers()) { |
| | | for (final SetPropSubCommandHandler sh : handlerFactory.getSetPropSubCommandHandlers()) { |
| | | relations.add(sh.getRelationDefinition()); |
| | | setPropHandlers.put(sh.getRelationDefinition(), sh); |
| | | } |
| | |
| | | builder.setMultipleColumnThreshold(0); |
| | | |
| | | for (final RelationDefinition<?, ?> rd : relations) { |
| | | final MenuCallback<Integer> callback = new SubMenuCallback(app, rd, |
| | | createHandlers.get(rd), deleteHandlers.get(rd), listHandlers.get(rd), |
| | | setPropHandlers.get(rd)); |
| | | final MenuCallback<Integer> callback = new SubMenuCallback(app, rd, createHandlers.get(rd), |
| | | deleteHandlers.get(rd), listHandlers.get(rd), setPropHandlers.get(rd)); |
| | | builder.addNumberedOption(rd.getUserFriendlyName(), callback); |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** Run the provided sub-command handler. */ |
| | | private int runSubCommand(SubCommandHandler handler) { |
| | | try { |
| | | final MenuResult<Integer> result = handler.run(this, factory); |
| | | |
| | | if (result.isSuccess()) { |
| | | if (isInteractive() && |
| | | handler.isCommandBuilderUseful()) |
| | | { |
| | | if (isInteractive() && handler.isCommandBuilderUseful()) { |
| | | printCommandBuilder(getCommandBuilder(handler)); |
| | | } |
| | | return result.getValue(); |
| | |
| | | } catch (ClientException e) { |
| | | Throwable cause = e.getCause(); |
| | | println(); |
| | | if (cause instanceof ManagedObjectDecodingException) |
| | | { |
| | | displayManagedObjectDecodingException(this, |
| | | (ManagedObjectDecodingException) cause); |
| | | } |
| | | else if (cause instanceof MissingMandatoryPropertiesException) |
| | | { |
| | | displayMissingMandatoryPropertyException(this, |
| | | (MissingMandatoryPropertiesException) cause); |
| | | } |
| | | else if (cause instanceof OperationRejectedException) |
| | | { |
| | | displayOperationRejectedException(this, |
| | | (OperationRejectedException) cause); |
| | | } |
| | | else |
| | | { |
| | | if (cause instanceof ManagedObjectDecodingException) { |
| | | displayManagedObjectDecodingException(this, (ManagedObjectDecodingException) cause); |
| | | } else if (cause instanceof MissingMandatoryPropertiesException) { |
| | | displayMissingMandatoryPropertyException(this, (MissingMandatoryPropertiesException) cause); |
| | | } else if (cause instanceof OperationRejectedException) { |
| | | displayOperationRejectedException(this, (OperationRejectedException) cause); |
| | | } else { |
| | | // Just display the default message. |
| | | println(e.getMessageObject()); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Updates the command builder with the global options: script friendly, |
| | | * verbose, etc. for a given sub command. It also adds systematically the |
| | | * no-prompt option. |
| | | * Updates the command builder with the global options: script friendly, verbose, etc. for a given sub command. It |
| | | * also adds systematically the no-prompt option. |
| | | * |
| | | * @param <T> |
| | | * SubCommand type. |
| | |
| | | * The sub command handler or common. |
| | | * @return <T> The builded command. |
| | | */ |
| | | <T> CommandBuilder getCommandBuilder(final T subCommand) |
| | | { |
| | | <T> CommandBuilder getCommandBuilder(final T subCommand) { |
| | | String commandName = System.getProperty(PROPERTY_SCRIPT_NAME); |
| | | if (commandName == null) |
| | | { |
| | | if (commandName == null) { |
| | | commandName = DSCONFIGTOOLNAME; |
| | | } |
| | | CommandBuilder commandBuilder = null; |
| | | if (subCommand instanceof SubCommandHandler) |
| | | { |
| | | commandBuilder = |
| | | new CommandBuilder(commandName, ((SubCommandHandler) subCommand) |
| | | .getSubCommand().getName()); |
| | | } |
| | | else |
| | | { |
| | | if (subCommand instanceof SubCommandHandler) { |
| | | commandBuilder = new CommandBuilder(commandName, |
| | | ((SubCommandHandler) subCommand).getSubCommand().getName()); |
| | | } else { |
| | | commandBuilder = new CommandBuilder(commandName, (String) subCommand); |
| | | } |
| | | if (factory != null && factory.getContextCommandBuilder() != null) |
| | | { |
| | | if (factory != null && factory.getContextCommandBuilder() != null) { |
| | | commandBuilder.append(factory.getContextCommandBuilder()); |
| | | } |
| | | |
| | | if (verboseArgument.isPresent()) |
| | | { |
| | | if (verboseArgument.isPresent()) { |
| | | commandBuilder.addArgument(verboseArgument); |
| | | } |
| | | |
| | | if (scriptFriendlyArgument.isPresent()) |
| | | { |
| | | if (scriptFriendlyArgument.isPresent()) { |
| | | commandBuilder.addArgument(scriptFriendlyArgument); |
| | | } |
| | | |
| | | commandBuilder.addArgument(noPromptArgument); |
| | | |
| | | if (propertiesFileArgument.isPresent()) |
| | | { |
| | | if (propertiesFileArgument.isPresent()) { |
| | | commandBuilder.addArgument(propertiesFileArgument); |
| | | } |
| | | |
| | | if (noPropertiesFileArgument.isPresent()) |
| | | { |
| | | if (noPropertiesFileArgument.isPresent()) { |
| | | commandBuilder.addArgument(noPropertiesFileArgument); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Prints the contents of a command builder. This method has been created |
| | | * since SetPropSubCommandHandler calls it. All the logic of DSConfig is on |
| | | * this method. It writes the content of the CommandBuilder to the standard |
| | | * output, or to a file depending on the options provided by the user. |
| | | * @param commandBuilder the command builder to be printed. |
| | | * Prints the contents of a command builder. This method has been created since SetPropSubCommandHandler calls it. |
| | | * All the logic of DSConfig is on this method. It writes the content of the CommandBuilder to the standard output, |
| | | * or to a file depending on the options provided by the user. |
| | | * |
| | | * @param commandBuilder |
| | | * the command builder to be printed. |
| | | */ |
| | | void printCommandBuilder(CommandBuilder commandBuilder) |
| | | { |
| | | if (displayEquivalentArgument.isPresent()) |
| | | { |
| | | void printCommandBuilder(CommandBuilder commandBuilder) { |
| | | if (displayEquivalentArgument.isPresent()) { |
| | | println(); |
| | | // We assume that the app we are running is this one. |
| | | println(INFO_DSCFG_NON_INTERACTIVE.get(commandBuilder)); |
| | | } |
| | | if (equivalentCommandFileArgument.isPresent()) |
| | | { |
| | | if (equivalentCommandFileArgument.isPresent()) { |
| | | String file = equivalentCommandFileArgument.getValue(); |
| | | BufferedWriter writer = null; |
| | | try |
| | | { |
| | | try { |
| | | writer = new BufferedWriter(new FileWriter(file, true)); |
| | | |
| | | if (!sessionStartTimePrinted) |
| | | { |
| | | if (!sessionStartTimePrinted) { |
| | | writer.write(SHELL_COMMENT_SEPARATOR+getSessionStartTimeMessage()); |
| | | writer.newLine(); |
| | | sessionStartTimePrinted = true; |
| | |
| | | |
| | | sessionEquivalentOperationNumber++; |
| | | writer.newLine(); |
| | | writer.write(SHELL_COMMENT_SEPARATOR+ |
| | | INFO_DSCFG_EQUIVALENT_COMMAND_LINE_SESSION_OPERATION_NUMBER.get( |
| | | sessionEquivalentOperationNumber)); |
| | | writer.write(SHELL_COMMENT_SEPARATOR |
| | | + INFO_DSCFG_EQUIVALENT_COMMAND_LINE_SESSION_OPERATION_NUMBER |
| | | .get(sessionEquivalentOperationNumber)); |
| | | writer.newLine(); |
| | | |
| | | writer.write(SHELL_COMMENT_SEPARATOR+getCurrentOperationDateMessage()); |
| | |
| | | writer.newLine(); |
| | | |
| | | writer.flush(); |
| | | } |
| | | catch (IOException ioe) |
| | | { |
| | | } catch (IOException ioe) { |
| | | println(ERR_DSCFG_ERROR_WRITING_EQUIVALENT_COMMAND_LINE.get(file, ioe)); |
| | | } |
| | | finally |
| | | { |
| | | } finally { |
| | | closeSilently(writer); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Returns the message to be displayed in the file with the equivalent |
| | | * command-line with information about when the session started. |
| | | * @return the message to be displayed in the file with the equivalent |
| | | * command-line with information about when the session started. |
| | | * Returns the message to be displayed in the file with the equivalent command-line with information about when the |
| | | * session started. |
| | | * |
| | | * @return the message to be displayed in the file with the equivalent command-line with information about when the |
| | | * session started. |
| | | */ |
| | | private String getSessionStartTimeMessage() |
| | | { |
| | | private String getSessionStartTimeMessage() { |
| | | String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME); |
| | | if (scriptName == null || scriptName.length() == 0) |
| | | { |
| | | if (scriptName == null || scriptName.length() == 0) { |
| | | scriptName = DSCONFIGTOOLNAME; |
| | | } |
| | | final String date = formatDateTimeStringForEquivalentCommand( |
| | | new Date(sessionStartTime)); |
| | | return INFO_DSCFG_SESSION_START_TIME_MESSAGE.get(scriptName, date). |
| | | toString(); |
| | | final String date = formatDateTimeStringForEquivalentCommand(new Date(sessionStartTime)); |
| | | return INFO_DSCFG_SESSION_START_TIME_MESSAGE.get(scriptName, date).toString(); |
| | | } |
| | | |
| | | private void handleBatchFile(String[] args) { |
| | |
| | | Collections.addAll(initialArgs, args); |
| | | int batchFileArgIndex = -1; |
| | | for (final String elem : initialArgs) { |
| | | if (elem.startsWith("-" + OPTION_SHORT_BATCH_FILE_PATH) |
| | | || elem.contains(OPTION_LONG_BATCH_FILE_PATH)) { |
| | | if (elem.startsWith("-" + OPTION_SHORT_BATCH_FILE_PATH) || elem.contains(OPTION_LONG_BATCH_FILE_PATH)) { |
| | | batchFileArgIndex = initialArgs.indexOf(elem); |
| | | break; |
| | | } |
| | |
| | | initialArgs.remove(batchFileArgIndex); |
| | | } |
| | | final String batchFilePath = batchFileArgument.getValue().trim(); |
| | | bReader = |
| | | new BufferedReader(new FileReader(batchFilePath)); |
| | | bReader = new BufferedReader(new FileReader(batchFilePath)); |
| | | String line; |
| | | String command = ""; |
| | | // Split the CLI string into arguments array |
| | |
| | | final String[] allArgsArray = allArguments.toArray(new String[]{}); |
| | | |
| | | int exitCode = main(allArgsArray, getOutputStream(), getErrorStream()); |
| | | if (exitCode != ReturnCode.SUCCESS.get()) |
| | | { |
| | | if (exitCode != ReturnCode.SUCCESS.get()) { |
| | | System.exit(filterExitCode(exitCode)); |
| | | } |
| | | errPrintln(); |