/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2014 ForgeRock AS */ package org.forgerock.opendj.config.dsconfig; import static com.forgerock.opendj.dsconfig.DsconfigMessages.*; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.opendj.config.AbstractManagedObjectDefinition; import org.forgerock.opendj.config.ManagedObjectDefinition; import org.forgerock.opendj.config.PropertyDefinition; import org.forgerock.opendj.config.PropertyDefinitionUsageBuilder; import org.forgerock.opendj.config.PropertyException; import org.forgerock.opendj.config.RelationDefinition; import org.forgerock.opendj.config.client.IllegalManagedObjectNameException; import org.forgerock.opendj.config.client.ManagedObjectDecodingException; import org.forgerock.opendj.config.client.MissingMandatoryPropertiesException; import org.forgerock.opendj.config.client.OperationRejectedException; import com.forgerock.opendj.cli.Argument; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.ClientException; import com.forgerock.opendj.cli.ConsoleApplication; import com.forgerock.opendj.cli.ReturnCode; import com.forgerock.opendj.cli.TableBuilder; import com.forgerock.opendj.cli.TextTablePrinter; /** * A utility class for converting various admin exception types into argument exceptions. */ public final class ArgumentExceptionFactory { /** * Creates a ClientException exception from an illegal managed object name exception. * * @param e * The illegal managed object name exception. * @param d * The managed object definition. * @return Returns a ClientException exception. */ public static ClientException adaptIllegalManagedObjectNameException(IllegalManagedObjectNameException e, AbstractManagedObjectDefinition<?, ?> d) { String illegalName = e.getIllegalName(); PropertyDefinition<?> pd = e.getNamingPropertyDefinition(); if (illegalName.length() == 0) { LocalizableMessage message = ERR_DSCFG_ERROR_ILLEGAL_NAME_EMPTY.get(d.getUserFriendlyPluralName()); return new ClientException(ReturnCode.ERROR_USER_DATA, message); } else if (illegalName.trim().length() == 0) { LocalizableMessage message = ERR_DSCFG_ERROR_ILLEGAL_NAME_BLANK.get(d.getUserFriendlyPluralName()); return new ClientException(ReturnCode.ERROR_USER_DATA, message); } else if (pd != null) { try { pd.decodeValue(illegalName); } catch (PropertyException e1) { PropertyDefinitionUsageBuilder b = new PropertyDefinitionUsageBuilder(true); LocalizableMessage syntax = b.getUsage(pd); LocalizableMessage message = ERR_DSCFG_ERROR_ILLEGAL_NAME_SYNTAX.get(illegalName, d.getUserFriendlyName(), syntax); return new ClientException(ReturnCode.ERROR_USER_DATA, message); } } LocalizableMessage message = ERR_DSCFG_ERROR_ILLEGAL_NAME_UNKNOWN.get(illegalName, d.getUserFriendlyName()); return new ClientException(ReturnCode.ERROR_USER_DATA, message); } /** * Creates an argument exception from a property exception. * * @param e * The property exception. * @param d * The managed object definition. * @return Returns an argument exception. */ public static ArgumentException adaptPropertyException(PropertyException e, AbstractManagedObjectDefinition<?, ?> d) { return new ArgumentException(e.getMessageObject()); } /** * Displays a table listing reasons why a managed object could not be decoded successfully. * * @param app * The console application. * @param e * The managed object decoding exception. */ public static void displayManagedObjectDecodingException(ConsoleApplication app, ManagedObjectDecodingException e) { AbstractManagedObjectDefinition<?, ?> d = e.getPartialManagedObject().getManagedObjectDefinition(); LocalizableMessage ufn = d.getUserFriendlyName(); LocalizableMessage msg = e.getCauses().size() == 1 ? ERR_GET_HEADING_MODE_SINGLE.get(ufn) : ERR_GET_HEADING_MODE_PLURAL.get(ufn); app.errPrintln(msg); app.errPrintln(); TableBuilder builder = new TableBuilder(); for (PropertyException pe : e.getCauses()) { ArgumentException ae = adaptPropertyException(pe, d); builder.startRow(); builder.appendCell("*"); builder.appendCell(ae.getMessage()); } TextTablePrinter printer = new TextTablePrinter(app.getErrorStream()); printer.setDisplayHeadings(false); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); } /** * Displays a table listing missing mandatory properties. * * @param app * The console application. * @param e * The missing mandatory property exception. */ public static void displayMissingMandatoryPropertyException(ConsoleApplication app, MissingMandatoryPropertiesException e) { LocalizableMessage ufn = e.getUserFriendlyName(); LocalizableMessage msg; final boolean onePropertyMissing = e.getCauses().size() == 1; if (e.isCreate()) { msg = onePropertyMissing ? ERR_CREATE_HEADING_MMPE_SINGLE.get(ufn) : ERR_CREATE_HEADING_MMPE_PLURAL.get(ufn); } else { msg = onePropertyMissing ? ERR_MODIFY_HEADING_MMPE_SINGLE.get(ufn) : ERR_MODIFY_HEADING_MMPE_PLURAL.get(ufn); } app.errPrintln(msg); app.errPrintln(); TableBuilder builder = new TableBuilder(); builder.addSortKey(0); builder.appendHeading(INFO_DSCFG_HEADING_PROPERTY_NAME.get()); builder.appendHeading(INFO_DSCFG_HEADING_PROPERTY_SYNTAX.get()); PropertyDefinitionUsageBuilder b = new PropertyDefinitionUsageBuilder(true); for (PropertyException pe : e.getCauses()) { PropertyDefinition<?> pd = pe.getPropertyDefinition(); builder.startRow(); builder.appendCell(pd.getName()); builder.appendCell(b.getUsage(pd)); } TextTablePrinter printer = new TextTablePrinter(app.getErrorStream()); printer.setDisplayHeadings(true); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); } /** * Displays a table listing the reasons why an operation was rejected. * * @param app * The console application. * @param e * The operation rejected exception. */ public static void displayOperationRejectedException(ConsoleApplication app, OperationRejectedException e) { LocalizableMessage ufn = e.getUserFriendlyName(); LocalizableMessage msg; final boolean singleMessage = e.getMessages().size() == 1; switch (e.getOperationType()) { case CREATE: msg = singleMessage ? ERR_DSCFG_ERROR_CREATE_ORE_SINGLE.get(ufn) : ERR_DSCFG_ERROR_CREATE_ORE_PLURAL.get(ufn); break; case DELETE: msg = singleMessage ? ERR_DSCFG_ERROR_DELETE_ORE_SINGLE.get(ufn) : ERR_DSCFG_ERROR_DELETE_ORE_PLURAL.get(ufn); break; default: msg = singleMessage ? ERR_DSCFG_ERROR_MODIFY_ORE_SINGLE.get(ufn) : ERR_DSCFG_ERROR_MODIFY_ORE_PLURAL.get(ufn); break; } app.errPrintln(msg); app.errPrintln(); TableBuilder builder = new TableBuilder(); for (LocalizableMessage reason : e.getMessages()) { builder.startRow(); builder.appendCell("*"); builder.appendCell(reason); } TextTablePrinter printer = new TextTablePrinter(app.getErrorStream()); printer.setDisplayHeadings(false); printer.setColumnWidth(1, 0); printer.setIndentWidth(4); builder.print(printer); } /** * Creates an argument exception which should be used when a property modification argument is incompatible with a * previous modification argument. * * @param arg * The incompatible argument. * @return Returns an argument exception. */ public static ArgumentException incompatiblePropertyModification(String arg) { LocalizableMessage msg = ERR_DSCFG_ERROR_INCOMPATIBLE_PROPERTY_MOD.get(arg); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when the client has not specified a bind password. * * @param bindDN * The name of the user requiring a password. * @return Returns an argument exception. */ public static ArgumentException missingBindPassword(String bindDN) { LocalizableMessage msg = ERR_DSCFG_ERROR_NO_PASSWORD.get(bindDN); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when the client has not specified a bind password. * * @param bindDN * The name of the user requiring a password. * @return Returns an argument exception. */ public static ArgumentException missingBindPassword(char[] bindDN) { LocalizableMessage msg = ERR_DSCFG_ERROR_NO_PASSWORD.get(bindDN); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when an argument, which is mandatory when the application is * non-interactive, has not been specified. * * @param arg * The missing argument. * @return Returns an argument exception. */ public static ArgumentException missingMandatoryNonInteractiveArgument(Argument arg) { LocalizableMessage msg = ERR_DSCFG_ERROR_MISSING_NON_INTERACTIVE_ARG.get(arg.getLongIdentifier()); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a property value argument is invalid because it does not * a property name. * * @param arg * The argument having the missing property name. * @return Returns an argument exception. */ public static ArgumentException missingNameInPropertyArgument(String arg) { LocalizableMessage msg = ERR_DSCFG_ERROR_NO_NAME_IN_PROPERTY_VALUE.get(arg); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a property modification argument is invalid because it * does not a property name. * * @param arg * The argument having the missing property name. * @return Returns an argument exception. */ public static ArgumentException missingNameInPropertyModification(String arg) { LocalizableMessage msg = ERR_DSCFG_ERROR_NO_NAME_IN_PROPERTY_MOD.get(arg); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a property value argument is invalid because it does not * contain a separator between the property name and its value. * * @param arg * The argument having a missing separator. * @return Returns an argument exception. */ public static ArgumentException missingSeparatorInPropertyArgument(String arg) { LocalizableMessage msg = ERR_DSCFG_ERROR_NO_SEPARATOR_IN_PROPERTY_VALUE.get(arg); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a property modification argument is invalid because it * does not contain a separator between the property name and its value. * * @param arg * The argument having a missing separator. * @return Returns an argument exception. */ public static ArgumentException missingSeparatorInPropertyModification(String arg) { LocalizableMessage msg = ERR_DSCFG_ERROR_NO_SEPARATOR_IN_PROPERTY_MOD.get(arg); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a property value argument is invalid because it does not * a property value. * * @param arg * The argument having the missing property value. * @return Returns an argument exception. */ public static ArgumentException missingValueInPropertyArgument(String arg) { LocalizableMessage msg = ERR_DSCFG_ERROR_NO_VALUE_IN_PROPERTY_VALUE.get(arg); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a property modification argument is invalid because it * does not a property value. * * @param arg * The argument having the missing property value. * @return Returns an argument exception. */ public static ArgumentException missingValueInPropertyModification(String arg) { LocalizableMessage msg = ERR_DSCFG_ERROR_NO_NAME_IN_PROPERTY_MOD.get(arg); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when the connection parameters could not be read from the * standard input. * * @param cause * The reason why the connection parameters could not be read. * @return Returns an argument exception. */ public static ArgumentException unableToReadConnectionParameters(Exception cause) { LocalizableMessage message = ERR_DSCFG_ERROR_CANNOT_READ_CONNECTION_PARAMETERS.get(cause.getMessage()); return new ArgumentException(message, cause); } /** * Creates an argument exception which should be used when the bind password could not be read from the standard * input because the application is non-interactive. * * @return Returns an argument exception. */ public static ArgumentException unableToReadBindPasswordInteractively() { LocalizableMessage message = ERR_DSCFG_ERROR_BIND_PASSWORD_NONINTERACTIVE.get(); return new ArgumentException(message); } /** * Creates an argument exception which should be used when an attempt is made to reset a mandatory property that * does not have any default values. * * @param d * The managed object definition. * @param name * The name of the mandatory property. * @param setOption * The name of the option which should be used to set the property's values. * @return Returns an argument exception. */ public static ArgumentException unableToResetMandatoryProperty(AbstractManagedObjectDefinition<?, ?> d, String name, String setOption) { LocalizableMessage message = ERR_DSCFG_ERROR_UNABLE_TO_RESET_MANDATORY_PROPERTY.get( d.getUserFriendlyPluralName(), name, setOption); return new ArgumentException(message); } /** * Creates an argument exception which should be used when an attempt is made to reset a property with a value. * * @param name * The name of the mandatory property. * @param resetOption * The name of the option which should be used to reset the property's values. * @return Returns an argument exception. */ public static ArgumentException unableToResetPropertyWithValue(String name, String resetOption) { LocalizableMessage message = ERR_DSCFG_ERROR_UNABLE_TO_RESET_PROPERTY_WITH_VALUE.get(resetOption, name, resetOption); return new ArgumentException(message); } /** * Creates an argument exception which should be used when an attempt is made to set the naming property for a * managed object during creation. * * @param d * The managed object definition. * @param pd * The naming property definition. * @return Returns an argument exception. */ public static ArgumentException unableToSetNamingProperty(AbstractManagedObjectDefinition<?, ?> d, PropertyDefinition<?> pd) { LocalizableMessage message = ERR_DSCFG_ERROR_UNABLE_TO_SET_NAMING_PROPERTY.get(pd.getName(), d.getUserFriendlyName()); return new ArgumentException(message); } /** * Creates an argument exception which should be used when a component category argument is not recognized. * * @param categoryName * The unrecognized component category. * @return Returns an argument exception. */ public static ArgumentException unknownCategory(String categoryName) { LocalizableMessage msg = ERR_DSCFG_ERROR_CATEGORY_UNRECOGNIZED.get(categoryName); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a property name is not recognized. * * @param d * The managed object definition. * @param name * The unrecognized property name. * @return Returns an argument exception. */ public static ArgumentException unknownProperty(AbstractManagedObjectDefinition<?, ?> d, String name) { LocalizableMessage message = ERR_DSCFG_ERROR_PROPERTY_UNRECOGNIZED.get(name, d.getUserFriendlyPluralName()); return new ArgumentException(message); } /** * Creates an argument exception which should be used when a property name is not recognized. * * @param name * The unrecognized property name. * @return Returns an argument exception. */ public static ArgumentException unknownProperty(String name) { LocalizableMessage message = ERR_DSCFG_ERROR_PROPERTY_UNRECOGNIZED_NO_DEFN.get(name); return new ArgumentException(message); } /** * Creates an argument exception which should be used when a sub-type argument in a create-xxx sub-command is not * recognized. * * @param r * The relation definition. * @param typeName * The unrecognized property sub-type. * @param typeUsage * A usage string describing the allowed sub-types. * @return Returns an argument exception. */ public static ArgumentException unknownSubType(RelationDefinition<?, ?> r, String typeName, String typeUsage) { LocalizableMessage msg = ERR_DSCFG_ERROR_SUB_TYPE_UNRECOGNIZED .get(typeName, r.getUserFriendlyName(), typeUsage); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a managed object type argument is not associated with a * category. * * @param categoryName * The component category. * @param typeName * The unrecognized component type. * @return Returns an argument exception. */ public static ArgumentException unknownTypeForCategory(String typeName, String categoryName) { LocalizableMessage msg = ERR_DSCFG_ERROR_CATEGORY_TYPE_UNRECOGNIZED.get(typeName, categoryName); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a multi-valued property does not contain a given value. * * @param value * The property value. * @param propertyName * The property name. * @return Returns an argument exception. */ public static ArgumentException unknownValueForMultiValuedProperty(String value, String propertyName) { LocalizableMessage msg = ERR_DSCFG_ERROR_VALUE_DOES_NOT_EXIST.get(value, propertyName); return new ArgumentException(msg); } /** * Creates an argument exception which should be used when a child component does not exist. * * @param componentName * The component name. * @return Returns an argument exception. */ public static ArgumentException unknownValueForChildComponent(String componentName) { LocalizableMessage msg = ERR_DSCFG_ERROR_FINDER_NO_CHILDREN.get(componentName); return new ArgumentException(msg); } /** * Creates a CLI exception which should be used when a managed object is retrieved but does not have the correct * type appropriate for the associated sub-command. * * @param r * The relation definition. * @param d * The definition of the managed object that was retrieved. * @param subcommandName * the sub-command name. * @return Returns a Client exception. */ public static ClientException wrongManagedObjectType(RelationDefinition<?, ?> r, ManagedObjectDefinition<?, ?> d, String subcommandName) { LocalizableMessage msg = ERR_DSCFG_ERROR_TYPE_UNRECOGNIZED_FOR_SUBCOMMAND.get(d.getUserFriendlyName(), subcommandName); return new ClientException(ReturnCode.ERROR_USER_DATA, msg); } /** Prevent instantiation. */ private ArgumentExceptionFactory() { // No implementation required. } }