From bedc84d04ab003c2dfec1119e95478c59599c043 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Tue, 31 Jul 2007 12:48:50 +0000
Subject: [PATCH] Fix issue 1991: dsconfig: split "component" field in list-properties
---
opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java | 423 ++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 325 insertions(+), 98 deletions(-)
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java
index 663839d..337c4bc 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java
@@ -35,9 +35,10 @@
import java.io.PrintStream;
import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -56,10 +57,12 @@
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider;
import org.opends.server.admin.StringPropertyDefinition;
+import org.opends.server.admin.Tag;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.admin.UnknownPropertyDefinitionException;
import org.opends.server.tools.ClientException;
import org.opends.server.util.args.ArgumentException;
+import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.StringArgument;
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.args.SubCommandArgumentParser;
@@ -351,6 +354,11 @@
}
}
+ /**
+ * The type component name to be used for top-level definitions.
+ */
+ private static final String GENERIC_TYPE = "generic";
+
// Strings used in property help.
private final static String HEADING_SEPARATOR = " : ";
@@ -358,17 +366,35 @@
private final static int HEADING_WIDTH;
/**
+ * The value for the long option inherited.
+ */
+ private static final String OPTION_DSCFG_LONG_INHERITED = "inherited";
+
+ /**
+ * The value for the short option inherited.
+ */
+ private static final Character OPTION_DSCFG_SHORT_INHERITED = null;
+
+ /**
* The value for the long option type.
*/
private static final String OPTION_DSCFG_LONG_TYPE = "type";
-
-
/**
* The value for the short option type.
*/
private static final Character OPTION_DSCFG_SHORT_TYPE = 't';
+ /**
+ * The value for the long option category.
+ */
+ private static final String OPTION_DSCFG_LONG_CATEGORY = "category";
+
+ /**
+ * The value for the short option category.
+ */
+ private static final Character OPTION_DSCFG_SHORT_CATEGORY = 'c';
+
static {
int tmp = getMessage(MSGID_DSCFG_HELP_HEADING_SYNTAX).length();
tmp = Math.max(tmp, getMessage(MSGID_DSCFG_HELP_HEADING_DEFAULT).length());
@@ -381,6 +407,8 @@
HEADING_WIDTH = tmp;
}
+
+
/**
* Creates a new help-properties sub-command.
*
@@ -513,17 +541,31 @@
}
}
-
-
// The sub-command associated with this handler.
private final SubCommand subCommand;
- // The argument which should be used to specify the type of managed
- // object to be retrieved.
+ // The argument which should be used to specify the category of
+ // managed object to be retrieved.
+ private final StringArgument categoryArgument;
+
+ //The argument which should be used to display inherited properties.
+ private BooleanArgument inheritedModeArgument;
+
+ // The argument which should be used to specify the sub-type of
+ // managed object to be retrieved.
private final StringArgument typeArgument;
- // A table listing all the available types of managed object.
- private final Map<String, AbstractManagedObjectDefinition<?, ?>> types;
+ // A table listing all the available types of managed object indexed
+ // on their parent type.
+ private final Map<String,
+ Map<String, AbstractManagedObjectDefinition<?, ?>>> categoryMap;
+
+ // A table listing all the available types of managed object indexed
+ // on their tag(s).
+ private final Map<Tag,
+ Map<String, AbstractManagedObjectDefinition<?, ?>>> tagMap;
+
+
// Private constructor.
private HelpSubCommandHandler(ConsoleApplication app,
@@ -536,17 +578,30 @@
this.subCommand = new SubCommand(parser, name, false, 0, 0, null,
descriptionID);
+ this.categoryArgument = new StringArgument(OPTION_DSCFG_LONG_CATEGORY,
+ OPTION_DSCFG_SHORT_CATEGORY, OPTION_DSCFG_LONG_CATEGORY, false, false,
+ true, "{CATEGORY}", null, null, MSGID_DSCFG_DESCRIPTION_HELP_CATEGORY);
+ this.subCommand.addArgument(this.categoryArgument);
+
this.typeArgument = new StringArgument(OPTION_DSCFG_LONG_TYPE,
OPTION_DSCFG_SHORT_TYPE, OPTION_DSCFG_LONG_TYPE, false, false, true,
"{TYPE}", null, null, MSGID_DSCFG_DESCRIPTION_HELP_TYPE);
this.subCommand.addArgument(this.typeArgument);
+ this.inheritedModeArgument = new BooleanArgument(
+ OPTION_DSCFG_LONG_INHERITED, OPTION_DSCFG_SHORT_INHERITED,
+ OPTION_DSCFG_LONG_INHERITED, MSGID_DSCFG_DESCRIPTION_HELP_INHERITED);
+ subCommand.addArgument(inheritedModeArgument);
+
// Register common arguments.
registerAdvancedModeArgument(this.subCommand,
MSGID_DSCFG_DESCRIPTION_ADVANCED_HELP);
registerPropertyNameArgument(this.subCommand);
- this.types = new TreeMap<String, AbstractManagedObjectDefinition<?, ?>>();
+ this.categoryMap = new TreeMap<String,
+ Map<String, AbstractManagedObjectDefinition<?, ?>>>();
+ this.tagMap = new HashMap<Tag,
+ Map<String, AbstractManagedObjectDefinition<?, ?>>>();
}
@@ -570,7 +625,47 @@
*/
public void registerManagedObjectDefinition(
AbstractManagedObjectDefinition<?, ?> d) {
- types.put(d.getName(), d);
+ // Determine the definition's base name.
+ AbstractManagedObjectDefinition<?, ?> parent = d;
+ while (parent.getParent() != null) {
+ parent = parent.getParent();
+ }
+
+ String baseName = parent.getName();
+ String typeName = null;
+ if (parent == d) {
+ // This was a top-level definition.
+ typeName = GENERIC_TYPE;
+ } else {
+ // For the type name we shorten it, if possible, by stripping
+ // off the trailing part of the name which matches the
+ // base-type.
+ String suffix = "-" + baseName;
+ typeName = d.getName();
+ if (typeName.endsWith(suffix)) {
+ typeName = typeName.substring(0, typeName.length() - suffix.length());
+ }
+ }
+
+ // Get the sub-type mapping, creating it if necessary.
+ Map<String, AbstractManagedObjectDefinition<?, ?>> subTypes = categoryMap
+ .get(baseName);
+ if (subTypes == null) {
+ subTypes = new TreeMap<String, AbstractManagedObjectDefinition<?, ?>>();
+ categoryMap.put(baseName, subTypes);
+ }
+
+ subTypes.put(typeName, d);
+
+ // Get the tag mapping, creating it if necessary.
+ for (Tag tag : d.getAllTags()) {
+ subTypes = tagMap.get(baseName);
+ if (subTypes == null) {
+ subTypes = new TreeMap<String, AbstractManagedObjectDefinition<?, ?>>();
+ tagMap.put(tag, subTypes);
+ }
+ subTypes.put(typeName, d);
+ }
}
@@ -579,53 +674,118 @@
* {@inheritDoc}
*/
@Override
- public int run()
- throws ArgumentException, ClientException {
+ public int run() throws ArgumentException, ClientException {
+ String categoryName = categoryArgument.getValue();
String typeName = typeArgument.getValue();
+ Tag tag = null;
Set<String> propertyNames = getPropertyNames();
- AbstractManagedObjectDefinition<?, ?> d = null;
- if (typeName != null) {
- // Requested help regarding a single managed object type.
- d = types.get(typeName);
- if (d == null) {
+ List<AbstractManagedObjectDefinition<?, ?>> dlist =
+ new LinkedList<AbstractManagedObjectDefinition<?, ?>>();
+ AbstractManagedObjectDefinition<?, ?> tmp = null;
+
+ if (categoryName != null) {
+ // User requested a category of components.
+ Map<String, AbstractManagedObjectDefinition<?, ?>> subTypes = categoryMap
+ .get(categoryName);
+
+ if (subTypes == null) {
+ // Try a tag-base look-up.
+ try {
+ tag = Tag.valueOf(categoryName);
+ } catch (IllegalArgumentException e) {
+ throw ArgumentExceptionFactory.unknownCategory(categoryName);
+ }
+
+ categoryName = null;
+ subTypes = tagMap.get(tag);
+ if (subTypes == null) {
+ throw ArgumentExceptionFactory.unknownCategory(categoryName);
+ }
+ } else {
+ // Cache the generic definition for improved errors later on.
+ tmp = subTypes.get(GENERIC_TYPE);
+ }
+
+ if (typeName != null) {
+ AbstractManagedObjectDefinition<?, ?> d = subTypes.get(typeName);
+ if (d == null) {
+ throw ArgumentExceptionFactory.unknownTypeInCategory(categoryName,
+ typeName);
+ }
+ dlist.add(d);
+
+ // Cache the generic definition for improved errors later on.
+ tmp = d;
+ } else {
+ dlist.addAll(subTypes.values());
+ }
+ } else if (typeName != null) {
+ // User requested just the sub-type which could appear in
+ // multiple categories.
+ boolean isFound = false;
+
+ for (Map<String, AbstractManagedObjectDefinition<?, ?>> subTypes :
+ categoryMap.values()) {
+ AbstractManagedObjectDefinition<?, ?> d = subTypes.get(typeName);
+ if (d != null) {
+ dlist.add(d);
+ isFound = true;
+ }
+ }
+
+ if (!isFound) {
throw ArgumentExceptionFactory.unknownType(typeName);
}
+ } else {
+ // User did not specify a category nor a sub-type.
+ for (Map<String, AbstractManagedObjectDefinition<?, ?>> subTypes :
+ categoryMap.values()) {
+ dlist.addAll(subTypes.values());
+ }
}
- // Validate property names if the type was specified.
- if (d != null) {
- for (String propertyName : propertyNames) {
+ // Validate property names.
+ if (dlist.size() == 1) {
+ // Cache the generic definition for improved errors later on.
+ tmp = dlist.get(0);
+ }
+
+ for (String propertyName : propertyNames) {
+ boolean isFound = false;
+
+ for (AbstractManagedObjectDefinition<?, ?> d : dlist) {
try {
d.getPropertyDefinition(propertyName);
+ isFound = true;
} catch (IllegalArgumentException e) {
- throw ArgumentExceptionFactory.unknownProperty(d, propertyName);
+ // Ignore for now.
+ }
+ }
+
+ if (!isFound) {
+ if (tmp != null) {
+ throw ArgumentExceptionFactory.unknownProperty(tmp, propertyName);
+ } else {
+ throw ArgumentExceptionFactory.unknownProperty(propertyName);
}
}
}
- // Determine the set of managed objects to be displayed.
- Collection<AbstractManagedObjectDefinition<?, ?>> defns;
- if (d == null) {
- defns = types.values();
+ if (!getConsoleApplication().isVerbose()) {
+ displayNonVerbose(categoryName, typeName, tag, propertyNames);
} else {
- defns = Collections.<AbstractManagedObjectDefinition<?, ?>> singleton(d);
+ displayVerbose(categoryName, typeName, tag, propertyNames);
}
- if (!getConsoleApplication().isVerbose()) {
- displayNonVerbose(defns, propertyNames);
- } else {
- displayVerbose(defns, propertyNames);
- }
return 0;
}
// Output property summary table.
- private void displayNonVerbose(
- Collection<AbstractManagedObjectDefinition<?, ?>> defns,
- Set<String> propertyNames) {
+ private void displayNonVerbose(String categoryName, String typeName,
+ Tag tag, Set<String> propertyNames) {
PrintStream out = getConsoleApplication().getOutputStream();
if (!getConsoleApplication().isScriptFriendly()) {
out.println(getMessage(MSGID_DSCFG_HELP_DESCRIPTION_OPTION));
@@ -647,7 +807,8 @@
// Headings.
TableBuilder builder = new TableBuilder();
- builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_MANAGED_OBJECT_NAME));
+ builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_COMPONENT_NAME));
+ builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_COMPONENT_TYPE));
builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_NAME));
builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_OPTIONS));
builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_SYNTAX));
@@ -655,45 +816,78 @@
// Sort keys.
builder.addSortKey(0);
builder.addSortKey(1);
+ builder.addSortKey(2);
// Generate the table content.
- for (AbstractManagedObjectDefinition<?, ?> mod : defns) {
- Collection<PropertyDefinition<?>> pds;
- if (getConsoleApplication().isScriptFriendly()) {
- pds = mod.getAllPropertyDefinitions();
- } else {
- pds = mod.getPropertyDefinitions();
+ for (String category : categoryMap.keySet()) {
+ // Skip if this is the wrong category.
+ if (categoryName != null && !categoryName.equals(category)) {
+ continue;
}
- for (PropertyDefinition<?> pd : pds) {
- if (pd.hasOption(PropertyOption.HIDDEN)) {
+ // Process the sub-types.
+ Map<String, AbstractManagedObjectDefinition<?, ?>> subTypes = categoryMap
+ .get(category);
+ for (String type : subTypes.keySet()) {
+ // Skip if this is the wrong sub-type.
+ if (typeName != null && !typeName.equals(type)) {
continue;
}
- if (!isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
+ // Display help for each property.
+ AbstractManagedObjectDefinition<?, ?> mod = subTypes.get(type);
+
+ // Skip if this does not have the required tag.
+ if (tag != null && !mod.hasTag(tag)) {
continue;
}
- if (!propertyNames.isEmpty() && !propertyNames.contains(pd.getName())) {
- continue;
+ Set<PropertyDefinition<?>> pds = new TreeSet<PropertyDefinition<?>>();
+ if (inheritedModeArgument.isPresent()) {
+ pds.addAll(mod.getAllPropertyDefinitions());
+ } else {
+ pds.addAll(mod.getPropertyDefinitions());
+
+ // The list will still contain overridden properties.
+ if (mod.getParent() != null) {
+ pds.removeAll(mod.getParent().getAllPropertyDefinitions());
+ }
}
- // Display the property.
- builder.startRow();
+ for (PropertyDefinition<?> pd : pds) {
+ if (pd.hasOption(PropertyOption.HIDDEN)) {
+ continue;
+ }
- // Display the managed object type if necessary.
- builder.appendCell(mod.getName());
+ if (!isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
+ continue;
+ }
- // Display the property name.
- builder.appendCell(pd.getName());
+ if (!propertyNames.isEmpty() &&
+ !propertyNames.contains(pd.getName())) {
+ continue;
+ }
- // Display the options.
- builder.appendCell(getPropertyOptionSummary(pd));
+ // Display the property.
+ builder.startRow();
- // Display the syntax.
- PropertyDefinitionUsageBuilder v =
- new PropertyDefinitionUsageBuilder(false);
- builder.appendCell(v.getUsage(pd));
+ // Display the component category.
+ builder.appendCell(category);
+
+ // Display the component type.
+ builder.appendCell(type);
+
+ // Display the property name.
+ builder.appendCell(pd.getName());
+
+ // Display the options.
+ builder.appendCell(getPropertyOptionSummary(pd));
+
+ // Display the syntax.
+ PropertyDefinitionUsageBuilder v = new PropertyDefinitionUsageBuilder(
+ false);
+ builder.appendCell(v.getUsage(pd));
+ }
}
}
@@ -709,9 +903,8 @@
// Display detailed help on managed objects and their properties.
- private void displayVerbose(
- Collection<AbstractManagedObjectDefinition<?, ?>> defns,
- Set<String> propertyNames) {
+ private void displayVerbose(String categoryName, String typeName,
+ Tag tag, Set<String> propertyNames) {
PrintStream out = getConsoleApplication().getOutputStream();
// Construct line used to separate consecutive sections.
@@ -722,54 +915,88 @@
// Display help for each managed object.
boolean isFirstManagedObject = true;
- for (AbstractManagedObjectDefinition<?, ?> mod : defns) {
- // Display help for each property.
- Set<PropertyDefinition<?>> pds =
- new TreeSet<PropertyDefinition<?>>(mod.getAllPropertyDefinitions());
- boolean isFirstProperty = true;
- for (PropertyDefinition<?> pd : pds) {
- if (pd.hasOption(PropertyOption.HIDDEN)) {
+ for (String category : categoryMap.keySet()) {
+ // Skip if this is the wrong category.
+ if (categoryName != null && !categoryName.equals(category)) {
+ continue;
+ }
+
+ // Process the sub-types.
+ Map<String, AbstractManagedObjectDefinition<?, ?>> subTypes = categoryMap
+ .get(category);
+ for (String type : subTypes.keySet()) {
+ // Skip if this is the wrong sub-type.
+ if (typeName != null && !typeName.equals(type)) {
continue;
}
- if (!isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
+ // Display help for each property.
+ AbstractManagedObjectDefinition<?, ?> mod = subTypes.get(type);
+
+ // Skip if this does not have the required tag.
+ if (tag != null && !mod.hasTag(tag)) {
continue;
}
- if (!propertyNames.isEmpty() && !propertyNames.contains(pd.getName())) {
- continue;
+ Set<PropertyDefinition<?>> pds = new TreeSet<PropertyDefinition<?>>();
+ if (inheritedModeArgument.isPresent()) {
+ pds.addAll(mod.getAllPropertyDefinitions());
+ } else {
+ pds.addAll(mod.getPropertyDefinitions());
+
+ // The list will still contain overridden properties.
+ if (mod.getParent() != null) {
+ pds.removeAll(mod.getParent().getAllPropertyDefinitions());
+ }
}
- if (isFirstProperty) {
- // User has requested properties relating to this managed
- // object definition, so display the summary of the managed
- // object.
- if (!isFirstManagedObject) {
- out.println();
- out.println(c1);
- out.println();
- } else {
- isFirstManagedObject = false;
+ boolean isFirstProperty = true;
+ for (PropertyDefinition<?> pd : pds) {
+ if (pd.hasOption(PropertyOption.HIDDEN)) {
+ continue;
}
- // Display the title.
- out.println(wrapText(getMessage(MSGID_DSCFG_HELP_HEADING_COMPONENT,
- mod.getUserFriendlyName()), MAX_LINE_WIDTH));
+ if (!isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
+ continue;
+ }
+
+ if (!propertyNames.isEmpty() &&
+ !propertyNames.contains(pd.getName())) {
+ continue;
+ }
+
+ if (isFirstProperty) {
+ // User has requested properties relating to this managed
+ // object definition, so display the summary of the
+ // managed
+ // object.
+ if (!isFirstManagedObject) {
+ out.println();
+ out.println(c1);
+ out.println();
+ } else {
+ isFirstManagedObject = false;
+ }
+
+ // Display the title.
+ out.println(wrapText(getMessage(MSGID_DSCFG_HELP_HEADING_COMPONENT,
+ mod.getUserFriendlyName()), MAX_LINE_WIDTH));
+
+ out.println();
+ out.println(wrapText(mod.getSynopsis(), MAX_LINE_WIDTH));
+ if (mod.getDescription() != null) {
+ out.println();
+ out.println(wrapText(mod.getDescription(), MAX_LINE_WIDTH));
+ }
+ }
out.println();
- out.println(wrapText(mod.getSynopsis(), MAX_LINE_WIDTH));
- if (mod.getDescription() != null) {
- out.println();
- out.println(wrapText(mod.getDescription(), MAX_LINE_WIDTH));
- }
+ out.println(c2);
+ out.println();
+
+ displayVerboseSingleProperty(mod, pd.getName(), out);
+ isFirstProperty = false;
}
-
- out.println();
- out.println(c2);
- out.println();
-
- displayVerboseSingleProperty(mod, pd.getName(), out);
- isFirstProperty = false;
}
}
}
--
Gitblit v1.10.0