From 54c2799f45256fef4a981fa2a6a7c97a9708ac8b Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Thu, 26 Jul 2007 12:01:44 +0000
Subject: [PATCH] Partial fix for issue 1831 - dsconfig interactive mode.
---
opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java | 2
opends/src/server/org/opends/server/admin/PropertyIsMandatoryException.java | 2
opends/src/server/org/opends/server/tools/dsconfig/messages.properties | 3
opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java | 15
opends/src/server/org/opends/server/admin/IllegalPropertyValueException.java | 2
opends/src/server/org/opends/server/admin/DefaultBehaviorException.java | 2
opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java | 124 -
opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java | 5
opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java | 4
opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java | 164 ++
opends/src/server/org/opends/server/tools/dsconfig/ConsoleApplication.java | 494 ++++++++++
opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java | 55
opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java | 10
opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java | 2
opends/src/server/org/opends/server/admin/client/ManagedObject.java | 209 +++-
opends/src/server/org/opends/server/admin/ManagedObjectPath.java | 71 +
opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java | 14
opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java | 89 +
opends/resource/admin/metaMO.xsl | 4
opends/src/server/org/opends/server/tools/dsconfig/ManagementContextFactory.java | 4
opends/src/server/org/opends/server/tools/dsconfig/InternalManagementContextFactory.java | 2
opends/src/server/org/opends/server/admin/ManagedObjectDefinitionResource.java | 9
opends/src/server/org/opends/server/tools/dsconfig/ArgumentExceptionFactory.java | 111 +
opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java | 4
opends/src/server/org/opends/server/admin/PropertyIsSingleValuedException.java | 2
opends/src/server/org/opends/server/admin/server/DNBuilder.java | 10
opends/resource/admin/clientMO.xsl | 16
opends/src/server/org/opends/server/admin/IllegalPropertyValueStringException.java | 2
opends/src/server/org/opends/server/admin/client/PropertySet.java | 8
opends/src/server/org/opends/server/admin/PropertyDefinition.java | 2
opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java | 2
opends/src/server/org/opends/server/admin/PropertyIsReadOnlyException.java | 2
opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java | 54
opends/src/server/org/opends/server/admin/AggregationRelationDefinition.java | 10
opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java | 270 +++--
opends/src/server/org/opends/server/admin/AbsoluteInheritedDefaultBehaviorProvider.java | 4
opends/src/server/org/opends/server/admin/RelativeInheritedDefaultBehaviorProvider.java | 3
opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java | 8
opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java | 12
opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java | 298 +----
opends/src/server/org/opends/server/tools/dsconfig/ValidationCallback.java | 59 +
opends/src/server/org/opends/server/admin/server/ConfigChangeListenerAdaptor.java | 24
opends/src/server/org/opends/server/admin/server/ServerManagedObject.java | 43
opends/src/server/org/opends/server/tools/dsconfig/LDAPManagementContextFactory.java | 2
opends/src/server/org/opends/server/tools/dsconfig/SubCommandBuilder.java | 39
opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java | 11
opends/src/server/org/opends/server/admin/UnknownPropertyDefinitionException.java | 2
opends/src/server/org/opends/server/messages/ToolMessages.java | 188 +++
opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java | 39
opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java | 278 ++++-
opends/src/server/org/opends/server/tools/dsconfig/HelpCallback.java | 43
51 files changed, 1,992 insertions(+), 840 deletions(-)
diff --git a/opends/resource/admin/clientMO.xsl b/opends/resource/admin/clientMO.xsl
index c4d166a..674072c 100644
--- a/opends/resource/admin/clientMO.xsl
+++ b/opends/resource/admin/clientMO.xsl
@@ -195,7 +195,7 @@
</xsl:call-template>
<xsl:value-of
select="concat(' <C extends ', $java-class-name,'CfgClient> C create', $java-relation-name, '(
',
- ' ManagedObjectDefinition<C, ?> d, Collection<DefaultBehaviorException> exceptions);
')" />
+ ' ManagedObjectDefinition<C, ? extends ', $java-class-name,'Cfg> d, Collection<DefaultBehaviorException> exceptions);
')" />
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
@@ -312,7 +312,7 @@
</xsl:call-template>
<xsl:value-of
select="concat(' <C extends ', $java-class-name,'CfgClient> C create', $java-relation-name, '(
',
- ' ManagedObjectDefinition<C, ?> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException;
')" />
+ ' ManagedObjectDefinition<C, ? extends ', $java-class-name,'Cfg> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException;
')" />
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
@@ -396,6 +396,18 @@
org.opends.server.admin.client.CommunicationException
</import>
</xsl:if>
+ <xsl:for-each select="$this-local-relations[adm:one-to-zero-or-one]|$this-local-relations[adm:one-to-many]">
+ <xsl:variable name="java-class-name">
+ <xsl:call-template name="name-to-java">
+ <xsl:with-param name="value"
+ select="@managed-object-name" />
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:element name="import">
+ <xsl:value-of
+ select="concat(@managed-object-package, '.server.', $java-class-name, 'Cfg')" />
+ </xsl:element>
+ </xsl:for-each>
<xsl:if
test="$this-local-relations/adm:one-to-zero-or-one|$this-local-relations/adm:one-to-many">
<import>java.util.Collection</import>
diff --git a/opends/resource/admin/metaMO.xsl b/opends/resource/admin/metaMO.xsl
index 3973263..3deb2c9 100644
--- a/opends/resource/admin/metaMO.xsl
+++ b/opends/resource/admin/metaMO.xsl
@@ -1201,7 +1201,7 @@
' * {@inheritDoc}
',
' */
',
' public <M extends ', $java-class-name, 'CfgClient> M create', $java-relation-name, '(
',
- ' ManagedObjectDefinition<M, ?> d, Collection<DefaultBehaviorException> exceptions) {
',
+ ' ManagedObjectDefinition<M, ? extends ', $java-class-name,'Cfg> d, Collection<DefaultBehaviorException> exceptions) {
',
' return impl.createChild(INSTANCE.get', $java-relation-name,'RelationDefinition(), d, exceptions).getConfiguration();
',
' }
')" />
<xsl:text>
</xsl:text>
@@ -1254,7 +1254,7 @@
' * {@inheritDoc}
',
' */
',
' public <M extends ', $java-class-name, 'CfgClient> M create', $java-relation-name, '(
',
- ' ManagedObjectDefinition<M, ?> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException {
',
+ ' ManagedObjectDefinition<M, ? extends ', $java-class-name,'Cfg> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException {
',
' return impl.createChild(INSTANCE.get', $java-relation-plural-name,'RelationDefinition(), d, name, exceptions).getConfiguration();
',
' }
')" />
<xsl:text>
</xsl:text>
diff --git a/opends/src/server/org/opends/server/admin/AbsoluteInheritedDefaultBehaviorProvider.java b/opends/src/server/org/opends/server/admin/AbsoluteInheritedDefaultBehaviorProvider.java
index c1671af..e0f961c 100644
--- a/opends/src/server/org/opends/server/admin/AbsoluteInheritedDefaultBehaviorProvider.java
+++ b/opends/src/server/org/opends/server/admin/AbsoluteInheritedDefaultBehaviorProvider.java
@@ -41,7 +41,7 @@
DefaultBehaviorProvider<T> {
// The absolute path to the managed object containing the property.
- private final ManagedObjectPath path;
+ private final ManagedObjectPath<?, ?> path;
// The name of the property containing the inherited default values.
private final String propertyName;
@@ -104,7 +104,7 @@
* @return Returns the absolute path of the managed object
* containing the property which has the default values.
*/
- public ManagedObjectPath getManagedObjectPath() {
+ public ManagedObjectPath<?, ?> getManagedObjectPath() {
return path;
}
diff --git a/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java b/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
index d6795e6..a1295cd 100644
--- a/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
+++ b/opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
@@ -334,13 +334,13 @@
* If the specified property name was null or empty or if
* the requested property definition was not found.
*/
- public final PropertyDefinition getPropertyDefinition(String name)
+ public final PropertyDefinition<?> getPropertyDefinition(String name)
throws IllegalArgumentException {
if ((name == null) || (name.length() == 0)) {
throw new IllegalArgumentException("null or empty property name");
}
- PropertyDefinition d = allPropertyDefinitions.get(name);
+ PropertyDefinition<?> d = allPropertyDefinitions.get(name);
if (d == null) {
throw new IllegalArgumentException("property definition \"" + name
+ "\" not found");
@@ -380,13 +380,13 @@
* If the specified relation name was null or empty or if
* the requested relation definition was not found.
*/
- public final RelationDefinition getRelationDefinition(String name)
+ public final RelationDefinition<?, ?> getRelationDefinition(String name)
throws IllegalArgumentException {
if ((name == null) || (name.length() == 0)) {
throw new IllegalArgumentException("null or empty relation name");
}
- RelationDefinition d = allRelationDefinitions.get(name);
+ RelationDefinition<?, ?> d = allRelationDefinitions.get(name);
if (d == null) {
throw new IllegalArgumentException("relation definition \"" + name
+ "\" not found");
@@ -642,7 +642,8 @@
* @param d
* The relation definition to be deregistered.
*/
- protected final void deregisterRelationDefinition(RelationDefinition d) {
+ protected final void deregisterRelationDefinition(
+ RelationDefinition<?, ?> d) {
String name = d.getName();
relationDefinitions.remove(name);
@@ -660,7 +661,7 @@
* @param d
* The property definition to be registered.
*/
- protected final void registerPropertyDefinition(PropertyDefinition d) {
+ protected final void registerPropertyDefinition(PropertyDefinition<?> d) {
String name = d.getName();
propertyDefinitions.put(name, d);
@@ -678,7 +679,7 @@
* @param d
* The relation definition to be registered.
*/
- protected final void registerRelationDefinition(RelationDefinition d) {
+ protected final void registerRelationDefinition(RelationDefinition<?, ?> d) {
String name = d.getName();
relationDefinitions.put(name, d);
diff --git a/opends/src/server/org/opends/server/admin/AggregationRelationDefinition.java b/opends/src/server/org/opends/server/admin/AggregationRelationDefinition.java
index dbd9300..fb699c1 100644
--- a/opends/src/server/org/opends/server/admin/AggregationRelationDefinition.java
+++ b/opends/src/server/org/opends/server/admin/AggregationRelationDefinition.java
@@ -70,7 +70,7 @@
// The path identifying the location of the referenced managed
// objects.
- private ManagedObjectPath path;
+ private ManagedObjectPath<?, ?> path;
// The plural name of the relation.
private final String pluralName;
@@ -131,7 +131,7 @@
* The path identifying the location of the referenced
* managed objects.
*/
- public void setPath(ManagedObjectPath path) {
+ public void setPath(ManagedObjectPath<?, ?> path) {
this.path = path;
}
@@ -157,7 +157,7 @@
// The path identifying the location of the referenced managed
// objects.
- private final ManagedObjectPath path;
+ private final ManagedObjectPath<?, ?> path;
// The plural name of the relation.
private final String pluralName;
@@ -166,7 +166,7 @@
// Private constructor.
private AggregationRelationDefinition(Common<C, S> common, String pluralName,
- ManagedObjectPath path, int minOccurs, int maxOccurs)
+ ManagedObjectPath<?, ?> path, int minOccurs, int maxOccurs)
throws IllegalArgumentException {
super(common);
@@ -228,7 +228,7 @@
* @return Returns the path identifying the location of the
* referenced managed objects.
*/
- public ManagedObjectPath getPath() {
+ public ManagedObjectPath<?, ?> getPath() {
return path;
}
diff --git a/opends/src/server/org/opends/server/admin/DefaultBehaviorException.java b/opends/src/server/org/opends/server/admin/DefaultBehaviorException.java
index 1ecc04a..55ed90d 100644
--- a/opends/src/server/org/opends/server/admin/DefaultBehaviorException.java
+++ b/opends/src/server/org/opends/server/admin/DefaultBehaviorException.java
@@ -62,7 +62,7 @@
* The exception that prevented the default values from
* being determined.
*/
- public DefaultBehaviorException(PropertyDefinition pd, Throwable cause) {
+ public DefaultBehaviorException(PropertyDefinition<?> pd, Throwable cause) {
super(pd);
this.cause = cause;
}
diff --git a/opends/src/server/org/opends/server/admin/IllegalPropertyValueException.java b/opends/src/server/org/opends/server/admin/IllegalPropertyValueException.java
index bae4b84..591252c 100644
--- a/opends/src/server/org/opends/server/admin/IllegalPropertyValueException.java
+++ b/opends/src/server/org/opends/server/admin/IllegalPropertyValueException.java
@@ -53,7 +53,7 @@
* @param value
* The illegal property value.
*/
- public IllegalPropertyValueException(PropertyDefinition d, Object value) {
+ public IllegalPropertyValueException(PropertyDefinition<?> d, Object value) {
super(d);
this.value = value;
}
diff --git a/opends/src/server/org/opends/server/admin/IllegalPropertyValueStringException.java b/opends/src/server/org/opends/server/admin/IllegalPropertyValueStringException.java
index f23e642..6c062ea 100644
--- a/opends/src/server/org/opends/server/admin/IllegalPropertyValueStringException.java
+++ b/opends/src/server/org/opends/server/admin/IllegalPropertyValueStringException.java
@@ -53,7 +53,7 @@
* @param value
* The illegal property value string.
*/
- public IllegalPropertyValueStringException(PropertyDefinition d,
+ public IllegalPropertyValueStringException(PropertyDefinition<?> d,
String value) {
super(d);
this.value = value;
diff --git a/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java b/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java
index 2c1865e..dc36db0 100644
--- a/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java
+++ b/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java
@@ -95,7 +95,7 @@
// Mapping from definition to locale-based resource bundle.
- private final Map<AbstractManagedObjectDefinition,
+ private final Map<AbstractManagedObjectDefinition<?, ?>,
Map<Locale, ResourceBundle>> resources;
@@ -107,7 +107,7 @@
// Private constructor.
private ManagedObjectDefinitionI18NResource(String prefix) {
- this.resources = new HashMap<AbstractManagedObjectDefinition,
+ this.resources = new HashMap<AbstractManagedObjectDefinition<?, ?>,
Map<Locale, ResourceBundle>>();
this.prefix = prefix;
}
@@ -127,7 +127,7 @@
* @throws MissingResourceException
* If the key was not found.
*/
- public String getMessage(AbstractManagedObjectDefinition d,
+ public String getMessage(AbstractManagedObjectDefinition<?, ?> d,
String key) throws MissingResourceException {
return getMessage(d, key, Locale.getDefault(), (String[]) null);
}
@@ -149,7 +149,7 @@
* @throws MissingResourceException
* If the key was not found.
*/
- public String getMessage(AbstractManagedObjectDefinition d,
+ public String getMessage(AbstractManagedObjectDefinition<?, ?> d,
String key, Locale locale) throws MissingResourceException {
return getMessage(d, key, locale, (String[]) null);
}
@@ -174,7 +174,7 @@
* @throws MissingResourceException
* If the key was not found.
*/
- public String getMessage(AbstractManagedObjectDefinition d,
+ public String getMessage(AbstractManagedObjectDefinition<?, ?> d,
String key, Locale locale, String... args)
throws MissingResourceException {
ResourceBundle resource = getResourceBundle(d, locale);
@@ -205,7 +205,7 @@
* @throws MissingResourceException
* If the key was not found.
*/
- public String getMessage(AbstractManagedObjectDefinition d,
+ public String getMessage(AbstractManagedObjectDefinition<?, ?> d,
String key, String... args) throws MissingResourceException {
return getMessage(d, key, Locale.getDefault(), args);
}
@@ -215,7 +215,7 @@
// Retrieve the resource bundle associated with a managed object and
// locale, lazily loading it if necessary.
private synchronized ResourceBundle getResourceBundle(
- AbstractManagedObjectDefinition d, Locale locale)
+ AbstractManagedObjectDefinition<?, ?> d, Locale locale)
throws MissingResourceException {
// First get the locale-resource mapping, creating it if
// necessary.
diff --git a/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionResource.java b/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionResource.java
index 8beb696..c3e4a20 100644
--- a/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionResource.java
+++ b/opends/src/server/org/opends/server/admin/ManagedObjectDefinitionResource.java
@@ -46,7 +46,8 @@
public final class ManagedObjectDefinitionResource {
// Mapping from definition to property tables.
- private final Map<AbstractManagedObjectDefinition, Properties> properties;
+ private final Map<AbstractManagedObjectDefinition<?, ?>,
+ Properties> properties;
// The resource name prefix.
private final String prefix;
@@ -71,7 +72,7 @@
// Private constructor.
private ManagedObjectDefinitionResource(String prefix) {
this.properties =
- new HashMap<AbstractManagedObjectDefinition, Properties>();
+ new HashMap<AbstractManagedObjectDefinition<?, ?>, Properties>();
this.prefix = prefix;
}
@@ -89,7 +90,7 @@
* @throws MissingResourceException
* If the key was not found.
*/
- public String getString(AbstractManagedObjectDefinition d,
+ public String getString(AbstractManagedObjectDefinition<?, ?> d,
String key) throws MissingResourceException {
Properties p = getProperties(d);
String result = p.getProperty(key);
@@ -111,7 +112,7 @@
// lazily
// loading it if necessary.
private synchronized Properties getProperties(
- AbstractManagedObjectDefinition d)
+ AbstractManagedObjectDefinition<?, ?> d)
throws MissingResourceException {
Properties p = properties.get(d);
diff --git a/opends/src/server/org/opends/server/admin/ManagedObjectPath.java b/opends/src/server/org/opends/server/admin/ManagedObjectPath.java
index eb164e1..d81a34c 100644
--- a/opends/src/server/org/opends/server/admin/ManagedObjectPath.java
+++ b/opends/src/server/org/opends/server/admin/ManagedObjectPath.java
@@ -150,6 +150,18 @@
/**
+ * Get the name associated with this element if applicable.
+ *
+ * @return Returns the name associated with this element if
+ * applicable.
+ */
+ public String getName() {
+ return null;
+ }
+
+
+
+ /**
* Get the relation definition associated with this element.
*
* @return Returns the relation definition associated with this
@@ -211,6 +223,16 @@
* {@inheritDoc}
*/
@Override
+ public String getName() {
+ return name;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public InstantiableRelationDefinition<? super C, ? super S>
getRelationDefinition() {
return r;
@@ -395,8 +417,8 @@
// Common element serialization.
- private <M, N> void serializeElement(RelationDefinition r,
- AbstractManagedObjectDefinition d) {
+ private <M, N> void serializeElement(RelationDefinition<?, ?> r,
+ AbstractManagedObjectDefinition<?, ?> d) {
// Always specify the relation name.
builder.append("/relation=");
builder.append(r.getName());
@@ -636,6 +658,49 @@
/**
+ * Creates a new managed object path which has the same structure as
+ * this path except that the final path element is associated with
+ * the specified managed object definition.
+ *
+ * @param <CC>
+ * The type of client managed object configuration that
+ * this path will reference.
+ * @param <SS>
+ * The type of server managed object configuration that
+ * this path will reference.
+ * @param nd
+ * The new managed object definition.
+ * @return Returns a new managed object path which has the same
+ * structure as this path except that the final path element
+ * is associated with the specified managed object
+ * definition.
+ */
+ @SuppressWarnings("unchecked")
+ public <CC extends C, SS extends S> ManagedObjectPath<CC, SS> asSubType(
+ AbstractManagedObjectDefinition<CC, SS> nd) {
+ if (r instanceof InstantiableRelationDefinition) {
+ InstantiableRelationDefinition<? super C, ? super S> ir =
+ (InstantiableRelationDefinition<? super C, ? super S>) r;
+ if (elements.size() == 0) {
+ return parent().child(ir, nd, null);
+ } else {
+ return parent().child(ir, nd,
+ elements.get(elements.size() - 1).getName());
+ }
+ } else if (r instanceof OptionalRelationDefinition) {
+ OptionalRelationDefinition<? super C, ? super S> or =
+ (OptionalRelationDefinition<? super C, ? super S>) r;
+ return parent().child(or, nd);
+ } else {
+ SingletonRelationDefinition<? super C, ? super S> sr =
+ (SingletonRelationDefinition<? super C, ? super S>) r;
+ return parent().child(sr, nd);
+ }
+ }
+
+
+
+ /**
* Creates a new child managed object path beneath the provided
* parent path having the specified managed object definition.
*
@@ -804,7 +869,7 @@
if (obj == this) {
return true;
} else if (obj instanceof ManagedObjectPath) {
- ManagedObjectPath other = (ManagedObjectPath) obj;
+ ManagedObjectPath<?, ?> other = (ManagedObjectPath<?, ?>) obj;
return toString().equals(other.toString());
} else {
return false;
diff --git a/opends/src/server/org/opends/server/admin/PropertyDefinition.java b/opends/src/server/org/opends/server/admin/PropertyDefinition.java
index ad8ba9c..e26e465 100644
--- a/opends/src/server/org/opends/server/admin/PropertyDefinition.java
+++ b/opends/src/server/org/opends/server/admin/PropertyDefinition.java
@@ -417,7 +417,7 @@
if (this == o) {
return true;
} else if (o instanceof PropertyDefinition) {
- PropertyDefinition other = (PropertyDefinition) o;
+ PropertyDefinition<?> other = (PropertyDefinition<?>) o;
if (propertyName.equals(other.propertyName)) {
if (theClass.equals(other.theClass)) {
return true;
diff --git a/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java b/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java
index 02342af..b6fda04 100644
--- a/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java
+++ b/opends/src/server/org/opends/server/admin/PropertyDefinitionUsageBuilder.java
@@ -311,7 +311,7 @@
* {@inheritDoc}
*/
@Override
- public String visitUnknown(PropertyDefinition d, Void p)
+ public String visitUnknown(PropertyDefinition<?> d, Void p)
throws UnknownPropertyDefinitionException {
return "?";
}
diff --git a/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java b/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
index 86900db..b445037 100644
--- a/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
+++ b/opends/src/server/org/opends/server/admin/PropertyDefinitionVisitor.java
@@ -250,7 +250,7 @@
* Visitor implementations may optionally throw this
* exception.
*/
- public R visitUnknown(PropertyDefinition d, P p)
+ public R visitUnknown(PropertyDefinition<?> d, P p)
throws UnknownPropertyDefinitionException {
throw new UnknownPropertyDefinitionException(d, p);
}
diff --git a/opends/src/server/org/opends/server/admin/PropertyIsMandatoryException.java b/opends/src/server/org/opends/server/admin/PropertyIsMandatoryException.java
index 4f50373..8277da5 100644
--- a/opends/src/server/org/opends/server/admin/PropertyIsMandatoryException.java
+++ b/opends/src/server/org/opends/server/admin/PropertyIsMandatoryException.java
@@ -47,7 +47,7 @@
* @param d
* The property definition.
*/
- public PropertyIsMandatoryException(PropertyDefinition d) {
+ public PropertyIsMandatoryException(PropertyDefinition<?> d) {
super(d);
}
diff --git a/opends/src/server/org/opends/server/admin/PropertyIsReadOnlyException.java b/opends/src/server/org/opends/server/admin/PropertyIsReadOnlyException.java
index 530e07a..bec4e26 100644
--- a/opends/src/server/org/opends/server/admin/PropertyIsReadOnlyException.java
+++ b/opends/src/server/org/opends/server/admin/PropertyIsReadOnlyException.java
@@ -47,7 +47,7 @@
* @param d
* The property definition.
*/
- public PropertyIsReadOnlyException(PropertyDefinition d) {
+ public PropertyIsReadOnlyException(PropertyDefinition<?> d) {
super(d);
}
diff --git a/opends/src/server/org/opends/server/admin/PropertyIsSingleValuedException.java b/opends/src/server/org/opends/server/admin/PropertyIsSingleValuedException.java
index 283d3f3..c268b8f 100644
--- a/opends/src/server/org/opends/server/admin/PropertyIsSingleValuedException.java
+++ b/opends/src/server/org/opends/server/admin/PropertyIsSingleValuedException.java
@@ -48,7 +48,7 @@
* @param d
* The property definition.
*/
- public PropertyIsSingleValuedException(PropertyDefinition d) {
+ public PropertyIsSingleValuedException(PropertyDefinition<?> d) {
super(d);
}
diff --git a/opends/src/server/org/opends/server/admin/RelativeInheritedDefaultBehaviorProvider.java b/opends/src/server/org/opends/server/admin/RelativeInheritedDefaultBehaviorProvider.java
index ee9468a..0749254 100644
--- a/opends/src/server/org/opends/server/admin/RelativeInheritedDefaultBehaviorProvider.java
+++ b/opends/src/server/org/opends/server/admin/RelativeInheritedDefaultBehaviorProvider.java
@@ -118,7 +118,8 @@
* @return Returns the absolute path of the managed object
* containing the property which has the default values.
*/
- public ManagedObjectPath getManagedObjectPath(ManagedObjectPath path) {
+ public ManagedObjectPath<?, ?> getManagedObjectPath(
+ ManagedObjectPath<?, ?> path) {
return path.parent(offset);
}
diff --git a/opends/src/server/org/opends/server/admin/UnknownPropertyDefinitionException.java b/opends/src/server/org/opends/server/admin/UnknownPropertyDefinitionException.java
index e1bc233..668bf45 100644
--- a/opends/src/server/org/opends/server/admin/UnknownPropertyDefinitionException.java
+++ b/opends/src/server/org/opends/server/admin/UnknownPropertyDefinitionException.java
@@ -53,7 +53,7 @@
* @param p
* The visitor parameter if there was one.
*/
- public UnknownPropertyDefinitionException(PropertyDefinition d, Object p) {
+ public UnknownPropertyDefinitionException(PropertyDefinition<?> d, Object p) {
super(d);
this.parameter = p;
}
diff --git a/opends/src/server/org/opends/server/admin/client/ManagedObject.java b/opends/src/server/org/opends/server/admin/client/ManagedObject.java
index 63eaec6..e9d385d 100644
--- a/opends/src/server/org/opends/server/admin/client/ManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/client/ManagedObject.java
@@ -32,6 +32,8 @@
import java.util.Collection;
import java.util.SortedSet;
+import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.Configuration;
import org.opends.server.admin.DefaultBehaviorException;
import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.IllegalPropertyValueException;
@@ -84,11 +86,11 @@
* <li>or, an empty set of values, if there are no default values.
* </ul>
*
- * @param <C>
+ * @param <T>
* The type of client configuration represented by the client
* managed object.
*/
-public interface ManagedObject<C extends ConfigurationClient> extends
+public interface ManagedObject<T extends ConfigurationClient> extends
PropertyProvider {
/**
@@ -138,10 +140,13 @@
* Once the managed object has been configured it can be added to
* the server using the {@link #commit()} method.
*
- * @param <M>
+ * @param <C>
* The expected type of the child managed object
* configuration client.
- * @param <N>
+ * @param <S>
+ * The expected type of the child managed object
+ * server configuration.
+ * @param <CC>
* The actual type of the added managed object
* configuration client.
* @param r
@@ -163,9 +168,10 @@
* If the relation definition is not associated with this
* managed object's definition.
*/
- <M extends ConfigurationClient, N extends M> ManagedObject<N> createChild(
- InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
- String name, Collection<DefaultBehaviorException> exceptions)
+ <C extends ConfigurationClient, S extends Configuration, CC extends C>
+ ManagedObject<CC> createChild(InstantiableRelationDefinition<C, S> r,
+ ManagedObjectDefinition<CC, ? extends S> d, String name,
+ Collection<DefaultBehaviorException> exceptions)
throws IllegalManagedObjectNameException, IllegalArgumentException;
@@ -177,10 +183,13 @@
* Once the managed object has been configured it can be added to
* the server using the {@link #commit()} method.
*
- * @param <M>
+ * @param <C>
* The expected type of the child managed object
* configuration client.
- * @param <N>
+ * @param <S>
+ * The expected type of the child managed object
+ * server configuration.
+ * @param <CC>
* The actual type of the added managed object
* configuration client.
* @param r
@@ -198,8 +207,9 @@
* If the relation definition is not associated with this
* managed object's definition.
*/
- <M extends ConfigurationClient, N extends M> ManagedObject<N> createChild(
- OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
+ <C extends ConfigurationClient, S extends Configuration, CC extends C>
+ ManagedObject<CC> createChild(OptionalRelationDefinition<C, S> r,
+ ManagedObjectDefinition<CC, ? extends S> d,
Collection<DefaultBehaviorException> exceptions)
throws IllegalArgumentException;
@@ -208,10 +218,13 @@
/**
* Retrieve an instantiable child managed object.
*
- * @param <M>
+ * @param <C>
* The requested type of the child managed object
* configuration client.
- * @param d
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
* The instantiable relation definition.
* @param name
* The name of the child managed object.
@@ -239,9 +252,9 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
- InstantiableRelationDefinition<M, ?> d, String name)
- throws IllegalArgumentException, DefinitionDecodingException,
+ <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(InstantiableRelationDefinition<C, S> r,
+ String name) throws IllegalArgumentException, DefinitionDecodingException,
ManagedObjectDecodingException, ManagedObjectNotFoundException,
ConcurrentModificationException, AuthorizationException,
CommunicationException;
@@ -251,10 +264,13 @@
/**
* Retrieve an optional child managed object.
*
- * @param <M>
+ * @param <C>
* The requested type of the child managed object
* configuration client.
- * @param d
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
* The optional relation definition.
* @return Returns the optional child managed object.
* @throws IllegalArgumentException
@@ -280,21 +296,25 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
- OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
- DefinitionDecodingException, ManagedObjectDecodingException,
- ManagedObjectNotFoundException, ConcurrentModificationException,
- AuthorizationException, CommunicationException;
+ <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(OptionalRelationDefinition<C, S> r)
+ throws IllegalArgumentException, DefinitionDecodingException,
+ ManagedObjectDecodingException, ManagedObjectNotFoundException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException;
/**
* Retrieve a singleton child managed object.
*
- * @param <M>
+ * @param <C>
* The requested type of the child managed object
* configuration client.
- * @param d
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
* The singleton relation definition.
* @return Returns the singleton child managed object.
* @throws IllegalArgumentException
@@ -320,11 +340,12 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
- SingletonRelationDefinition<M, ?> d) throws IllegalArgumentException,
- DefinitionDecodingException, ManagedObjectDecodingException,
- ManagedObjectNotFoundException, ConcurrentModificationException,
- AuthorizationException, CommunicationException;
+ <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(SingletonRelationDefinition<C, S> r)
+ throws IllegalArgumentException, DefinitionDecodingException,
+ ManagedObjectDecodingException, ManagedObjectNotFoundException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException;
@@ -336,7 +357,7 @@
* @return Returns a client configuration view of this managed
* object.
*/
- C getConfiguration();
+ T getConfiguration();
@@ -346,7 +367,8 @@
* @return Returns the definition associated with this managed
* object.
*/
- ManagedObjectDefinition<C, ?> getManagedObjectDefinition();
+ ManagedObjectDefinition<T, ? extends Configuration>
+ getManagedObjectDefinition();
@@ -355,7 +377,7 @@
*
* @return Returns the path of this managed object.
*/
- ManagedObjectPath getManagedObjectPath();
+ ManagedObjectPath<T, ? extends Configuration> getManagedObjectPath();
@@ -365,9 +387,9 @@
* See the class description for more information about how the
* effective property value is derived.
*
- * @param <T>
+ * @param <P>
* The type of the property to be retrieved.
- * @param d
+ * @param pd
* The property to be retrieved.
* @return Returns the property's effective value, or
* <code>null</code> if there is no effective value
@@ -376,7 +398,7 @@
* If the property definition is not associated with this
* managed object's definition.
*/
- <T> T getPropertyValue(PropertyDefinition<T> d)
+ <P> P getPropertyValue(PropertyDefinition<P> pd)
throws IllegalArgumentException;
@@ -387,9 +409,9 @@
* See the class description for more information about how the
* effective property values are derived.
*
- * @param <T>
+ * @param <P>
* The type of the property to be retrieved.
- * @param d
+ * @param pd
* The property to be retrieved.
* @return Returns the property's effective values, or an empty set
* if there are no effective values defined.
@@ -397,7 +419,7 @@
* If the property definition is not associated with this
* managed object's definition.
*/
- <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> d)
+ <P> SortedSet<P> getPropertyValues(PropertyDefinition<P> pd)
throws IllegalArgumentException;
@@ -406,7 +428,13 @@
* Determines whether or not the optional managed object associated
* with the specified optional relations exists.
*
- * @param d
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
* The optional relation definition.
* @return Returns <code>true</code> if the optional managed
* object exists, <code>false</code> otherwise.
@@ -423,7 +451,8 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- boolean hasChild(OptionalRelationDefinition<?, ?> d)
+ <C extends ConfigurationClient, S extends Configuration>
+ boolean hasChild(OptionalRelationDefinition<C, S> r)
throws IllegalArgumentException, ConcurrentModificationException,
AuthorizationException, CommunicationException;
@@ -433,7 +462,13 @@
* Lists the child managed objects associated with the specified
* instantiable relation.
*
- * @param d
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
* The instantiable relation definition.
* @return Returns the names of the child managed objects.
* @throws IllegalArgumentException
@@ -450,7 +485,47 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- String[] listChildren(InstantiableRelationDefinition<?, ?> d)
+ <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(InstantiableRelationDefinition<C, S> r)
+ throws IllegalArgumentException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException;
+
+
+
+ /**
+ * Lists the child managed objects associated with the specified
+ * instantiable relation which are a sub-type of the specified
+ * managed object definition.
+ *
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
+ * The instantiable relation definition.
+ * @param d
+ * The managed object definition.
+ * @return Returns the names of the child managed objects which are
+ * a sub-type of the specified managed object definition.
+ * @throws IllegalArgumentException
+ * If the relation definition is not associated with this
+ * managed object's definition.
+ * @throws ConcurrentModificationException
+ * If this managed object has been removed from the server
+ * by another client.
+ * @throws AuthorizationException
+ * If the server refuses to list the managed objects
+ * because the client does not have the correct
+ * privileges.
+ * @throws CommunicationException
+ * If the client cannot contact the server due to an
+ * underlying communication problem.
+ */
+ <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(InstantiableRelationDefinition<C, S> r,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
throws IllegalArgumentException, ConcurrentModificationException,
AuthorizationException, CommunicationException;
@@ -459,10 +534,13 @@
/**
* Removes the named instantiable child managed object.
*
- * @param <M>
- * The type of the child managed object configuration
- * client.
- * @param d
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
* The instantiable relation definition.
* @param name
* The name of the child managed object to be removed.
@@ -488,8 +566,8 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- <M extends ConfigurationClient> void removeChild(
- InstantiableRelationDefinition<M, ?> d, String name)
+ <C extends ConfigurationClient, S extends Configuration>
+ void removeChild(InstantiableRelationDefinition<C, S> r, String name)
throws IllegalArgumentException, ManagedObjectNotFoundException,
OperationRejectedException, ConcurrentModificationException,
AuthorizationException, CommunicationException;
@@ -499,10 +577,13 @@
/**
* Removes an optional child managed object.
*
- * @param <M>
- * The type of the child managed object configuration
- * client.
- * @param d
+ * @param <C>
+ * The type of client managed object configuration that the
+ * relation definition refers to.
+ * @param <S>
+ * The type of server managed object configuration that the
+ * relation definition refers to.
+ * @param r
* The optional relation definition.
* @throws IllegalArgumentException
* If the relation definition is not associated with this
@@ -526,11 +607,11 @@
* If the client cannot contact the server due to an
* underlying communication problem.
*/
- <M extends ConfigurationClient> void removeChild(
- OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
- ManagedObjectNotFoundException, OperationRejectedException,
- ConcurrentModificationException, AuthorizationException,
- CommunicationException;
+ <C extends ConfigurationClient, S extends Configuration>
+ void removeChild(OptionalRelationDefinition<C, S> r)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ OperationRejectedException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException;
@@ -540,9 +621,9 @@
* See the class description for more information regarding pending
* values.
*
- * @param <T>
+ * @param <P>
* The type of the property to be modified.
- * @param d
+ * @param pd
* The property to be modified.
* @param value
* The new pending value for the property, or
@@ -560,7 +641,7 @@
* If the specified property definition is not associated
* with this managed object.
*/
- <T> void setPropertyValue(PropertyDefinition<T> d, T value)
+ <P> void setPropertyValue(PropertyDefinition<P> pd, P value)
throws IllegalPropertyValueException, PropertyIsReadOnlyException,
PropertyIsMandatoryException, IllegalArgumentException;
@@ -572,9 +653,9 @@
* See the class description for more information regarding pending
* values.
*
- * @param <T>
+ * @param <P>
* The type of the property to be modified.
- * @param d
+ * @param pd
* The property to be modified.
* @param values
* A non-<code>null</code> set of new pending values for
@@ -596,7 +677,7 @@
* If the specified property definition is not associated
* with this managed object.
*/
- <T> void setPropertyValues(PropertyDefinition<T> d, Collection<T> values)
+ <P> void setPropertyValues(PropertyDefinition<P> pd, Collection<P> values)
throws IllegalPropertyValueException, PropertyIsSingleValuedException,
PropertyIsReadOnlyException, PropertyIsMandatoryException,
IllegalArgumentException;
diff --git a/opends/src/server/org/opends/server/admin/client/PropertySet.java b/opends/src/server/org/opends/server/admin/client/PropertySet.java
index d4407ac..5bddcbd 100644
--- a/opends/src/server/org/opends/server/admin/client/PropertySet.java
+++ b/opends/src/server/org/opends/server/admin/client/PropertySet.java
@@ -220,7 +220,7 @@
}
// The properties.
- private final Map<PropertyDefinition, MyProperty> properties;
+ private final Map<PropertyDefinition<?>, MyProperty<?>> properties;
@@ -228,7 +228,7 @@
* Creates a new empty property set.
*/
public PropertySet() {
- this.properties = new HashMap<PropertyDefinition, MyProperty>();
+ this.properties = new HashMap<PropertyDefinition<?>, MyProperty<?>>();
}
@@ -286,7 +286,7 @@
throw new IllegalArgumentException("Unknown property " + d.getName());
}
- return properties.get(d);
+ return (Property<T>) properties.get(d);
}
@@ -445,7 +445,7 @@
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append('{');
- for (Map.Entry<PropertyDefinition, MyProperty> entry : properties
+ for (Map.Entry<PropertyDefinition<?>, MyProperty<?>> entry : properties
.entrySet()) {
builder.append(entry.getKey().getName());
builder.append('=');
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java b/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
index 9443bdf..23ff928 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/JNDIDirContextAdaptor.java
@@ -152,7 +152,7 @@
@Override
public void deleteSubtree(LdapName dn) throws NamingException {
// Delete the children first.
- for (LdapName child : listEntries(dn)) {
+ for (LdapName child : listEntries(dn, null)) {
deleteSubtree(child);
}
@@ -189,8 +189,12 @@
* {@inheritDoc}
*/
@Override
- public Collection<LdapName> listEntries(LdapName dn) throws NamingException {
- String filter = "(objectClass=*)";
+ public Collection<LdapName> listEntries(LdapName dn, String filter)
+ throws NamingException {
+ if (filter == null) {
+ filter = "(objectClass=*)";
+ }
+
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
index 7c34d15..35cd644 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPConnection.java
@@ -100,11 +100,14 @@
*
* @param dn
* The name of the entry to list.
+ * @param filter
+ * An LDAP filter string, or <code>null</code> indicating
+ * the default filter of <code>(objectclass=*)</code>.
* @return Returns the names of the children.
* @throws NamingException
* If an error occurred whilst listing the children.
*/
- public abstract Collection<LdapName> listEntries(LdapName dn)
+ public abstract Collection<LdapName> listEntries(LdapName dn, String filter)
throws NamingException;
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
index 0c7630f..ced5595 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -54,6 +54,7 @@
import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider;
import org.opends.server.admin.AbstractManagedObjectDefinition;
import org.opends.server.admin.AliasDefaultBehaviorProvider;
+import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.DefaultBehaviorException;
import org.opends.server.admin.DefaultBehaviorProviderVisitor;
@@ -98,12 +99,12 @@
/**
* A managed object bound to an LDAP connection.
*
- * @param <C>
+ * @param <T>
* The type of client configuration represented by the client
* managed object.
*/
-final class LDAPManagedObject<C extends ConfigurationClient> implements
- ManagedObject<C> {
+final class LDAPManagedObject<T extends ConfigurationClient> implements
+ ManagedObject<T> {
/**
* A default behavior visitor used for retrieving the default values
@@ -135,7 +136,7 @@
* decoded properly.
*/
public static <T> Collection<T> getDefaultValues(
- LDAPManagementContext context, ManagedObjectPath p,
+ LDAPManagementContext context, ManagedObjectPath<?, ?> p,
PropertyDefinition<T> pd, boolean isCreate)
throws DefaultBehaviorException {
DefaultValueFinder<T> v = new DefaultValueFinder<T>(context, p, isCreate);
@@ -153,10 +154,10 @@
private final boolean isCreate;
// The path of the managed object containing the first property.
- private final ManagedObjectPath firstPath;
+ private final ManagedObjectPath<?, ?> firstPath;
// The path of the managed object containing the next property.
- private ManagedObjectPath nextPath = null;
+ private ManagedObjectPath<?, ?> nextPath = null;
// The next property whose default values were required.
private PropertyDefinition<T> nextProperty = null;
@@ -165,7 +166,7 @@
// Private constructor.
private DefaultValueFinder(LDAPManagementContext context,
- ManagedObjectPath p, boolean isCreate) {
+ ManagedObjectPath<?, ?> p, boolean isCreate) {
this.context = context;
this.firstPath = p;
this.isCreate = isCreate;
@@ -248,7 +249,8 @@
// Find the default values for the next path/property.
- private Collection<T> find(ManagedObjectPath p, PropertyDefinition<T> pd)
+ private Collection<T> find(ManagedObjectPath<?, ?> p,
+ PropertyDefinition<T> pd)
throws DefaultBehaviorException {
this.nextPath = p;
this.nextProperty = pd;
@@ -403,10 +405,10 @@
// Determine the type of managed object associated with the named
// entry.
- private static <M extends ConfigurationClient>
- ManagedObjectDefinition<? extends M, ?> getEntryDefinition(
+ private static <M extends ConfigurationClient, N extends Configuration>
+ ManagedObjectDefinition<? extends M, ? extends N> getEntryDefinition(
final LDAPManagementContext context,
- AbstractManagedObjectDefinition<M, ?> d, LdapName dn)
+ AbstractManagedObjectDefinition<M, N> d, LdapName dn)
throws NamingException, DefinitionDecodingException {
Attributes attributes = context.getLDAPConnection().readEntry(dn,
Collections.singleton("objectclass"));
@@ -449,7 +451,7 @@
// The managed object definition associated with this managed
// object.
- private final ManagedObjectDefinition<C, ?> definition;
+ private final ManagedObjectDefinition<T, ? extends Configuration> definition;
// Indicates whether or not this managed object exists on the server
// (false means the managed object is new and has not been
@@ -460,7 +462,7 @@
private final PropertyDefinition<?> namingPropertyDefinition;
// The path associated with this managed object.
- private ManagedObjectPath<?, ?> path;
+ private ManagedObjectPath<T, ? extends Configuration> path;
// The managed object's properties.
private final PropertySet properties;
@@ -469,7 +471,8 @@
// Create an new LDAP managed object with the provided JNDI context.
private LDAPManagedObject(LDAPManagementContext context,
- ManagedObjectDefinition<C, ?> d, ManagedObjectPath path,
+ ManagedObjectDefinition<T, ? extends Configuration> d,
+ ManagedObjectPath<T, ? extends Configuration> path,
PropertySet properties, boolean existsOnServer,
PropertyDefinition<?> namingPropertyDefinition) {
this.definition = d;
@@ -518,10 +521,10 @@
/**
* {@inheritDoc}
*/
- public <M extends ConfigurationClient, N extends M>
- ManagedObject<N> createChild(
- InstantiableRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
- String name, Collection<DefaultBehaviorException> exceptions)
+ public <C extends ConfigurationClient, S extends Configuration, CC extends C>
+ ManagedObject<CC> createChild(InstantiableRelationDefinition<C, S> r,
+ ManagedObjectDefinition<CC, ? extends S> d, String name,
+ Collection<DefaultBehaviorException> exceptions)
throws IllegalManagedObjectNameException, IllegalArgumentException {
validateRelationDefinition(r);
@@ -541,7 +544,7 @@
}
}
- ManagedObjectPath childPath = path.child(r, name);
+ ManagedObjectPath<CC, ? extends S> childPath = path.child(r, d, name);
return createNewManagedObject(d, childPath, pd, name, exceptions);
}
@@ -550,14 +553,13 @@
/**
* {@inheritDoc}
*/
- @SuppressWarnings("unchecked")
- public <M extends ConfigurationClient, N extends M>
- ManagedObject<N> createChild(
- OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
+ public <C extends ConfigurationClient, S extends Configuration, CC extends C>
+ ManagedObject<CC> createChild(OptionalRelationDefinition<C, S> r,
+ ManagedObjectDefinition<CC, ? extends S> d,
Collection<DefaultBehaviorException> exceptions)
throws IllegalArgumentException {
validateRelationDefinition(r);
- ManagedObjectPath childPath = path.child(r);
+ ManagedObjectPath<CC, ? extends S> childPath = path.child(r, d);
return createNewManagedObject(d, childPath, null, null, exceptions);
}
@@ -566,15 +568,31 @@
/**
* {@inheritDoc}
*/
- public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
- InstantiableRelationDefinition<M, ?> d, String name)
+ public <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(InstantiableRelationDefinition<C, S> r,
+ String name) throws IllegalArgumentException, DefinitionDecodingException,
+ ManagedObjectDecodingException, ManagedObjectNotFoundException,
+ ConcurrentModificationException, AuthorizationException,
+ CommunicationException {
+ validateRelationDefinition(r);
+ ensureThisManagedObjectExists();
+ return readManagedObject(r.getChildDefinition(), path.child(r, name));
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(OptionalRelationDefinition<C, S> r)
throws IllegalArgumentException, DefinitionDecodingException,
ManagedObjectDecodingException, ManagedObjectNotFoundException,
ConcurrentModificationException, AuthorizationException,
CommunicationException {
- validateRelationDefinition(d);
+ validateRelationDefinition(r);
ensureThisManagedObjectExists();
- return readManagedObject(d.getChildDefinition(), path.child(d, name));
+ return readManagedObject(r.getChildDefinition(), path.child(r));
}
@@ -582,14 +600,15 @@
/**
* {@inheritDoc}
*/
- public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
- OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
+ public <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> getChild(
+ SingletonRelationDefinition<C, S> r) throws IllegalArgumentException,
DefinitionDecodingException, ManagedObjectDecodingException,
ManagedObjectNotFoundException, ConcurrentModificationException,
AuthorizationException, CommunicationException {
- validateRelationDefinition(d);
+ validateRelationDefinition(r);
ensureThisManagedObjectExists();
- return readManagedObject(d.getChildDefinition(), path.child(d));
+ return readManagedObject(r.getChildDefinition(), path.child(r));
}
@@ -597,22 +616,7 @@
/**
* {@inheritDoc}
*/
- public <M extends ConfigurationClient> ManagedObject<? extends M> getChild(
- SingletonRelationDefinition<M, ?> d) throws IllegalArgumentException,
- DefinitionDecodingException, ManagedObjectDecodingException,
- ManagedObjectNotFoundException, ConcurrentModificationException,
- AuthorizationException, CommunicationException {
- validateRelationDefinition(d);
- ensureThisManagedObjectExists();
- return readManagedObject(d.getChildDefinition(), path.child(d));
- }
-
-
-
- /**
- * {@inheritDoc}
- */
- public C getConfiguration() {
+ public T getConfiguration() {
return definition.createClientConfiguration(this);
}
@@ -621,7 +625,8 @@
/**
* {@inheritDoc}
*/
- public ManagedObjectDefinition<C, ?> getManagedObjectDefinition() {
+ public ManagedObjectDefinition<T, ? extends Configuration>
+ getManagedObjectDefinition() {
return definition;
}
@@ -630,7 +635,7 @@
/**
* {@inheritDoc}
*/
- public ManagedObjectPath getManagedObjectPath() {
+ public ManagedObjectPath<T, ? extends Configuration> getManagedObjectPath() {
return path;
}
@@ -639,9 +644,9 @@
/**
* {@inheritDoc}
*/
- public <T> T getPropertyValue(PropertyDefinition<T> d)
+ public <P> P getPropertyValue(PropertyDefinition<P> pd)
throws IllegalArgumentException {
- return properties.getPropertyValue(d);
+ return properties.getPropertyValue(pd);
}
@@ -649,9 +654,9 @@
/**
* {@inheritDoc}
*/
- public <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> d)
+ public <P> SortedSet<P> getPropertyValues(PropertyDefinition<P> pd)
throws IllegalArgumentException {
- return properties.getPropertyValues(d);
+ return properties.getPropertyValues(pd);
}
@@ -659,13 +664,14 @@
/**
* {@inheritDoc}
*/
- public boolean hasChild(OptionalRelationDefinition<?, ?> d)
+ public <C extends ConfigurationClient, S extends Configuration>
+ boolean hasChild(OptionalRelationDefinition<C, S> r)
throws IllegalArgumentException, ConcurrentModificationException,
AuthorizationException, CommunicationException {
- validateRelationDefinition(d);
+ validateRelationDefinition(r);
ensureThisManagedObjectExists();
- ManagedObjectPath p = path.child(d);
+ ManagedObjectPath<C, S> p = path.child(r);
LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
return entryExists(dn);
}
@@ -675,16 +681,41 @@
/**
* {@inheritDoc}
*/
- public String[] listChildren(InstantiableRelationDefinition<?, ?> d)
+ public <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(InstantiableRelationDefinition<C, S> r)
throws IllegalArgumentException, ConcurrentModificationException,
AuthorizationException, CommunicationException {
- validateRelationDefinition(d);
+ return listChildren(r, r.getChildDefinition());
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public <C extends ConfigurationClient, S extends Configuration>
+ String[] listChildren(InstantiableRelationDefinition<C, S> r,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws IllegalArgumentException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(r);
ensureThisManagedObjectExists();
+ // Get the search base DN.
+ LdapName dn = LDAPNameBuilder.create(path, r, context.getLDAPProfile());
+
+ // Retrieve only those entries which are sub-types of the
+ // specified definition.
+ StringBuilder builder = new StringBuilder();
+ builder.append("(objectclass=");
+ builder.append(context.getLDAPProfile().getObjectClass(d));
+ builder.append(')');
+ String filter = builder.toString();
+
List<String> children = new ArrayList<String>();
- LdapName dn = LDAPNameBuilder.create(path, d, context.getLDAPProfile());
try {
- for (LdapName child : context.getLDAPConnection().listEntries(dn)) {
+ for (LdapName child :
+ context.getLDAPConnection().listEntries(dn, filter)) {
children.add(child.getRdn(child.size() - 1).getValue().toString());
}
} catch (NameNotFoundException e) {
@@ -702,14 +733,14 @@
/**
* {@inheritDoc}
*/
- public <M extends ConfigurationClient> void removeChild(
- InstantiableRelationDefinition<M, ?> d, String name)
+ public <C extends ConfigurationClient, S extends Configuration>
+ void removeChild(InstantiableRelationDefinition<C, S> r, String name)
throws IllegalArgumentException, ManagedObjectNotFoundException,
OperationRejectedException, ConcurrentModificationException,
AuthorizationException, CommunicationException {
- validateRelationDefinition(d);
+ validateRelationDefinition(r);
ensureThisManagedObjectExists();
- ManagedObjectPath p = path.child(d, name);
+ ManagedObjectPath<C, S> p = path.child(r, name);
removeManagedObject(p);
}
@@ -718,14 +749,14 @@
/**
* {@inheritDoc}
*/
- public <M extends ConfigurationClient> void removeChild(
- OptionalRelationDefinition<M, ?> d) throws IllegalArgumentException,
- ManagedObjectNotFoundException, OperationRejectedException,
- ConcurrentModificationException, AuthorizationException,
- CommunicationException {
- validateRelationDefinition(d);
+ public <C extends ConfigurationClient, S extends Configuration>
+ void removeChild(OptionalRelationDefinition<C, S> r)
+ throws IllegalArgumentException, ManagedObjectNotFoundException,
+ OperationRejectedException, ConcurrentModificationException,
+ AuthorizationException, CommunicationException {
+ validateRelationDefinition(r);
ensureThisManagedObjectExists();
- ManagedObjectPath p = path.child(d);
+ ManagedObjectPath<C, S> p = path.child(r);
removeManagedObject(p);
}
@@ -734,13 +765,13 @@
/**
* {@inheritDoc}
*/
- public <T> void setPropertyValue(PropertyDefinition<T> d, T value)
+ public <P> void setPropertyValue(PropertyDefinition<P> pd, P value)
throws IllegalPropertyValueException, PropertyIsReadOnlyException,
PropertyIsMandatoryException, IllegalArgumentException {
if (value == null) {
- setPropertyValues(d, Collections.<T> emptySet());
+ setPropertyValues(pd, Collections.<P> emptySet());
} else {
- setPropertyValues(d, Collections.singleton(value));
+ setPropertyValues(pd, Collections.singleton(value));
}
}
@@ -749,24 +780,24 @@
/**
* {@inheritDoc}
*/
- public <T> void setPropertyValues(PropertyDefinition<T> d,
- Collection<T> values) throws IllegalPropertyValueException,
+ public <P> void setPropertyValues(PropertyDefinition<P> pd,
+ Collection<P> values) throws IllegalPropertyValueException,
PropertyIsSingleValuedException, PropertyIsReadOnlyException,
PropertyIsMandatoryException, IllegalArgumentException {
- if (d.hasOption(PropertyOption.MONITORING)) {
- throw new PropertyIsReadOnlyException(d);
+ if (pd.hasOption(PropertyOption.MONITORING)) {
+ throw new PropertyIsReadOnlyException(pd);
}
- if (existsOnServer && d.hasOption(PropertyOption.READ_ONLY)) {
- throw new PropertyIsReadOnlyException(d);
+ if (existsOnServer && pd.hasOption(PropertyOption.READ_ONLY)) {
+ throw new PropertyIsReadOnlyException(pd);
}
- properties.setPropertyValues(d, values);
+ properties.setPropertyValues(pd, values);
// If this is a naming property then update the name.
- if (d.equals(namingPropertyDefinition)) {
+ if (pd.equals(namingPropertyDefinition)) {
// The property must be single-valued and mandatory.
- String newName = d.encodeValue(values.iterator().next());
+ String newName = pd.encodeValue(values.iterator().next());
path = path.rename(newName);
}
}
@@ -933,28 +964,29 @@
// Create a managed object which already exists on the server.
- private <M extends ConfigurationClient>
+ private <M extends ConfigurationClient, N extends Configuration>
ManagedObject<M> createExistingManagedObject(
- ManagedObjectDefinition<M, ?> d, ManagedObjectPath p,
- PropertySet properties) {
+ ManagedObjectDefinition<M, N> d,
+ ManagedObjectPath<? super M, ? super N> p, PropertySet properties) {
RelationDefinition<?, ?> rd = p.getRelationDefinition();
PropertyDefinition<?> pd = null;
if (rd instanceof InstantiableRelationDefinition) {
InstantiableRelationDefinition<?, ?> ird =
- (InstantiableRelationDefinition) rd;
+ (InstantiableRelationDefinition<?, ?>) rd;
pd = ird.getNamingPropertyDefinition();
}
- return new LDAPManagedObject<M>(context, d, p, properties, true, pd);
+ return new LDAPManagedObject<M>(context, d, p.asSubType(d), properties,
+ true, pd);
}
// Creates a new managed object with no active values, just default
// values.
- private <M extends ConfigurationClient, T>
+ private <M extends ConfigurationClient, P>
ManagedObject<M> createNewManagedObject(
- ManagedObjectDefinition<M, ?> d, ManagedObjectPath p,
- PropertyDefinition<T> namingPropertyDefinition, String name,
+ ManagedObjectDefinition<M, ?> d, ManagedObjectPath<M, ?> p,
+ PropertyDefinition<P> namingPropertyDefinition, String name,
Collection<DefaultBehaviorException> exceptions) {
PropertySet childProperties = new PropertySet();
for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) {
@@ -970,7 +1002,7 @@
// Set the naming property if there is one.
if (namingPropertyDefinition != null) {
- T value = namingPropertyDefinition.decodeValue(name);
+ P value = namingPropertyDefinition.decodeValue(name);
childProperties.setPropertyValue(namingPropertyDefinition, value);
}
@@ -981,16 +1013,17 @@
// Create an empty property.
- private <T> void createProperty(PropertySet properties, ManagedObjectPath p,
- PropertyDefinition<T> pd) throws DefaultBehaviorException {
+ private <P> void createProperty(PropertySet properties,
+ ManagedObjectPath<?, ?> p, PropertyDefinition<P> pd)
+ throws DefaultBehaviorException {
try {
- Collection<T> defaultValues = DefaultValueFinder.getDefaultValues(
+ Collection<P> defaultValues = DefaultValueFinder.getDefaultValues(
context, p, pd, true);
- properties.addProperty(pd, defaultValues, Collections.<T> emptySet());
+ properties.addProperty(pd, defaultValues, Collections.<P> emptySet());
} catch (DefaultBehaviorException e) {
// Make sure that we have still created the property.
- properties.addProperty(pd, Collections.<T> emptySet(), Collections
- .<T> emptySet());
+ properties.addProperty(pd, Collections.<P> emptySet(), Collections
+ .<P> emptySet());
throw e;
}
}
@@ -998,13 +1031,13 @@
// Create a property using the provided string values.
- private <T> void decodeProperty(PropertySet newProperties,
- ManagedObjectPath p, PropertyDefinition<T> pd, List<String> values)
+ private <P> void decodeProperty(PropertySet newProperties,
+ ManagedObjectPath<?, ?> p, PropertyDefinition<P> pd, List<String> values)
throws PropertyException {
PropertyException exception = null;
// Get the property's active values.
- Collection<T> activeValues = new ArrayList<T>(values.size());
+ Collection<P> activeValues = new ArrayList<P>(values.size());
for (String value : values) {
try {
activeValues.add(pd.decodeValue(value));
@@ -1016,7 +1049,7 @@
if (activeValues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
// This exception takes precedence over previous exceptions.
exception = new PropertyIsSingleValuedException(pd);
- T value = activeValues.iterator().next();
+ P value = activeValues.iterator().next();
activeValues.clear();
activeValues.add(value);
}
@@ -1029,7 +1062,7 @@
}
// Get the property's default values.
- Collection<T> defaultValues;
+ Collection<P> defaultValues;
try {
defaultValues = DefaultValueFinder.getDefaultValues(context, p, pd,
false);
@@ -1047,18 +1080,18 @@
// Encode a property into LDAP string values.
- private <T> void encodeProperty(Attribute attribute,
- PropertyDefinition<T> pd, PropertySet properties) {
- Property<T> p = properties.getProperty(pd);
+ private <P> void encodeProperty(Attribute attribute,
+ PropertyDefinition<P> pd, PropertySet properties) {
+ Property<P> p = properties.getProperty(pd);
if (pd.hasOption(PropertyOption.MANDATORY)) {
// For mandatory properties we fall-back to the default values
// if defined which can sometimes be the case e.g when a
// mandatory property is overridden.
- for (T value : p.getEffectiveValues()) {
+ for (P value : p.getEffectiveValues()) {
attribute.add(pd.encodeValue(value));
}
} else {
- for (T value : p.getPendingValues()) {
+ for (P value : p.getPendingValues()) {
attribute.add(pd.encodeValue(value));
}
}
@@ -1096,17 +1129,17 @@
// Read the entry identified by the path and which is a sub-type of
// the specified definition.
- private <M extends ConfigurationClient>
- ManagedObject<? extends M> readManagedObject(
- AbstractManagedObjectDefinition<M, ?> d, ManagedObjectPath p)
+ private <C extends ConfigurationClient, S extends Configuration>
+ ManagedObject<? extends C> readManagedObject(
+ AbstractManagedObjectDefinition<C, S> d, ManagedObjectPath<C, S> p)
throws DefinitionDecodingException, ManagedObjectDecodingException,
ManagedObjectNotFoundException, AuthorizationException,
CommunicationException {
try {
// Read the entry associated with the managed object.
LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
- ManagedObjectDefinition<? extends M, ?> mod = getEntryDefinition(context,
- d, dn);
+ ManagedObjectDefinition<? extends C, ? extends S> mod =
+ getEntryDefinition(context, d, dn);
ArrayList<String> attrIds = new ArrayList<String>();
for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
@@ -1144,9 +1177,8 @@
// If there were no decoding problems then return the object,
// otherwise throw an operations exception.
- ManagedObject<? extends M> mo = createExistingManagedObject(mod, p,
+ ManagedObject<? extends C> mo = createExistingManagedObject(mod, p,
newProperties);
-
if (exceptions.isEmpty()) {
return mo;
} else {
@@ -1164,7 +1196,7 @@
// Remove the named managed object.
- private void removeManagedObject(ManagedObjectPath p)
+ private void removeManagedObject(ManagedObjectPath<?, ?> p)
throws CommunicationException, AuthorizationException,
OperationRejectedException, ManagedObjectNotFoundException {
LdapName dn = LDAPNameBuilder.create(p, context.getLDAPProfile());
@@ -1189,8 +1221,8 @@
// object.
private void validateRelationDefinition(RelationDefinition<?, ?> rd)
throws IllegalArgumentException {
- ManagedObjectDefinition d = getManagedObjectDefinition();
- RelationDefinition tmp = d.getRelationDefinition(rd.getName());
+ ManagedObjectDefinition<T, ?> d = getManagedObjectDefinition();
+ RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName());
if (tmp != rd) {
throw new IllegalArgumentException("The relation " + rd.getName()
+ " is not associated with a " + d.getName());
diff --git a/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java b/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
index 167b988..431a4e9 100644
--- a/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
+++ b/opends/src/server/org/opends/server/admin/client/ldap/LDAPNameBuilder.java
@@ -65,7 +65,8 @@
* @return Returns a new LDAP name representing the specified
* managed object path.
*/
- public static LdapName create(ManagedObjectPath path, LDAPProfile profile) {
+ public static LdapName create(ManagedObjectPath<?, ?> path,
+ LDAPProfile profile) {
LDAPNameBuilder builder = new LDAPNameBuilder(profile);
path.serialize(builder);
return builder.getInstance();
@@ -87,7 +88,7 @@
* @return Returns a new LDAP name representing the specified
* managed object path and instantiable relation.
*/
- public static LdapName create(ManagedObjectPath path,
+ public static LdapName create(ManagedObjectPath<?, ?> path,
InstantiableRelationDefinition<?, ?> relation, LDAPProfile profile) {
LDAPNameBuilder builder = new LDAPNameBuilder(profile);
path.serialize(builder);
@@ -125,7 +126,7 @@
InstantiableRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d, String name) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition) r);
+ appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
// Now add the single RDN representing the named instance.
String type = profile.getInstantiableRelationChildRDNType(r);
@@ -167,7 +168,7 @@
OptionalRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition) r);
+ appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
}
@@ -180,7 +181,7 @@
SingletonRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition) r);
+ appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
}
diff --git a/opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java b/opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
index d4d3c33..b762abe 100644
--- a/opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
+++ b/opends/src/server/org/opends/server/admin/server/ConfigAddListenerAdaptor.java
@@ -85,7 +85,7 @@
* @param listener
* The underlying add listener.
*/
- public ConfigAddListenerAdaptor(ManagedObjectPath path,
+ public ConfigAddListenerAdaptor(ManagedObjectPath<?, ?> path,
InstantiableRelationDefinition<?, S> relation,
ConfigurationAddListener<S> listener) {
this.path = path;
@@ -108,7 +108,7 @@
* @param listener
* The underlying add listener.
*/
- public ConfigAddListenerAdaptor(ManagedObjectPath path,
+ public ConfigAddListenerAdaptor(ManagedObjectPath<?, ?> path,
OptionalRelationDefinition<?, S> relation,
ConfigurationAddListener<S> listener) {
this.path = path;
@@ -129,7 +129,7 @@
// Optional managed objects are located directly beneath the
// parent and have a well-defined name. We need to make sure
// that we are handling the correct entry.
- ManagedObjectPath childPath = path.child(optionalRelation);
+ ManagedObjectPath<?, ?> childPath = path.child(optionalRelation);
DN expectedDN = DNBuilder.create(childPath);
if (!configEntry.getDN().equals(expectedDN)) {
// Doesn't apply to us.
@@ -153,7 +153,7 @@
AttributeValue av = dn.getRDN().getAttributeValue(0);
String name = av.getStringValue().trim();
- ManagedObjectPath childPath;
+ ManagedObjectPath<?, ?> childPath;
RelationDefinition<?, S> r;
if (instantiableRelation != null) {
childPath = path.child(instantiableRelation, name);
diff --git a/opends/src/server/org/opends/server/admin/server/ConfigChangeListenerAdaptor.java b/opends/src/server/org/opends/server/admin/server/ConfigChangeListenerAdaptor.java
index 58ae50a..71047d6 100644
--- a/opends/src/server/org/opends/server/admin/server/ConfigChangeListenerAdaptor.java
+++ b/opends/src/server/org/opends/server/admin/server/ConfigChangeListenerAdaptor.java
@@ -85,7 +85,7 @@
* The type of property.
*/
private static final class Visitor<T> implements
- DefaultBehaviorProviderVisitor<T, Void, ManagedObjectPath> {
+ DefaultBehaviorProviderVisitor<T, Void, ManagedObjectPath<?, ?>> {
/**
* Finds the dependencies associated with the provided property
@@ -100,7 +100,7 @@
* @param dependencies
* Add dependencies names to this collection.
*/
- public static <T> void find(ManagedObjectPath path,
+ public static <T> void find(ManagedObjectPath<?, ?> path,
PropertyDefinition<T> pd, Collection<DN> dependencies) {
Visitor<T> v = new Visitor<T>(dependencies);
DefaultBehaviorProvider<T> db = pd.getDefaultBehaviorProvider();
@@ -123,8 +123,9 @@
* {@inheritDoc}
*/
public Void visitAbsoluteInherited(
- AbsoluteInheritedDefaultBehaviorProvider<T> d, ManagedObjectPath p) {
- ManagedObjectPath next = d.getManagedObjectPath();
+ AbsoluteInheritedDefaultBehaviorProvider<T> d,
+ ManagedObjectPath<?, ?> p) {
+ ManagedObjectPath<?, ?> next = d.getManagedObjectPath();
dependencies.add(DNBuilder.create(next));
// If the dependent property uses inherited defaults then
@@ -144,7 +145,7 @@
* {@inheritDoc}
*/
public Void visitAlias(AliasDefaultBehaviorProvider<T> d,
- ManagedObjectPath p) {
+ ManagedObjectPath<?, ?> p) {
return null;
}
@@ -154,7 +155,7 @@
* {@inheritDoc}
*/
public Void visitDefined(DefinedDefaultBehaviorProvider<T> d,
- ManagedObjectPath p) {
+ ManagedObjectPath<?, ?> p) {
return null;
}
@@ -164,8 +165,9 @@
* {@inheritDoc}
*/
public Void visitRelativeInherited(
- RelativeInheritedDefaultBehaviorProvider<T> d, ManagedObjectPath p) {
- ManagedObjectPath next = d.getManagedObjectPath(p);
+ RelativeInheritedDefaultBehaviorProvider<T> d,
+ ManagedObjectPath<?, ?> p) {
+ ManagedObjectPath<?, ?> next = d.getManagedObjectPath(p);
dependencies.add(DNBuilder.create(next));
// If the dependent property uses inherited defaults then
@@ -185,7 +187,7 @@
* {@inheritDoc}
*/
public Void visitUndefined(UndefinedDefaultBehaviorProvider<T> d,
- ManagedObjectPath p) {
+ ManagedObjectPath<?, ?> p) {
return null;
}
}
@@ -215,7 +217,7 @@
private final ConfigurationChangeListener<? super S> listener;
// The managed object path.
- private final ManagedObjectPath path;
+ private final ManagedObjectPath<?, ?> path;
@@ -229,7 +231,7 @@
* @param listener
* The underlying change listener.
*/
- public ConfigChangeListenerAdaptor(ManagedObjectPath path,
+ public ConfigChangeListenerAdaptor(ManagedObjectPath<?, ?> path,
AbstractManagedObjectDefinition<?, S> d,
ConfigurationChangeListener<? super S> listener) {
this.path = path;
diff --git a/opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java b/opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
index 8abd474..04c2646 100644
--- a/opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
+++ b/opends/src/server/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java
@@ -87,7 +87,7 @@
* @param listener
* The underlying delete listener.
*/
- public ConfigDeleteListenerAdaptor(ManagedObjectPath path,
+ public ConfigDeleteListenerAdaptor(ManagedObjectPath<?, ?> path,
InstantiableRelationDefinition<?, S> relation,
ConfigurationDeleteListener<S> listener) {
this.path = path;
@@ -110,7 +110,7 @@
* @param listener
* The underlying delete listener.
*/
- public ConfigDeleteListenerAdaptor(ManagedObjectPath path,
+ public ConfigDeleteListenerAdaptor(ManagedObjectPath<?, ?> path,
OptionalRelationDefinition<?, S> relation,
ConfigurationDeleteListener<S> listener) {
this.path = path;
@@ -131,7 +131,7 @@
// Optional managed objects are located directly beneath the
// parent and have a well-defined name. We need to make sure
// that we are handling the correct entry.
- ManagedObjectPath childPath = path.child(optionalRelation);
+ ManagedObjectPath<?, ?> childPath = path.child(optionalRelation);
DN expectedDN = DNBuilder.create(childPath);
if (!configEntry.getDN().equals(expectedDN)) {
// Doesn't apply to us.
@@ -155,7 +155,7 @@
AttributeValue av = dn.getRDN().getAttributeValue(0);
String name = av.getStringValue().trim();
- ManagedObjectPath childPath;
+ ManagedObjectPath<?, ?> childPath;
RelationDefinition<?, S> r;
if (instantiableRelation != null) {
childPath = path.child(instantiableRelation, name);
@@ -197,10 +197,10 @@
/**
- * Get the configuiration delete listener associated with this
+ * Get the configuration delete listener associated with this
* adaptor.
*
- * @return Returns the configuiration delete listener associated
+ * @return Returns the configuration delete listener associated
* with this adaptor.
*/
ConfigurationDeleteListener<S> getConfigurationDeleteListener() {
diff --git a/opends/src/server/org/opends/server/admin/server/DNBuilder.java b/opends/src/server/org/opends/server/admin/server/DNBuilder.java
index 118ec71..35c62cd 100644
--- a/opends/src/server/org/opends/server/admin/server/DNBuilder.java
+++ b/opends/src/server/org/opends/server/admin/server/DNBuilder.java
@@ -60,7 +60,7 @@
* The managed object path.
* @return Returns a new DN representing the specified managed object path.
*/
- public static DN create(ManagedObjectPath path) {
+ public static DN create(ManagedObjectPath<?, ?> path) {
DNBuilder builder = new DNBuilder();
path.serialize(builder);
return builder.getInstance();
@@ -79,7 +79,7 @@
* @return Returns a new DN representing the specified managed
* object path and relation.
*/
- public static DN create(ManagedObjectPath path,
+ public static DN create(ManagedObjectPath<?, ?> path,
RelationDefinition<?, ?> relation) {
DNBuilder builder = new DNBuilder();
path.serialize(builder);
@@ -113,7 +113,7 @@
InstantiableRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d, String name) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition) r);
+ appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
// Now add the single RDN representing the named instance.
String type = profile.getInstantiableRelationChildRDNType(r);
@@ -151,7 +151,7 @@
OptionalRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition) r);
+ appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
}
@@ -164,7 +164,7 @@
SingletonRelationDefinition<? super C, ? super S> r,
AbstractManagedObjectDefinition<C, S> d) {
// Add the RDN sequence representing the relation.
- appendManagedObjectPathElement((RelationDefinition) r);
+ appendManagedObjectPathElement((RelationDefinition<?, ?>) r);
}
diff --git a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
index ed9e19a..ff01987 100644
--- a/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
+++ b/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
@@ -128,7 +128,7 @@
* If the default values could not be retrieved or
* decoded properly.
*/
- public static <T> Collection<T> getDefaultValues(ManagedObjectPath p,
+ public static <T> Collection<T> getDefaultValues(ManagedObjectPath<?, ?> p,
PropertyDefinition<T> pd, ConfigEntry newConfigEntry)
throws DefaultBehaviorException {
DefaultValueFinder<T> v = new DefaultValueFinder<T>(newConfigEntry);
@@ -140,7 +140,7 @@
private DefaultBehaviorException exception = null;
// The path of the managed object containing the next property.
- private ManagedObjectPath nextPath = null;
+ private ManagedObjectPath<?, ?> nextPath = null;
// The next property whose default values were required.
private PropertyDefinition<T> nextProperty = null;
@@ -232,8 +232,8 @@
// Find the default values for the next path/property.
- private Collection<T> find(ManagedObjectPath p, PropertyDefinition<T> pd)
- throws DefaultBehaviorException {
+ private Collection<T> find(ManagedObjectPath<?, ?> p,
+ PropertyDefinition<T> pd) throws DefaultBehaviorException {
nextPath = p;
nextProperty = pd;
@@ -393,7 +393,8 @@
* not be decoded.
*/
static <S extends Configuration> ServerManagedObject<? extends S> decode(
- ManagedObjectPath path, AbstractManagedObjectDefinition<?, S> definition,
+ ManagedObjectPath<?, ?> path,
+ AbstractManagedObjectDefinition<?, S> definition,
ConfigEntry configEntry) throws DefinitionDecodingException,
ServerManagedObjectDecodingException {
return decode(path, definition, configEntry, null);
@@ -427,7 +428,8 @@
* not be decoded.
*/
static <S extends Configuration> ServerManagedObject<? extends S> decode(
- ManagedObjectPath path, AbstractManagedObjectDefinition<?, S> definition,
+ ManagedObjectPath<?, ?> path,
+ AbstractManagedObjectDefinition<?, S> definition,
ConfigEntry configEntry, ConfigEntry newConfigEntry)
throws DefinitionDecodingException, ServerManagedObjectDecodingException {
// First determine the correct definition to use for the entry.
@@ -476,7 +478,7 @@
// Decode helper method required to avoid generics warning.
private static <S extends Configuration> ServerManagedObject<S> decodeAux(
- ManagedObjectPath path, ManagedObjectDefinition<?, S> d,
+ ManagedObjectPath<?, ?> path, ManagedObjectDefinition<?, S> d,
Map<PropertyDefinition<?>, SortedSet<?>> properties,
ConfigEntry configEntry) {
return new ServerManagedObject<S>(path, d, properties, configEntry);
@@ -487,7 +489,7 @@
// Create a property using the provided string values.
private static <T> void decodeProperty(
Map<PropertyDefinition<?>, SortedSet<?>> properties,
- ManagedObjectPath path, PropertyDefinition<T> pd,
+ ManagedObjectPath<?, ?> path, PropertyDefinition<T> pd,
List<String> stringValues, ConfigEntry newConfigEntry)
throws PropertyException {
PropertyException exception = null;
@@ -611,7 +613,7 @@
// Create an new server side managed object.
- private ServerManagedObject(ManagedObjectPath path,
+ private ServerManagedObject(ManagedObjectPath<?, ?> path,
ManagedObjectDefinition<?, S> d,
Map<PropertyDefinition<?>, SortedSet<?>> properties,
ConfigEntry configEntry) {
@@ -681,7 +683,8 @@
ConfigurationChangeListener<? super S> listener) {
for (ConfigChangeListener l : configEntry.getChangeListeners()) {
if (l instanceof ConfigChangeListenerAdaptor) {
- ConfigChangeListenerAdaptor adaptor = (ConfigChangeListenerAdaptor) l;
+ ConfigChangeListenerAdaptor<?> adaptor =
+ (ConfigChangeListenerAdaptor<?>) l;
if (adaptor.getConfigurationChangeListener() == listener) {
configEntry.deregisterChangeListener(adaptor);
}
@@ -761,7 +764,7 @@
InstantiableRelationDefinition<?, M> d, String name)
throws IllegalArgumentException, ConfigException {
validateRelationDefinition(d);
- ManagedObjectPath childPath = path.child(d, name);
+ ManagedObjectPath<?, ?> childPath = path.child(d, name);
return getChild(childPath, d);
}
@@ -787,7 +790,7 @@
OptionalRelationDefinition<?, M> d) throws IllegalArgumentException,
ConfigException {
validateRelationDefinition(d);
- ManagedObjectPath childPath = path.child(d);
+ ManagedObjectPath<?, ?> childPath = path.child(d);
return getChild(childPath, d);
}
@@ -813,7 +816,7 @@
SingletonRelationDefinition<?, M> d) throws IllegalArgumentException,
ConfigException {
validateRelationDefinition(d);
- ManagedObjectPath childPath = path.child(d);
+ ManagedObjectPath<?, ?> childPath = path.child(d);
return getChild(childPath, d);
}
@@ -866,7 +869,7 @@
*
* @return Returns the path of this server managed object.
*/
- public ManagedObjectPath getManagedObjectPath() {
+ public ManagedObjectPath<?, ?> getManagedObjectPath() {
return path;
}
@@ -1159,7 +1162,8 @@
if (configEntry != null) {
for (ConfigAddListener l : configEntry.getAddListeners()) {
if (l instanceof ConfigAddListenerAdaptor) {
- ConfigAddListenerAdaptor adaptor = (ConfigAddListenerAdaptor) l;
+ ConfigAddListenerAdaptor<?> adaptor =
+ (ConfigAddListenerAdaptor<?>) l;
if (adaptor.getConfigurationAddListener() == listener) {
configEntry.deregisterAddListener(adaptor);
}
@@ -1184,8 +1188,8 @@
if (configEntry != null) {
for (ConfigDeleteListener l : configEntry.getDeleteListeners()) {
if (l instanceof ConfigDeleteListenerAdaptor) {
- ConfigDeleteListenerAdaptor adaptor =
- (ConfigDeleteListenerAdaptor) l;
+ ConfigDeleteListenerAdaptor<?> adaptor =
+ (ConfigDeleteListenerAdaptor<?>) l;
if (adaptor.getConfigurationDeleteListener() == listener) {
configEntry.deregisterDeleteListener(adaptor);
}
@@ -1204,7 +1208,7 @@
// Get a child managed object.
private <M extends Configuration> ServerManagedObject<? extends M> getChild(
- ManagedObjectPath childPath, RelationDefinition<?, M> d)
+ ManagedObjectPath<?, ?> childPath, RelationDefinition<?, M> d)
throws ConfigException {
// Get the configuration entry.
DN targetDN = DNBuilder.create(childPath);
@@ -1310,7 +1314,8 @@
// object.
private void validateRelationDefinition(RelationDefinition<?, ?> rd)
throws IllegalArgumentException {
- RelationDefinition tmp = definition.getRelationDefinition(rd.getName());
+ RelationDefinition<?, ?> tmp =
+ definition.getRelationDefinition(rd.getName());
if (tmp != rd) {
throw new IllegalArgumentException("The relation " + rd.getName()
+ " is not associated with a " + definition.getName());
diff --git a/opends/src/server/org/opends/server/messages/ToolMessages.java b/opends/src/server/org/opends/server/messages/ToolMessages.java
index 9c298a5..ce41e5e 100644
--- a/opends/src/server/org/opends/server/messages/ToolMessages.java
+++ b/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -9231,6 +9231,151 @@
public static final int MSGID_REVERT_DESCRIPTION_SILENT =
CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1222;
+ /**
+ * The message ID for the message which should be used when an
+ * argument, which is mandatory when the application is
+ * non-interactive, has not been specified. This takes a
+ * single arguments which is the long name of the missing argument.
+ */
+ public static final int MSGID_DSCFG_ERROR_MISSING_NON_INTERACTIVE_ARG =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1223;
+
+ /**
+ * The message ID for the message that will be used if dsconfig cannot
+ * read input from the console. This takes a single argument, which
+ * is a message explaining the problem that occurred.
+ */
+ public static final int MSGID_DSCFG_ERROR_CANNOT_READ_CONSOLE_INPUT =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1224;
+
+ /**
+ * The message ID for the message that will be used as the prompt
+ * for the type of component to be created when using the create-xxx
+ * sub-command interactively. This takes a single argument which is
+ * the user friendly name for the type of managed objects being
+ * created.
+ */
+ public static final int MSGID_DSCFG_CREATE_TYPE_PROMPT =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1225;
+
+ /**
+ * The message ID for the message that will be used as the prompt
+ * for the name of the component to be created when using the
+ * create-xxx sub-command interactively. This takes a single
+ * argument which is the user friendly name for the type of managed
+ * objects being created.
+ */
+ public static final int MSGID_DSCFG_CREATE_NAME_PROMPT =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1226;
+
+ /**
+ * The message ID for the message that will be used when a child
+ * managed object name the was specified interactively cannot be
+ * used because there is already a managed object with the same
+ * name. This takes two arguments which are the type of managed
+ * object being created and the name of the existing managed object.
+ */
+ public static final int MSGID_DSCFG_ERROR_CREATE_NAME_ALREADY_EXISTS =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1227;
+
+ /**
+ * The message ID for the message that will be used as the type
+ * heading in interactive help. This does not require any arguments.
+ */
+ public static final int MSGID_DSCFG_DESCRIPTION_CREATE_HELP_HEADING_TYPE =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1228;
+
+ /**
+ * The message ID for the message that will be used as the description
+ * heading in interactive help. This does not require any arguments.
+ */
+ public static final int MSGID_DSCFG_DESCRIPTION_CREATE_HELP_HEADING_DESCR =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1229;
+
+ /**
+ * The message ID for the message that will be used when a user
+ * requests to interactively select the name of acomponent, but
+ * there are none available. This takes a single argument which is
+ * the user friendly plural name of the component type.
+ */
+ public static final int MSGID_DSCFG_ERROR_FINDER_NO_CHILDREN =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1230;
+
+ /**
+ * The message ID for the message that will be used when a user
+ * requests to interactively select the name of a component, but
+ * there was only one available and the user did not select it. This
+ * takes a single argument which is the user friendly name of the
+ * component type.
+ */
+ public static final int MSGID_DSCFG_ERROR_FINDER_SINGLE_CHILD_REJECTED =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1231;
+
+ /**
+ * The message ID for the message that will be used as the prompt
+ * when a user requests to interactively select the name of a
+ * component and there is only one option. This takes two arguments
+ * which are the user friendly name of the component type and the
+ * single available choice.
+ */
+ public static final int MSGID_DSCFG_FINDER_PROMPT_SINGLE =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1232;
+
+ /**
+ * The message ID for the message that will be used as the prompt
+ * when a user requests to interactively select the name of a
+ * component and there is more than one option. This takes a single
+ * argument which is the user friendly name of the component type.
+ */
+ public static final int MSGID_DSCFG_FINDER_PROMPT_MANY =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1233;
+
+ /**
+ * The message ID for the word that will be used in confirmation
+ * messages to indicate "yes".
+ */
+ public static final int MSGID_DSCFG_GENERAL_CONFIRM_NO =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1234;
+
+ /**
+ * The message ID for the word that will be used in confirmation
+ * messages to indicate "yes".
+ */
+ public static final int MSGID_DSCFG_GENERAL_CONFIRM_YES =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1235;
+
+ /**
+ * The message ID for the message that will be used when a user
+ * fails to input a valid response to a confirmation message. This
+ * takes two arguments which are the word for "yes" and the word for
+ * "no".
+ */
+ public static final int MSGID_DSCFG_ERROR_GENERAL_CONFIRM =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1236;
+
+ /**
+ * The message ID for the prompt that will be used in choice menus
+ * when no help is available. This takes a single argument which is
+ * the choice upper-bound.
+ */
+ public static final int MSGID_DSCFG_GENERAL_CHOICE_PROMPT_NOHELP =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1237;
+
+ /**
+ * The message ID for the prompt that will be used in choice menus
+ * when help is available. This takes a single argument which is the
+ * choice upper-bound.
+ */
+ public static final int MSGID_DSCFG_GENERAL_CHOICE_PROMPT_HELP =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1238;
+
+ /**
+ * The message ID for the message that will be used when a user
+ * fails to input a valid response to a choice prompt. This takes a
+ * single argument which is the choice's upper-bound.
+ */
+ public static final int MSGID_DSCFG_ERROR_GENERAL_CHOICE =
+ CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1239;
/**
* Associates a set of generic messages with the message IDs defined in this
@@ -11510,6 +11655,10 @@
"The LDAP bind password could not be read due to the" +
" following error: %s");
+ registerMessage(MSGID_DSCFG_ERROR_CANNOT_READ_CONSOLE_INPUT,
+ "The response could not be read from the console due " +
+ "to the following error: %s");
+
registerMessage(MSGID_DSCFG_ERROR_BIND_PASSWORD_NONINTERACTIVE,
"The LDAP bind password was not specified and " +
"cannot be read interactively");
@@ -11566,6 +11715,12 @@
"The type of %s which should be created (Default: %s). " +
"The value for TYPE can be one of: %s");
+ registerMessage(MSGID_DSCFG_CREATE_TYPE_PROMPT,
+ "Select the type of %s that you want to create:");
+
+ registerMessage(MSGID_DSCFG_CREATE_NAME_PROMPT,
+ "Enter a name for the %s that you want to create:");
+
registerMessage(MSGID_DSCFG_DESCRIPTION_PROP,
"The name of a property to be displayed");
@@ -11713,6 +11868,9 @@
"The %s could not be created because there is " +
"already an existing one with the same name");
+ registerMessage(MSGID_DSCFG_ERROR_CREATE_NAME_ALREADY_EXISTS,
+ "There is already another %s with the name \"%s\"");
+
registerMessage(MSGID_DSCFG_ERROR_CREATE_MMPE,
"The %s could not be created because the " +
"following mandatory properties must be defined: %s");
@@ -11888,6 +12046,10 @@
"The property modification \"%s\" is incompatible" +
" with a previous modification to the same property");
+ registerMessage(MSGID_DSCFG_ERROR_MISSING_NON_INTERACTIVE_ARG,
+ "The argument \"--%s\" must be specified when " +
+ "this application is used non-interactively");
+
registerMessage(MSGID_DSCFG_ERROR_SUB_TYPE_UNRECOGNIZED,
"The sub-type \"%s\" is not a recognized type of %s. " +
"It should be one of: %s");
@@ -12217,7 +12379,31 @@
"Prompt for any required information rather than fail");
registerMessage(MSGID_REVERT_DESCRIPTION_SILENT,
"Perform a silent reversion");
-
+ registerMessage(MSGID_DSCFG_DESCRIPTION_CREATE_HELP_HEADING_TYPE,
+ "Type");
+ registerMessage(MSGID_DSCFG_DESCRIPTION_CREATE_HELP_HEADING_DESCR,
+ "Description");
+ registerMessage(MSGID_DSCFG_FINDER_PROMPT_SINGLE,
+ "There is only one %s: \"%s\". Are you sure that " +
+ "this is the correct one?");
+ registerMessage(MSGID_DSCFG_FINDER_PROMPT_MANY,
+ "Select the %s from the following list:");
+ registerMessage(MSGID_DSCFG_ERROR_FINDER_NO_CHILDREN,
+ "Unable to continue since there are no %s currently " +
+ "configured on the server");
+ registerMessage(MSGID_DSCFG_ERROR_FINDER_SINGLE_CHILD_REJECTED,
+ "Unable to continue because the only available %s was " +
+ "not selected");
+ registerMessage(MSGID_DSCFG_GENERAL_CONFIRM_NO, "no");
+ registerMessage(MSGID_DSCFG_GENERAL_CONFIRM_YES, "yes");
+ registerMessage(MSGID_DSCFG_GENERAL_CHOICE_PROMPT_HELP,
+ "Enter choice [1 - %s, ? - help]:");
+ registerMessage(MSGID_DSCFG_GENERAL_CHOICE_PROMPT_NOHELP,
+ "Enter choice [1 - %s]:");
+ registerMessage(MSGID_DSCFG_ERROR_GENERAL_CHOICE,
+ "Invalid response. Please enter a value between 1 and %s");
+ registerMessage(MSGID_DSCFG_ERROR_GENERAL_CONFIRM,
+ "Invalid response. Please enter \"%s\" or \"%s\"");
}
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/ArgumentExceptionFactory.java b/opends/src/server/org/opends/server/tools/dsconfig/ArgumentExceptionFactory.java
index f897317..b9d6399 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/ArgumentExceptionFactory.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/ArgumentExceptionFactory.java
@@ -45,6 +45,7 @@
import org.opends.server.admin.RelationDefinition;
import org.opends.server.admin.client.IllegalManagedObjectNameException;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
+import org.opends.server.util.args.Argument;
import org.opends.server.util.args.ArgumentException;
@@ -66,7 +67,8 @@
* @return Returns an argument exception.
*/
public static ArgumentException adaptIllegalManagedObjectNameException(
- IllegalManagedObjectNameException e, AbstractManagedObjectDefinition d) {
+ IllegalManagedObjectNameException e,
+ AbstractManagedObjectDefinition<?, ?> d) {
String illegalName = e.getIllegalName();
PropertyDefinition<?> pd = e.getNamingPropertyDefinition();
@@ -112,7 +114,7 @@
*/
public static ArgumentException adaptMissingMandatoryPropertiesException(
MissingMandatoryPropertiesException e,
- AbstractManagedObjectDefinition d) {
+ AbstractManagedObjectDefinition<?, ?> d) {
int msgID = MSGID_DSCFG_ERROR_CREATE_MMPE;
StringBuilder builder = new StringBuilder();
boolean isFirst = true;
@@ -139,7 +141,7 @@
* @return Returns an argument exception.
*/
public static ArgumentException adaptPropertyException(PropertyException e,
- AbstractManagedObjectDefinition d) {
+ AbstractManagedObjectDefinition<?, ?> d) {
if (e instanceof IllegalPropertyValueException) {
IllegalPropertyValueException pe = (IllegalPropertyValueException) e;
return adapt(d, pe);
@@ -203,6 +205,24 @@
/**
+ * 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) {
+ int msgID = MSGID_DSCFG_ERROR_MISSING_NON_INTERACTIVE_ARG;
+ String msg = getMessage(msgID, arg.getLongIdentifier());
+ return new ArgumentException(msgID, msg);
+ }
+
+
+
+ /**
* Creates an argument exception which should be used when a
* property value argument is invalid because it does not a property
* name.
@@ -309,26 +329,6 @@
/**
- * 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) {
- int msgID = MSGID_DSCFG_ERROR_UNABLE_TO_SET_NAMING_PROPERTY;
- String message = getMessage(msgID, pd.getName(), d.getUserFriendlyName());
- return new ArgumentException(msgID, message);
- }
-
-
-
- /**
* Creates an argument exception which should be used when the bind
* password could not be read from the standard input.
*
@@ -360,6 +360,22 @@
/**
+ * Creates an argument exception which should be used when
+ * interaction with the console fails due to an IO exception.
+ *
+ * @param cause
+ * The reason why console input failed.
+ * @return Returns an argument exception.
+ */
+ public static ArgumentException unableToReadConsoleInput(Exception cause) {
+ int msgID = MSGID_DSCFG_ERROR_CANNOT_READ_CONSOLE_INPUT;
+ String message = getMessage(msgID, cause.getMessage());
+ return new ArgumentException(msgID, message, cause);
+ }
+
+
+
+ /**
* 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.
@@ -374,7 +390,7 @@
* @return Returns an argument exception.
*/
public static ArgumentException unableToResetMandatoryProperty(
- AbstractManagedObjectDefinition d, String name, String setOption) {
+ AbstractManagedObjectDefinition<?, ?> d, String name, String setOption) {
int msgID = MSGID_DSCFG_ERROR_UNABLE_TO_RESET_MANDATORY_PROPERTY;
String message = getMessage(msgID, d.getUserFriendlyPluralName(), name,
setOption);
@@ -384,6 +400,26 @@
/**
+ * 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) {
+ int msgID = MSGID_DSCFG_ERROR_UNABLE_TO_SET_NAMING_PROPERTY;
+ String message = getMessage(msgID, pd.getName(), d.getUserFriendlyName());
+ return new ArgumentException(msgID, message);
+ }
+
+
+
+ /**
* Creates an argument exception which should be used when a
* property name is not recognized.
*
@@ -394,7 +430,7 @@
* @return Returns an argument exception.
*/
public static ArgumentException unknownProperty(
- AbstractManagedObjectDefinition d, String name) {
+ AbstractManagedObjectDefinition<?, ?> d, String name) {
int msgID = MSGID_DSCFG_ERROR_PROPERTY_UNRECOGNIZED;
String message = getMessage(msgID, name, d.getUserFriendlyPluralName());
return new ArgumentException(msgID, message);
@@ -414,7 +450,7 @@
* A usage string describing the allowed sub-types.
* @return Returns an argument exception.
*/
- public static ArgumentException unknownSubType(RelationDefinition r,
+ public static ArgumentException unknownSubType(RelationDefinition<?, ?> r,
String typeName, String typeUsage) {
int msgID = MSGID_DSCFG_ERROR_SUB_TYPE_UNRECOGNIZED;
String msg = getMessage(msgID, typeName, r.getUserFriendlyName(),
@@ -451,8 +487,8 @@
* The definition of the managed object that was retrieved.
* @return Returns an argument exception.
*/
- public static ArgumentException wrongManagedObjectType(RelationDefinition r,
- ManagedObjectDefinition d) {
+ public static ArgumentException wrongManagedObjectType(
+ RelationDefinition<?, ?> r, ManagedObjectDefinition<?, ?> d) {
int msgID = MSGID_DSCFG_ERROR_TYPE_UNRECOGNIZED;
String msg = getMessage(msgID, r.getUserFriendlyName(), d
.getUserFriendlyName());
@@ -470,8 +506,8 @@
* The default behavior exception.
* @return Returns an argument exception.
*/
- private static ArgumentException adapt(AbstractManagedObjectDefinition d,
- DefaultBehaviorException e) {
+ private static ArgumentException adapt(
+ AbstractManagedObjectDefinition<?, ?> d, DefaultBehaviorException e) {
int msgID = MSGID_DSCFG_ERROR_PROPERTY_DEFAULT_BEHAVIOR;
String message = getMessage(msgID, d.getUserFriendlyName(), e
.getPropertyDefinition().getName(), e.getMessage());
@@ -490,7 +526,8 @@
* The illegal property value exception.
* @return Returns an argument exception.
*/
- private static ArgumentException adapt(AbstractManagedObjectDefinition d,
+ private static ArgumentException adapt(
+ AbstractManagedObjectDefinition<?, ?> d,
IllegalPropertyValueException e) {
PropertyDefinitionUsageBuilder b = new PropertyDefinitionUsageBuilder(true);
String syntax = b.getUsage(e.getPropertyDefinition());
@@ -518,7 +555,8 @@
* The illegal property string value exception.
* @return Returns an argument exception.
*/
- private static ArgumentException adapt(AbstractManagedObjectDefinition d,
+ private static ArgumentException adapt(
+ AbstractManagedObjectDefinition<?, ?> d,
IllegalPropertyValueStringException e) {
PropertyDefinitionUsageBuilder b = new PropertyDefinitionUsageBuilder(true);
String syntax = b.getUsage(e.getPropertyDefinition());
@@ -547,7 +585,8 @@
* The property is mandatory exception.
* @return Returns an argument exception.
*/
- private static ArgumentException adapt(AbstractManagedObjectDefinition d,
+ private static ArgumentException adapt(
+ AbstractManagedObjectDefinition<?, ?> d,
PropertyIsMandatoryException e) {
int msgID = MSGID_DSCFG_ERROR_PROPERTY_MANDATORY;
String message = getMessage(msgID, d.getUserFriendlyName(), e
@@ -567,7 +606,8 @@
* The property is read-only exception.
* @return Returns an argument exception.
*/
- private static ArgumentException adapt(AbstractManagedObjectDefinition d,
+ private static ArgumentException adapt(
+ AbstractManagedObjectDefinition<?, ?> d,
PropertyIsReadOnlyException e) {
int msgID = MSGID_DSCFG_ERROR_PROPERTY_READ_ONLY;
String message = getMessage(msgID, d.getUserFriendlyName(), e
@@ -587,7 +627,8 @@
* The property is single-valued exception.
* @return Returns an argument exception.
*/
- private static ArgumentException adapt(AbstractManagedObjectDefinition d,
+ private static ArgumentException adapt(
+ AbstractManagedObjectDefinition<?, ?> d,
PropertyIsSingleValuedException e) {
int msgID = MSGID_DSCFG_ERROR_PROPERTY_SINGLE_VALUED;
String message = getMessage(msgID, d.getUserFriendlyName(), e
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/ConsoleApplication.java b/opends/src/server/org/opends/server/tools/dsconfig/ConsoleApplication.java
new file mode 100644
index 0000000..abe488a
--- /dev/null
+++ b/opends/src/server/org/opends/server/tools/dsconfig/ConsoleApplication.java
@@ -0,0 +1,494 @@
+/*
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.tools.dsconfig;
+
+
+
+import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.messages.ToolMessages.*;
+import static org.opends.server.util.ServerConstants.*;
+import static org.opends.server.util.StaticUtils.*;
+
+import java.io.BufferedReader;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.util.List;
+
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.tools.ClientException;
+import org.opends.server.types.NullOutputStream;
+import org.opends.server.util.PasswordReader;
+import org.opends.server.util.Validator;
+import org.opends.server.util.args.ArgumentException;
+import org.opends.server.util.table.TableBuilder;
+import org.opends.server.util.table.TextTablePrinter;
+
+
+
+/**
+ * This class provides an abstract base class which can be used as the
+ * basis of a console-based application.
+ */
+public abstract class ConsoleApplication {
+
+ // The error stream which this application should use.
+ private final PrintStream err;
+
+ // The input stream reader which this application should use.
+ private final BufferedReader in;
+
+ // The output stream which this application should use.
+ private final PrintStream out;
+
+
+
+ /**
+ * Creates a new console application instance.
+ *
+ * @param in
+ * The application input stream.
+ * @param out
+ * The application output stream.
+ * @param err
+ * The application error stream.
+ */
+ protected ConsoleApplication(InputStream in, OutputStream out,
+ OutputStream err) {
+ if (in != null) {
+ this.in = new BufferedReader(new InputStreamReader(in));
+ } else {
+ this.in = new BufferedReader(new Reader() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void close() throws IOException {
+ // Do nothing.
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ return -1;
+ }
+
+ });
+ }
+
+ if (out != null) {
+ this.out = new PrintStream(out);
+ } else {
+ this.out = NullOutputStream.printStream();
+ }
+
+ if (err != null) {
+ this.err = new PrintStream(err);
+ } else {
+ this.err = NullOutputStream.printStream();
+ }
+ }
+
+
+
+ /**
+ * Interactively confirms whether a user wishes to perform an
+ * action. If the application is non-interactive, then the action is
+ * granted by default.
+ *
+ * @param prompt
+ * The prompt describing the action.
+ * @return Returns <code>true</code> if the user wishes the action
+ * to be performed, or <code>false</code> if they refused,
+ * or if an exception occurred.
+ * @throws ArgumentException
+ * If the user's response could not be read from the
+ * console for some reason.
+ */
+ public final boolean confirmAction(String prompt) throws ArgumentException {
+ if (!isInteractive()) {
+ return true;
+ }
+
+ final String yes = getMessage(MSGID_DSCFG_GENERAL_CONFIRM_YES);
+ final String no = getMessage(MSGID_DSCFG_GENERAL_CONFIRM_NO);
+ final String errMsg =
+ getMessage(MSGID_DSCFG_ERROR_GENERAL_CONFIRM, yes, no);
+ prompt = prompt + String.format(" (%s / %s): ", yes, no);
+
+ ValidationCallback<Boolean> validator = new ValidationCallback<Boolean>() {
+
+ public Boolean validate(ConsoleApplication app, String input) {
+ String ninput = input.toLowerCase().trim();
+ if (ninput.length() == 0) {
+ // Empty input.
+ app.printMessage(errMsg);
+ } else if (no.startsWith(ninput)) {
+ return false;
+ } else if (yes.startsWith(ninput)) {
+ return true;
+ } else {
+ // Try again...
+ app.printMessage(errMsg);
+ }
+
+ return null;
+ }
+ };
+
+ try {
+ return readValidatedInput(prompt, validator);
+ } catch (ClientException e) {
+ // Should never happen.
+ throw new RuntimeException(e);
+ }
+ }
+
+
+
+ /**
+ * Displays a message to the error stream.
+ *
+ * @param msg
+ * The message.
+ */
+ public final void printMessage(String msg) {
+ err.println(wrapText(msg, MAX_LINE_WIDTH));
+ }
+
+
+
+ /**
+ * Displays a blank line to the error stream.
+ */
+ public final void println() {
+ err.println();
+ }
+
+
+
+ /**
+ * Displays a message to the error stream if verbose mode is
+ * enabled.
+ *
+ * @param msg
+ * The verbose message.
+ */
+ public final void printVerboseMessage(String msg) {
+ if (isVerbose()) {
+ err.println(wrapText(msg, MAX_LINE_WIDTH));
+ }
+ }
+
+
+
+ /**
+ * Gets the application error stream.
+ *
+ * @return Returns the application error stream.
+ */
+ public final PrintStream getErrorStream() {
+ return err;
+ }
+
+
+
+ /**
+ * Gets the application input stream.
+ *
+ * @return Returns the application input stream.
+ */
+ public final BufferedReader getInputStream() {
+ return in;
+ }
+
+
+
+ /**
+ * Gets the management context which sub-commands should use in
+ * order to manage the directory server.
+ *
+ * @return Returns the management context which sub-commands should
+ * use in order to manage the directory server.
+ * @throws ArgumentException
+ * If a management context related argument could not be
+ * parsed successfully.
+ * @throws ClientException
+ * If the management context could not be created.
+ */
+ public abstract ManagementContext getManagementContext()
+ throws ArgumentException, ClientException;
+
+
+
+ /**
+ * Gets the application output stream.
+ *
+ * @return Returns the application output stream.
+ */
+ public final PrintStream getOutputStream() {
+ return out;
+ }
+
+
+
+ /**
+ * Indicates whether or not the user has requested interactive
+ * behavior.
+ *
+ * @return Returns <code>true</code> if the user has requested
+ * interactive behavior.
+ */
+ public abstract boolean isInteractive();
+
+
+
+ /**
+ * Indicates whether or not the user has requested quiet output.
+ *
+ * @return Returns <code>true</code> if the user has requested
+ * quiet output.
+ */
+ public abstract boolean isQuiet();
+
+
+
+ /**
+ * Indicates whether or not the user has requested script-friendly
+ * output.
+ *
+ * @return Returns <code>true</code> if the user has requested
+ * script-friendly output.
+ */
+ public abstract boolean isScriptFriendly();
+
+
+
+ /**
+ * Indicates whether or not the user has requested verbose output.
+ *
+ * @return Returns <code>true</code> if the user has requested
+ * verbose output.
+ */
+ public abstract boolean isVerbose();
+
+
+
+ /**
+ * Interactively prompts the user to select from a choice of
+ * options.
+ *
+ * @param <T>
+ * The type of the values represented by each choice.
+ * @param prompt
+ * The prompt which should appear before the list of
+ * choices.
+ * @param descriptions
+ * The descriptions of each choice.
+ * @param values
+ * The choices.
+ * @param helpCallback
+ * An optional help call-back which can be used to display
+ * additional help.
+ * @return Returns the selected value.
+ * @throws ArgumentException
+ * If the user input could not be retrieved for some
+ * reason.
+ */
+ public final <T> T readChoice(final String prompt, List<String> descriptions,
+ List<T> values, final HelpCallback helpCallback)
+ throws ArgumentException {
+ Validator.ensureTrue(descriptions.size() == values.size());
+
+ // Output main prompt.
+ println();
+ printMessage(prompt);
+ println();
+
+ // Build the table of choices.
+ final TableBuilder builder = new TableBuilder();
+ final int size = descriptions.size();
+ for (int i = 0; i < size; i++) {
+ builder.startRow();
+ builder.appendCell("[" + (i + 1) + "]");
+ builder.appendCell(descriptions.get(i));
+ }
+
+ // Display the table of choices.
+ final TextTablePrinter printer = new TextTablePrinter(err);
+ printer.setDisplayHeadings(false);
+ printer.setColumnWidth(1, 0);
+ builder.print(printer);
+
+ // Get the user input.
+ String promptMsg;
+ if (helpCallback != null) {
+ promptMsg = getMessage(MSGID_DSCFG_GENERAL_CHOICE_PROMPT_HELP, size);
+ } else {
+ promptMsg = getMessage(MSGID_DSCFG_GENERAL_CHOICE_PROMPT_NOHELP, size);
+ }
+
+ ValidationCallback<Integer> validator = new ValidationCallback<Integer>() {
+
+ public Integer validate(ConsoleApplication app, String input) {
+ String ninput = input.trim();
+
+ if (ninput.equals("?") && helpCallback != null) {
+ app.println();
+ helpCallback.display(app);
+ app.println();
+
+ // Output main prompt.
+ printMessage(prompt);
+ println();
+ builder.print(printer);
+ println();
+
+ return null;
+ } else {
+ try {
+ int i = Integer.parseInt(ninput);
+ if (i < 1 || i > size) {
+ throw new NumberFormatException();
+ }
+ return i;
+ } catch (NumberFormatException e) {
+ app.println();
+ String errMsg = getMessage(MSGID_DSCFG_ERROR_GENERAL_CHOICE, size);
+ app.printMessage(errMsg);
+ app.println();
+ return null;
+ }
+ }
+ }
+ };
+
+ // Get the choice.
+ int choice;
+ try {
+ choice = readValidatedInput(promptMsg, validator);
+ } catch (ClientException e) {
+ // Should never happen.
+ throw new RuntimeException(e);
+ }
+ return values.get(choice - 1);
+ }
+
+
+
+ /**
+ * Interactively retrieves a line of input from the console.
+ *
+ * @param prompt
+ * The prompt.
+ * @return Returns the line of input, or <code>null</code> if the
+ * end of input has been reached.
+ * @throws ArgumentException
+ * If the line of input could not be retrieved for some
+ * reason.
+ */
+ public final String readLineOfInput(String prompt) throws ArgumentException {
+ err.println();
+ err.print(wrapText(prompt.trim() + " ", MAX_LINE_WIDTH));
+ try {
+ return in.readLine();
+ } catch (IOException e) {
+ throw ArgumentExceptionFactory.unableToReadConsoleInput(e);
+ }
+ }
+
+
+
+ /**
+ * Interactively retrieves a password from the console.
+ *
+ * @param prompt
+ * The password prompt.
+ * @return Returns the password.
+ * @throws ArgumentException
+ * If the password could not be retrieved for some reason.
+ */
+ public final String readPassword(String prompt) throws ArgumentException {
+ err.print(wrapText(prompt + " ", MAX_LINE_WIDTH));
+ char[] pwChars;
+ try {
+ pwChars = PasswordReader.readPassword();
+ } catch (Exception e) {
+ throw ArgumentExceptionFactory.unableToReadConsoleInput(e);
+ }
+ return new String(pwChars);
+ }
+
+
+
+ /**
+ * Interactively prompts for user input and continues until valid
+ * input is provided.
+ *
+ * @param <T>
+ * The type of decoded user input.
+ * @param prompt
+ * The interactive prompt which should be displayed on each
+ * input attempt.
+ * @param validator
+ * An input validator responsible for validating and
+ * decoding the user's response.
+ * @return Returns the decoded user's response.
+ * @throws ArgumentException
+ * If the line of input could not be retrieved for some
+ * reason.
+ * @throws ClientException
+ * If an unexpected error occurred which prevented
+ * validation.
+ */
+ public final <T> T readValidatedInput(String prompt,
+ ValidationCallback<T> validator) throws ArgumentException,
+ ClientException {
+ while (true) {
+ String response = readLineOfInput(prompt);
+
+ if (response == null) {
+ throw ArgumentExceptionFactory
+ .unableToReadConsoleInput(new EOFException("End of input"));
+ }
+
+ T value = validator.validate(this, response);
+ if (value != null) {
+ return value;
+ }
+ }
+ }
+}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
index f5944e3..3c3034c 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
@@ -31,7 +31,7 @@
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ToolMessages.*;
-import java.io.PrintStream;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -43,6 +43,7 @@
import java.util.TreeMap;
import org.opends.server.admin.AbstractManagedObjectDefinition;
+import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
import org.opends.server.admin.DefaultBehaviorException;
import org.opends.server.admin.DefinitionDecodingException;
@@ -65,7 +66,6 @@
import org.opends.server.admin.client.IllegalManagedObjectNameException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
-import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.protocols.ldap.LDAPResultCode;
@@ -74,6 +74,8 @@
import org.opends.server.util.args.StringArgument;
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.args.SubCommandArgumentParser;
+import org.opends.server.util.table.TableBuilder;
+import org.opends.server.util.table.TextTablePrinter;
@@ -84,9 +86,12 @@
*
* @param <C>
* The type of managed object which can be created.
+ * @param <S>
+ * The type of server managed object which can be created.
*/
-final class CreateSubCommandHandler<C extends ConfigurationClient> extends
- SubCommandHandler {
+final class CreateSubCommandHandler<C extends ConfigurationClient,
+ S extends Configuration> extends SubCommandHandler {
+
/**
* A property provider which uses the command-line arguments to
@@ -95,8 +100,8 @@
private static class MyPropertyProvider implements PropertyProvider {
// Decoded set of properties.
- private final Map<PropertyDefinition, Collection> properties =
- new HashMap<PropertyDefinition, Collection>();
+ private final Map<PropertyDefinition<?>, Collection<?>> properties =
+ new HashMap<PropertyDefinition<?>, Collection<?>>();
@@ -162,7 +167,7 @@
* @return Returns the set of parsed property definitions that
* have values specified.
*/
- public Set<PropertyDefinition> getProperties() {
+ public Set<PropertyDefinition<?>> getProperties() {
return properties.keySet();
}
@@ -174,7 +179,7 @@
@SuppressWarnings("unchecked")
public <T> Collection<T> getPropertyValues(PropertyDefinition<T> d)
throws IllegalArgumentException {
- Collection<T> values = properties.get(d);
+ Collection<T> values = (Collection<T>) properties.get(d);
if (values == null) {
return Collections.emptySet();
} else {
@@ -195,7 +200,7 @@
throw ArgumentExceptionFactory.adaptPropertyException(e, d);
}
- Collection<T> values = properties.get(pd);
+ Collection<T> values = (Collection<T>) properties.get(pd);
if (values == null) {
values = new LinkedList<T>();
}
@@ -210,6 +215,53 @@
}
}
+
+
+ /**
+ * A help call-back which displays help about available component types.
+ */
+ private final class TypeHelpCallback implements HelpCallback {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void display(ConsoleApplication app) {
+ // Create a table containing a description of each component type.
+ TableBuilder builder = new TableBuilder();
+
+ int msgID = MSGID_DSCFG_DESCRIPTION_CREATE_HELP_HEADING_TYPE;
+ builder.appendHeading(getMessage(msgID));
+
+ msgID = MSGID_DSCFG_DESCRIPTION_CREATE_HELP_HEADING_DESCR;
+ builder.appendHeading(getMessage(msgID));
+
+ boolean isFirst = true;
+ for (ManagedObjectDefinition<?, ?> d : types.values()) {
+ if (!isFirst) {
+ builder.startRow();
+ builder.startRow();
+ } else {
+ isFirst = false;
+ }
+
+ builder.startRow();
+ builder.appendCell(d.getUserFriendlyName());
+ builder.appendCell(d.getSynopsis());
+ if (d.getDescription() != null) {
+ builder.startRow();
+ builder.startRow();
+ builder.appendCell();
+ builder.appendCell(d.getDescription());
+ }
+ }
+
+ TextTablePrinter printer = new TextTablePrinter(app.getErrorStream());
+ printer.setColumnWidth(1, 0);
+ printer.setColumnSeparator(":");
+ builder.print(printer);
+ }
+ }
+
/**
* The value for the -t argument which will be used for the most
* generic managed object when it is instantiable.
@@ -244,6 +296,10 @@
*
* @param <C>
* The type of managed object which can be created.
+ * @param <S>
+ * The type of server managed object which can be created.
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param p
@@ -254,10 +310,12 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static <C extends ConfigurationClient> CreateSubCommandHandler create(
- SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
- InstantiableRelationDefinition<C, ?> r) throws ArgumentException {
- return new CreateSubCommandHandler<C>(parser, p, r, r
+ public static <C extends ConfigurationClient, S extends Configuration>
+ CreateSubCommandHandler<C, S> create(
+ ConsoleApplication app, SubCommandArgumentParser parser,
+ ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> r)
+ throws ArgumentException {
+ return new CreateSubCommandHandler<C, S>(app, parser, p, r, r
.getNamingPropertyDefinition(), p.child(r, "DUMMY"));
}
@@ -268,6 +326,10 @@
*
* @param <C>
* The type of managed object which can be created.
+ * @param <S>
+ * The type of server managed object which can be created.
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param p
@@ -278,10 +340,13 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static <C extends ConfigurationClient> CreateSubCommandHandler create(
- SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
- OptionalRelationDefinition<C, ?> r) throws ArgumentException {
- return new CreateSubCommandHandler<C>(parser, p, r, null, p.child(r));
+ public static <C extends ConfigurationClient, S extends Configuration>
+ CreateSubCommandHandler<C, S> create(
+ ConsoleApplication app, SubCommandArgumentParser parser,
+ ManagedObjectPath<?, ?> p, OptionalRelationDefinition<C, S> r)
+ throws ArgumentException {
+ return new CreateSubCommandHandler<C, S>(app, parser, p, r, null, p
+ .child(r));
}
// The sub-commands naming arguments.
@@ -298,7 +363,7 @@
private final StringArgument propertySetArgument;
// The relation which should be used for creating children.
- private final RelationDefinition<C, ?> relation;
+ private final RelationDefinition<C, S> relation;
// The sub-command associated with this handler.
private final SubCommand subCommand;
@@ -310,7 +375,7 @@
// The set of instantiable managed object definitions and their
// associated type option value.
private final SortedMap<String,
- ManagedObjectDefinition<? extends C, ?>> types;
+ ManagedObjectDefinition<? extends C, ? extends S>> types;
// The syntax of the type argument.
private final String typeUsage;
@@ -318,10 +383,13 @@
// Common constructor.
- private CreateSubCommandHandler(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> p, RelationDefinition<C, ?> r,
+ private CreateSubCommandHandler(ConsoleApplication app,
+ SubCommandArgumentParser parser,
+ ManagedObjectPath<?, ?> p, RelationDefinition<C, S> r,
PropertyDefinition<?> pd, ManagedObjectPath<?, ?> c)
throws ArgumentException {
+ super(app);
+
this.path = p;
this.relation = r;
this.namingPropertyDefinition = pd;
@@ -359,9 +427,9 @@
this.typeUsage = builder.toString();
if (!types.containsKey(GENERIC_TYPE)) {
- // The option is mandatory.
+ // The option is mandatory when non-interactive.
this.typeArgument = new StringArgument("type", OPTION_DSCFG_SHORT_TYPE,
- OPTION_DSCFG_LONG_TYPE, true, false, true, "{TYPE}", null, null,
+ OPTION_DSCFG_LONG_TYPE, false, false, true, "{TYPE}", null, null,
MSGID_DSCFG_DESCRIPTION_TYPE, r.getChildDefinition()
.getUserFriendlyName(), typeUsage);
} else {
@@ -399,11 +467,40 @@
* {@inheritDoc}
*/
@Override
- public int run(DSConfig app, PrintStream out, PrintStream err)
- throws ArgumentException, ClientException {
+ public int run() throws ArgumentException, ClientException {
// Determine the type of managed object to be created.
- String typeName = typeArgument.getValue();
- ManagedObjectDefinition<? extends C, ?> d = types.get(typeName);
+ String typeName;
+
+ if (!typeArgument.isPresent()) {
+ if (getConsoleApplication().isInteractive()) {
+ // Let the user choose.
+
+ // If there is only one choice then return immediately.
+ if (types.size() == 1) {
+ typeName = types.keySet().iterator().next();
+ } else {
+ List<String> values = new ArrayList<String>(types.keySet());
+ List<String> descriptions = new ArrayList<String>(values.size());
+ for (ManagedObjectDefinition<?, ?> d : types.values()) {
+ descriptions.add(d.getUserFriendlyName());
+ }
+ int msgID = MSGID_DSCFG_CREATE_TYPE_PROMPT;
+ String msg = getMessage(msgID, relation.getChildDefinition()
+ .getUserFriendlyName());
+ typeName = getConsoleApplication().readChoice(msg, descriptions,
+ values, new TypeHelpCallback());
+ }
+ } else if (typeArgument.getDefaultValue() != null) {
+ typeName = typeArgument.getDefaultValue();
+ } else {
+ throw ArgumentExceptionFactory
+ .missingMandatoryNonInteractiveArgument(typeArgument);
+ }
+ } else {
+ typeName = typeArgument.getValue();
+ }
+
+ ManagedObjectDefinition<? extends C, ? extends S> d = types.get(typeName);
if (d == null) {
throw ArgumentExceptionFactory.unknownSubType(relation, typeName,
typeUsage);
@@ -418,10 +515,9 @@
namingPropertyDefinition, propertyArgs);
// Add the child managed object.
- ManagementContext context = app.getManagementContext();
ManagedObject<?> parent;
try {
- parent = getManagedObject(context, path, names);
+ parent = getManagedObject(path, names);
} catch (AuthorizationException e) {
int msgID = MSGID_DSCFG_ERROR_CREATE_AUTHZ;
String msg = getMessage(msgID, d.getUserFriendlyName());
@@ -459,18 +555,28 @@
List<DefaultBehaviorException> exceptions =
new LinkedList<DefaultBehaviorException>();
if (relation instanceof InstantiableRelationDefinition) {
- InstantiableRelationDefinition<C, ?> irelation =
- (InstantiableRelationDefinition<C, ?>) relation;
+ InstantiableRelationDefinition<C, S> irelation =
+ (InstantiableRelationDefinition<C, S>) relation;
String name = names.get(names.size() - 1);
- try {
- child = parent.createChild(irelation, d, name, exceptions);
- } catch (IllegalManagedObjectNameException e) {
- throw ArgumentExceptionFactory
- .adaptIllegalManagedObjectNameException(e, d);
+ if (name == null) {
+ if (getConsoleApplication().isInteractive()) {
+ child = createChildInteractively(parent, irelation, d, exceptions);
+ } else {
+ throw ArgumentExceptionFactory
+ .missingMandatoryNonInteractiveArgument(namingArgs.get(names
+ .size() - 1));
+ }
+ } else {
+ try {
+ child = parent.createChild(irelation, d, name, exceptions);
+ } catch (IllegalManagedObjectNameException e) {
+ throw ArgumentExceptionFactory
+ .adaptIllegalManagedObjectNameException(e, d);
+ }
}
} else {
- OptionalRelationDefinition<C, ?> orelation =
- (OptionalRelationDefinition<C, ?>) relation;
+ OptionalRelationDefinition<C, S> orelation =
+ (OptionalRelationDefinition<C, S>) relation;
child = parent.createChild(orelation, d, exceptions);
}
@@ -485,11 +591,11 @@
// Confirm commit.
String prompt = String.format(Messages.getString("create.confirm"), d
.getUserFriendlyName());
- if (!app.confirmAction(prompt)) {
+ if (!getConsoleApplication().confirmAction(prompt)) {
// Output failure message.
String msg = String.format(Messages.getString("create.failed"), d
.getUserFriendlyName());
- app.displayVerboseMessage(msg);
+ getConsoleApplication().printVerboseMessage(msg);
return 1;
}
@@ -499,7 +605,7 @@
// Output success message.
String msg = String.format(Messages.getString("create.done"), d
.getUserFriendlyName());
- app.displayVerboseMessage(msg);
+ getConsoleApplication().printVerboseMessage(msg);
} catch (MissingMandatoryPropertiesException e) {
throw ArgumentExceptionFactory.adaptMissingMandatoryPropertiesException(
e, d);
@@ -535,28 +641,100 @@
+ // Interactively create the child by prompting for the name.
+ private ManagedObject<? extends C> createChildInteractively(
+ final ManagedObject<?> parent,
+ final InstantiableRelationDefinition<C, S> irelation,
+ final ManagedObjectDefinition<? extends C, ? extends S> d,
+ final List<DefaultBehaviorException> exceptions)
+ throws ArgumentException, ClientException {
+ int msgID = MSGID_DSCFG_CREATE_NAME_PROMPT;
+ String msg = getMessage(msgID, relation.getUserFriendlyName());
+ ValidationCallback<ManagedObject<? extends C>> validator =
+ new ValidationCallback<ManagedObject<? extends C>>() {
+
+ public ManagedObject<? extends C> validate(ConsoleApplication app,
+ String input) throws ClientException {
+ ManagedObject<? extends C> child;
+
+ // First attempt to create the child, this will guarantee that
+ // the name is acceptable.
+ try {
+ child = parent.createChild(irelation, d, input, exceptions);
+ } catch (IllegalManagedObjectNameException e) {
+ ArgumentException ae = ArgumentExceptionFactory
+ .adaptIllegalManagedObjectNameException(e, d);
+ app.printMessage(ae.getMessage());
+ return null;
+ }
+
+ // Make sure that there are not any other children with the
+ // same name.
+ try {
+ // Attempt to retrieve a child using this name.
+ parent.getChild(irelation, input);
+ } catch (AuthorizationException e) {
+ int msgID = MSGID_DSCFG_ERROR_CREATE_AUTHZ;
+ String msg = getMessage(msgID, irelation.getUserFriendlyName());
+ throw new ClientException(LDAPResultCode.INSUFFICIENT_ACCESS_RIGHTS,
+ msgID, msg);
+ } catch (ConcurrentModificationException e) {
+ int msgID = MSGID_DSCFG_ERROR_CREATE_CME;
+ String msg = getMessage(msgID, irelation.getUserFriendlyName());
+ throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msgID,
+ msg);
+ } catch (CommunicationException e) {
+ int msgID = MSGID_DSCFG_ERROR_CREATE_CE;
+ String msg = getMessage(msgID, irelation.getUserFriendlyName(), e
+ .getMessage());
+ throw new ClientException(LDAPResultCode.CLIENT_SIDE_SERVER_DOWN,
+ msgID, msg);
+ } catch (DefinitionDecodingException e) {
+ // Do nothing.
+ } catch (ManagedObjectDecodingException e) {
+ // Do nothing.
+ } catch (ManagedObjectNotFoundException e) {
+ // The child does not already exist so this name is ok.
+ return child;
+ }
+
+ // A child with the specified name must already exist.
+ int msgID = MSGID_DSCFG_ERROR_CREATE_NAME_ALREADY_EXISTS;
+ String msg = getMessage(msgID, relation.getUserFriendlyName(), input);
+ app.printMessage(msg);
+ return null;
+ }
+
+ };
+
+ return getConsoleApplication().readValidatedInput(msg, validator);
+ }
+
+
+
// Generate the type name - definition mapping table.
@SuppressWarnings("unchecked")
- private SortedMap<String, ManagedObjectDefinition<? extends C, ?>>
- getSubTypes(AbstractManagedObjectDefinition<C, ?> d) {
- SortedMap<String, ManagedObjectDefinition<? extends C, ?>> map;
- map = new TreeMap<String, ManagedObjectDefinition<? extends C, ?>>();
+ private SortedMap<String, ManagedObjectDefinition<? extends C, ? extends S>>
+ getSubTypes(AbstractManagedObjectDefinition<C, S> d) {
+ SortedMap<String, ManagedObjectDefinition<? extends C, ? extends S>> map;
+ map =
+ new TreeMap<String, ManagedObjectDefinition<? extends C, ? extends S>>();
// If the top-level definition is instantiable, we use the value
// "generic".
if (d instanceof ManagedObjectDefinition) {
- ManagedObjectDefinition<? extends C, ?> mod =
- (ManagedObjectDefinition<? extends C, ?>) d;
+ ManagedObjectDefinition<? extends C, ? extends S> mod =
+ (ManagedObjectDefinition<? extends C, ? extends S>) d;
map.put(GENERIC_TYPE, mod);
}
// Process its sub-definitions.
String suffix = "-" + d.getName();
- for (AbstractManagedObjectDefinition<? extends C, ?> c :
+ for (AbstractManagedObjectDefinition<? extends C, ? extends S> c :
d.getAllChildren()) {
if (c instanceof ManagedObjectDefinition) {
- ManagedObjectDefinition<? extends C, ?> mod =
- (ManagedObjectDefinition<? extends C, ?>) c;
+ ManagedObjectDefinition<? extends C, ? extends S> mod =
+ (ManagedObjectDefinition<? extends C, ? extends S>) c;
// For the type name we shorten it, if possible, by stripping
// off the trailing part of the name which matches the
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java b/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
index 69ea295..ba3df5d 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
@@ -32,16 +32,10 @@
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ToolMessages.*;
import static org.opends.server.tools.ToolConstants.*;
-import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
-import java.io.BufferedReader;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.Reader;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
@@ -62,13 +56,13 @@
import org.opends.server.tools.ClientException;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.InitializationException;
-import org.opends.server.types.NullOutputStream;
-import org.opends.server.util.PasswordReader;
import org.opends.server.util.StaticUtils;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.args.SubCommandArgumentParser;
+import org.opends.server.util.table.TableBuilder;
+import org.opends.server.util.table.TextTablePrinter;
@@ -76,7 +70,7 @@
* This class provides a command-line tool which enables
* administrators to configure the Directory Server.
*/
-public final class DSConfig {
+public final class DSConfig extends ConsoleApplication {
/**
* The tracer object for the debug logger.
@@ -100,35 +94,38 @@
}
}
+
+
/**
* 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.
- * @param initializeServer Indicates whether to perform basic initialization
- * (which should not be done if the tool is running
- * in the same JVM as the server).
- * @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.
+ * @param args
+ * The set of command-line arguments provided to this
+ * program.
+ * @param initializeServer
+ * Indicates whether to perform basic initialization (which
+ * should not be done if the tool is running in the same
+ * JVM as the server).
+ * @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.
*/
public static int main(String[] args, boolean initializeServer,
- OutputStream outStream, OutputStream errStream)
- {
+ OutputStream outStream, OutputStream errStream) {
DSConfig app = new DSConfig(System.in, outStream, errStream,
new LDAPManagementContextFactory());
// Only initialize the client environment when run as a standalone
// application.
- if (initializeServer)
- {
+ if (initializeServer) {
try {
app.initializeClientEnvironment();
} catch (InitializationException e) {
// TODO: is this ok as an error message?
- System.err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+ app.printMessage(e.getMessage());
return 1;
}
}
@@ -141,9 +138,6 @@
// already been initialized.
private boolean environmentInitialized = false;
- // The error stream which this application should use.
- private final PrintStream err;
-
// The factory which the application should use to retrieve its
// management context.
private final ManagementContextFactory factory;
@@ -156,16 +150,10 @@
private final Map<SubCommand, SubCommandHandler> handlers =
new HashMap<SubCommand, SubCommandHandler>();
- // The input stream reader which this application should use.
- private final BufferedReader in;
-
// The argument which should be used to request interactive
// behavior.
private BooleanArgument interactiveArgument;
- // The output stream which this application should use.
- private final PrintStream out;
-
// The command-line argument parser.
private final SubCommandArgumentParser parser;
@@ -203,126 +191,17 @@
*/
public DSConfig(InputStream in, OutputStream out, OutputStream err,
ManagementContextFactory factory) {
+ super(in, out, err);
+
this.parser = new SubCommandArgumentParser(this.getClass().getName(),
getMessage(MSGID_CONFIGDS_TOOL_DESCRIPTION), false);
- if (in != null) {
- this.in = new BufferedReader(new InputStreamReader(in));
- } else {
- this.in = new BufferedReader(new Reader() {
-
- @Override
- public void close() throws IOException {
- // Do nothing.
- }
-
-
-
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- return -1;
- }
-
- });
- }
-
- if (out != null) {
- this.out = new PrintStream(out);
- } else {
- this.out = NullOutputStream.printStream();
- }
-
- if (err != null) {
- this.err = new PrintStream(err);
- } else {
- this.err = NullOutputStream.printStream();
- }
-
this.factory = factory;
}
/**
- * Interactively confirms whether a user wishes to perform an
- * action. If the application is non-interactive, then the action is
- * granted by default.
- *
- * @param prompt
- * The prompt describing the action.
- * @return Returns <code>true</code> if the user wishes the action
- * to be performed, or <code>false</code> if they refused,
- * or if an exception occurred.
- */
- public boolean confirmAction(String prompt) {
- if (!isInteractive()) {
- return true;
- }
-
- String yes = Messages.getString("general.yes");
- String no = Messages.getString("general.no");
- String errMsg = Messages.getString("general.confirm.error");
- String error = String.format(errMsg, yes, no);
- prompt = prompt + String.format(" (%s / %s): ", yes, no);
-
- while (true) {
- String response;
- try {
- response = readLineOfInput(prompt);
- } catch (Exception e) {
- return false;
- }
-
- if (response == null) {
- // End of input.
- return false;
- }
-
- response = response.toLowerCase().trim();
- if (response.length() == 0) {
- // Empty input.
- err.println(wrapText(error, MAX_LINE_WIDTH));
- } else if (no.startsWith(response)) {
- return false;
- } else if (yes.startsWith(response)) {
- return true;
- } else {
- // Try again...
- err.println(wrapText(error, MAX_LINE_WIDTH));
- }
- }
- }
-
-
-
- /**
- * Displays a message to the error stream.
- *
- * @param msg
- * The message.
- */
- public void displayMessage(String msg) {
- err.println(wrapText(msg, MAX_LINE_WIDTH));
- }
-
-
-
- /**
- * Displays a message to the error stream if verbose mode is
- * enabled.
- *
- * @param msg
- * The verbose message.
- */
- public void displayVerboseMessage(String msg) {
- if (isVerbose()) {
- err.println(wrapText(msg, MAX_LINE_WIDTH));
- }
- }
-
-
-
- /**
* Initializes core APIs for use when dsconfig will be run as a
* standalone application.
*
@@ -350,11 +229,7 @@
/**
- * Indicates whether or not the user has requested interactive
- * behavior.
- *
- * @return Returns <code>true</code> if the user has requested
- * interactive behavior.
+ * {@inheritDoc}
*/
public boolean isInteractive() {
return interactiveArgument.isPresent();
@@ -363,10 +238,7 @@
/**
- * Indicates whether or not the user has requested quiet output.
- *
- * @return Returns <code>true</code> if the user has requested
- * quiet output.
+ * {@inheritDoc}
*/
public boolean isQuiet() {
return quietArgument.isPresent();
@@ -375,11 +247,7 @@
/**
- * Indicates whether or not the user has requested script-friendly
- * output.
- *
- * @return Returns <code>true</code> if the user has requested
- * script-friendly output.
+ * {@inheritDoc}
*/
public boolean isScriptFriendly() {
return scriptFriendlyArgument.isPresent();
@@ -388,10 +256,7 @@
/**
- * Indicates whether or not the user has requested verbose output.
- *
- * @return Returns <code>true</code> if the user has requested
- * verbose output.
+ * {@inheritDoc}
*/
public boolean isVerbose() {
return verboseArgument.isPresent();
@@ -400,59 +265,24 @@
/**
- * Interactively retrieves a line of input from the console.
- *
- * @param prompt
- * The prompt.
- * @return Returns the line of input, or <code>null</code> if the
- * end of input has been reached.
- * @throws Exception
- * If the line of input could not be retrieved for some
- * reason.
+ * {@inheritDoc}
*/
- public String readLineOfInput(String prompt) throws Exception {
- err.print(wrapText(prompt, MAX_LINE_WIDTH));
- return in.readLine();
- }
-
-
-
- /**
- * Interactively retrieves a password from the console.
- *
- * @param prompt
- * The password prompt.
- * @return Returns the password.
- * @throws Exception
- * If the password could not be retrieved for some reason.
- */
- public String readPassword(String prompt) throws Exception {
- err.print(wrapText(prompt, MAX_LINE_WIDTH));
- char[] pwChars = PasswordReader.readPassword();
- return new String(pwChars);
- }
-
-
-
- /**
- * Gets the management context which sub-commands should use in
- * order to manage the directory server.
- *
- * @return Returns the management context which sub-commands should
- * use in order to manage the directory server.
- * @throws ArgumentException
- * If a management context related argument could not be
- * parsed successfully.
- * @throws ClientException
- * If the management context could not be created.
- */
- ManagementContext getManagementContext() throws ArgumentException,
+ public ManagementContext getManagementContext() throws ArgumentException,
ClientException {
return factory.getManagementContext(this);
}
+ // Displays the provided message followed by a help usage reference.
+ private void displayMessageAndUsageReference(String message) {
+ printMessage(message);
+ printMessage("");
+ printMessage(parser.getHelpUsageReference());
+ }
+
+
+
/**
* Registers the global arguments with the argument parser.
*
@@ -478,7 +308,7 @@
// Register the global arguments.
parser.addGlobalArgument(showUsageArgument);
- parser.setUsageArgument(showUsageArgument, out);
+ parser.setUsageArgument(showUsageArgument, getOutputStream());
parser.addGlobalArgument(verboseArgument);
parser.addGlobalArgument(quietArgument);
parser.addGlobalArgument(scriptFriendlyArgument);
@@ -515,7 +345,8 @@
Map<Tag, SortedSet<SubCommand>> groups =
new TreeMap<Tag, SortedSet<SubCommand>>();
SortedSet<SubCommand> allSubCommands = new TreeSet<SubCommand>(c);
- for (SubCommandHandler handler : builder.getSubCommandHandlers(parser)) {
+ for (SubCommandHandler handler : builder.getSubCommandHandlers(this,
+ parser)) {
SubCommand sc = handler.getSubCommand();
handlers.put(sc, handler);
@@ -578,7 +409,7 @@
} catch (ArgumentException e) {
int msgID = MSGID_CANNOT_INITIALIZE_ARGS;
String message = getMessage(msgID, e.getMessage());
- err.println(wrapText(message, MAX_LINE_WIDTH));
+ printMessage(message);
return 1;
}
@@ -588,9 +419,7 @@
} catch (ArgumentException ae) {
int msgID = MSGID_ERROR_PARSING_ARGS;
String message = getMessage(msgID, ae.getMessage());
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -605,9 +434,7 @@
int msgID = MSGID_ERROR_PARSING_ARGS;
String message = getMessage(msgID,
getMessage(MSGID_DSCFG_ERROR_MISSING_SUBCOMMAND));
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -615,9 +442,7 @@
int msgID = MSGID_TOOL_CONFLICTING_ARGS;
String message = getMessage(msgID, quietArgument.getLongIdentifier(),
verboseArgument.getLongIdentifier());
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -625,9 +450,7 @@
int msgID = MSGID_TOOL_CONFLICTING_ARGS;
String message = getMessage(msgID, quietArgument.getLongIdentifier(),
interactiveArgument.getLongIdentifier());
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -635,9 +458,7 @@
int msgID = MSGID_TOOL_CONFLICTING_ARGS;
String message = getMessage(msgID, scriptFriendlyArgument
.getLongIdentifier(), verboseArgument.getLongIdentifier());
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -645,37 +466,44 @@
try {
factory.validateGlobalArguments();
} catch (ArgumentException e) {
- err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+ printMessage(e.getMessage());
return 1;
}
// Retrieve the sub-command implementation and run it.
SubCommandHandler handler = handlers.get(parser.getSubCommand());
try {
- return handler.run(this, out, err);
+ return handler.run();
} catch (ArgumentException e) {
- err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+ printMessage(e.getMessage());
return 1;
} catch (ClientException e) {
// If the client exception was caused by a decoding exception
// then we should display the causes.
- err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+ printMessage(e.getMessage());
Throwable cause = e.getCause();
if (cause instanceof ManagedObjectDecodingException) {
- // FIXME: use a table.
ManagedObjectDecodingException de =
(ManagedObjectDecodingException) cause;
- err.println();
+ printMessage("");
+ TableBuilder builder = new TableBuilder();
for (PropertyException pe : de.getCauses()) {
AbstractManagedObjectDefinition<?, ?> d = de
.getPartialManagedObject().getManagedObjectDefinition();
ArgumentException ae = ArgumentExceptionFactory
.adaptPropertyException(pe, d);
- err.println(wrapText(" * " + ae.getMessage(), MAX_LINE_WIDTH));
+ builder.startRow();
+ builder.appendCell("*");
+ builder.appendCell(ae.getMessage());
}
- err.println();
+
+ TextTablePrinter printer = new TextTablePrinter(getErrorStream());
+ printer.setDisplayHeadings(false);
+ printer.setColumnWidth(1, 0);
+ builder.print(printer);
+ printMessage("");
}
return 1;
@@ -683,7 +511,7 @@
if (debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- err.println(wrapText(StaticUtils.stackTraceToString(e), MAX_LINE_WIDTH));
+ printMessage(StaticUtils.stackTraceToString(e));
return 1;
}
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java
index 426cdf3..c833566 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/DeleteSubCommandHandler.java
@@ -31,7 +31,6 @@
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ToolMessages.*;
-import java.io.PrintStream;
import java.util.List;
import org.opends.server.admin.DefinitionDecodingException;
@@ -45,7 +44,6 @@
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
-import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.tools.ClientException;
@@ -81,6 +79,8 @@
* Creates a new delete-xxx sub-command for an instantiable
* relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param p
@@ -91,10 +91,10 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static DeleteSubCommandHandler create(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<?, ?> r)
- throws ArgumentException {
- return new DeleteSubCommandHandler(parser, p, r, p.child(r, "DUMMY"));
+ public static DeleteSubCommandHandler create(ConsoleApplication app,
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ InstantiableRelationDefinition<?, ?> r) throws ArgumentException {
+ return new DeleteSubCommandHandler(app, parser, p, r, p.child(r, "DUMMY"));
}
@@ -102,6 +102,8 @@
/**
* Creates a new delete-xxx sub-command for an optional relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param p
@@ -112,10 +114,10 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static DeleteSubCommandHandler create(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> p, OptionalRelationDefinition<?, ?> r)
- throws ArgumentException {
- return new DeleteSubCommandHandler(parser, p, r, p.child(r));
+ public static DeleteSubCommandHandler create(ConsoleApplication app,
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ OptionalRelationDefinition<?, ?> r) throws ArgumentException {
+ return new DeleteSubCommandHandler(app, parser, p, r, p.child(r));
}
// The argument which should be used to force deletion.
@@ -137,9 +139,12 @@
// Private constructor.
- private DeleteSubCommandHandler(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> p, RelationDefinition<?, ?> r,
- ManagedObjectPath<?, ?> c) throws ArgumentException {
+ private DeleteSubCommandHandler(ConsoleApplication app,
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ RelationDefinition<?, ?> r, ManagedObjectPath<?, ?> c)
+ throws ArgumentException {
+ super(app);
+
this.path = p;
this.relation = r;
@@ -179,16 +184,14 @@
* {@inheritDoc}
*/
@Override
- public int run(DSConfig app, PrintStream out, PrintStream err)
- throws ArgumentException, ClientException {
+ public int run() throws ArgumentException, ClientException {
// Get the naming argument values.
List<String> names = getNamingArgValues(namingArgs);
// Delete the child managed object.
- ManagementContext context = app.getManagementContext();
ManagedObject<?> parent = null;
try {
- parent = getManagedObject(context, path, names);
+ parent = getManagedObject(path, names);
} catch (AuthorizationException e) {
int msgID = MSGID_DSCFG_ERROR_DELETE_AUTHZ;
String msg = getMessage(msgID, relation.getUserFriendlyName());
@@ -213,8 +216,8 @@
} catch (ConcurrentModificationException e) {
int msgID = MSGID_DSCFG_ERROR_DELETE_CME;
String msg = getMessage(msgID, relation.getUserFriendlyName());
- throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION, msgID,
- msg);
+ throw new ClientException(LDAPResultCode.CONSTRAINT_VIOLATION,
+ msgID, msg);
} catch (ManagedObjectNotFoundException e) {
// Ignore the error if the deletion is being forced.
if (!forceArgument.isPresent()) {
@@ -227,25 +230,28 @@
if (parent != null) {
try {
- // Confirm deletion.
- String prompt = String.format(Messages.getString("delete.confirm"),
- relation.getUserFriendlyName());
- if (!app.confirmAction(prompt)) {
- // Output failure message.
- String msg = String.format(Messages.getString("delete.failed"),
- relation.getUserFriendlyName());
- app.displayVerboseMessage(msg);
- return 1;
- }
-
if (relation instanceof InstantiableRelationDefinition) {
InstantiableRelationDefinition<?, ?> irelation =
(InstantiableRelationDefinition<?, ?>) relation;
- parent.removeChild(irelation, names.get(names.size() - 1));
+ String childName = names.get(names.size() - 1);
+ if (childName == null) {
+ childName = readChildName(parent, irelation, null);
+ }
+
+ if (confirmDeletion()) {
+ parent.removeChild(irelation, childName);
+ } else {
+ return 1;
+ }
} else if (relation instanceof OptionalRelationDefinition) {
OptionalRelationDefinition<?, ?> orelation =
(OptionalRelationDefinition<?, ?>) relation;
- parent.removeChild(orelation);
+
+ if (confirmDeletion()) {
+ parent.removeChild(orelation);
+ } else {
+ return 1;
+ }
}
} catch (AuthorizationException e) {
int msgID = MSGID_DSCFG_ERROR_DELETE_AUTHZ;
@@ -282,9 +288,26 @@
// Output success message.
String msg = String.format(Messages.getString("delete.done"), relation
.getUserFriendlyName());
- app.displayVerboseMessage(msg);
+ getConsoleApplication().printVerboseMessage(msg);
return 0;
}
+
+
+ // Confirm deletion.
+ private boolean confirmDeletion() throws ArgumentException {
+ String prompt = String.format(Messages.getString("delete.confirm"),
+ relation.getUserFriendlyName());
+ if (!getConsoleApplication().confirmAction(prompt)) {
+ // Output failure message.
+ String msg = String.format(Messages.getString("delete.failed"), relation
+ .getUserFriendlyName());
+ getConsoleApplication().printVerboseMessage(msg);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java
index 4519901..9295ddd 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java
@@ -59,7 +59,6 @@
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
-import org.opends.server.admin.client.ManagementContext;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.tools.ClientException;
import org.opends.server.util.args.ArgumentException;
@@ -84,6 +83,8 @@
* Creates a new get-xxx-prop sub-command for an instantiable
* relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param path
@@ -94,15 +95,19 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static GetPropSubCommandHandler create(
+ public static GetPropSubCommandHandler create(ConsoleApplication app,
SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
InstantiableRelationDefinition<?, ?> r) throws ArgumentException {
- return new GetPropSubCommandHandler(parser, path.child(r, "DUMMY"), r);
+ return new GetPropSubCommandHandler(app, parser, path.child(r, "DUMMY"), r);
}
+
+
/**
* Creates a new get-xxx-prop sub-command for an optional relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param path
@@ -113,15 +118,19 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static GetPropSubCommandHandler create(
+ public static GetPropSubCommandHandler create(ConsoleApplication app,
SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
OptionalRelationDefinition<?, ?> r) throws ArgumentException {
- return new GetPropSubCommandHandler(parser, path.child(r), r);
+ return new GetPropSubCommandHandler(app, parser, path.child(r), r);
}
+
+
/**
* Creates a new get-xxx-prop sub-command for a singleton relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param path
@@ -132,10 +141,10 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static GetPropSubCommandHandler create(
+ public static GetPropSubCommandHandler create(ConsoleApplication app,
SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
SingletonRelationDefinition<?, ?> r) throws ArgumentException {
- return new GetPropSubCommandHandler(parser, path.child(r), r);
+ return new GetPropSubCommandHandler(app, parser, path.child(r), r);
}
// The sub-commands naming arguments.
@@ -150,9 +159,11 @@
// Private constructor.
- private GetPropSubCommandHandler(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> path, RelationDefinition<?, ?> r)
- throws ArgumentException {
+ private GetPropSubCommandHandler(ConsoleApplication app,
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
+ RelationDefinition<?, ?> r) throws ArgumentException {
+ super(app);
+
this.path = path;
// Create the sub-command.
@@ -192,21 +203,19 @@
* {@inheritDoc}
*/
@Override
- public int run(DSConfig app, PrintStream out, PrintStream err)
- throws ArgumentException, ClientException {
+ public int run() throws ArgumentException, ClientException {
// Get the property names.
Set<String> propertyNames = getPropertyNames();
PropertyValuePrinter valuePrinter = new PropertyValuePrinter(getSizeUnit(),
- getTimeUnit(), app.isScriptFriendly());
+ getTimeUnit(), getConsoleApplication().isScriptFriendly());
// Get the naming argument values.
List<String> names = getNamingArgValues(namingArgs);
// Get the targeted managed object.
- ManagementContext context = app.getManagementContext();
ManagedObject<?> child;
try {
- child = getManagedObject(context, path, names);
+ child = getManagedObject(path, names);
} catch (AuthorizationException e) {
int msgID = MSGID_DSCFG_ERROR_GET_CHILD_AUTHZ;
String ufn = path.getManagedObjectDefinition().getUserFriendlyName();
@@ -273,11 +282,12 @@
}
if (propertyNames.isEmpty() || propertyNames.contains(pd.getName())) {
- displayProperty(app, builder, child, pd, valuePrinter);
+ displayProperty(builder, child, pd, valuePrinter);
}
}
- if (app.isScriptFriendly()) {
+ PrintStream out = getConsoleApplication().getOutputStream();
+ if (getConsoleApplication().isScriptFriendly()) {
TablePrinter printer = createScriptFriendlyTablePrinter(out);
builder.print(printer);
} else {
@@ -293,9 +303,8 @@
// Display the set of values associated with a property.
- private <T> void displayProperty(final DSConfig app, TableBuilder builder,
- ManagedObject<?> mo, PropertyDefinition<T> pd,
- PropertyValuePrinter valuePrinter) {
+ private <T> void displayProperty(TableBuilder builder, ManagedObject<?> mo,
+ PropertyDefinition<T> pd, PropertyValuePrinter valuePrinter) {
SortedSet<T> values = mo.getPropertyValues(pd);
if (values.isEmpty()) {
// There are no values or default values. Display the default
@@ -313,7 +322,7 @@
public String visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) {
- if (app.isVerbose()) {
+ if (getConsoleApplication().isVerbose()) {
return d.getSynopsis();
} else {
return null;
@@ -351,7 +360,7 @@
String content = pd.getDefaultBehaviorProvider().accept(visitor, null);
if (content == null) {
- if (app.isScriptFriendly()) {
+ if (getConsoleApplication().isScriptFriendly()) {
builder.appendCell();
} else {
builder.appendCell("-");
@@ -370,7 +379,7 @@
builder.startRow();
builder.appendCell(pd.getName());
- if (app.isScriptFriendly()) {
+ if (getConsoleApplication().isScriptFriendly()) {
for (T value : values) {
builder.appendCell(valuePrinter.print(pd, value));
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/HelpCallback.java b/opends/src/server/org/opends/server/tools/dsconfig/HelpCallback.java
new file mode 100644
index 0000000..8412933
--- /dev/null
+++ b/opends/src/server/org/opends/server/tools/dsconfig/HelpCallback.java
@@ -0,0 +1,43 @@
+/*
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.tools.dsconfig;
+
+
+
+/**
+ * An interface for displaying help interactively.
+ */
+interface HelpCallback {
+
+ /**
+ * Displays help to the provided application console.
+ *
+ * @param app
+ * The console application.
+ */
+ void display(ConsoleApplication app);
+}
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 e55d148..319d83a 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java
@@ -294,7 +294,7 @@
* {@inheritDoc}
*/
@Override
- public Void visitUnknown(PropertyDefinition d, PrintStream p)
+ public Void visitUnknown(PropertyDefinition<?> d, PrintStream p)
throws UnknownPropertyDefinitionException {
PropertyDefinitionUsageBuilder usageBuilder =
new PropertyDefinitionUsageBuilder(true);
@@ -458,19 +458,43 @@
/**
* Creates a new help-properties sub-command.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @return Returns the new help-properties sub-command.
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static HelpSubCommandHandler create(SubCommandArgumentParser parser)
+ public static synchronized HelpSubCommandHandler create(
+ ConsoleApplication app, SubCommandArgumentParser parser)
throws ArgumentException {
- return new HelpSubCommandHandler(parser);
+ if (INSTANCE == null) {
+ INSTANCE = new HelpSubCommandHandler(app, parser);
+ }
+ return INSTANCE;
}
+ /**
+ * Gets the application-wide help sub-command handler.
+ *
+ * @return Returns the application-wide help sub-command handler.
+ */
+ public static synchronized HelpSubCommandHandler getInstance() {
+ if (INSTANCE == null) {
+ throw new RuntimeException("Help sub-command handler not initialized");
+ } else {
+ return INSTANCE;
+ }
+ }
+
+
+
+ // The singleton instance.
+ private static HelpSubCommandHandler INSTANCE = null;
+
// The sub-command associated with this handler.
private final SubCommand subCommand;
@@ -482,8 +506,10 @@
private final Map<String, AbstractManagedObjectDefinition<?, ?>> types;
// Private constructor.
- private HelpSubCommandHandler(SubCommandArgumentParser parser)
- throws ArgumentException {
+ private HelpSubCommandHandler(ConsoleApplication app,
+ SubCommandArgumentParser parser) throws ArgumentException {
+ super(app);
+
// Create the sub-command.
String name = "list-properties";
int descriptionID = MSGID_DSCFG_DESCRIPTION_SUBCMD_HELPPROP;
@@ -649,7 +675,7 @@
* {@inheritDoc}
*/
@Override
- public int run(DSConfig app, PrintStream out, PrintStream err)
+ public int run()
throws ArgumentException, ClientException {
String typeName = typeArgument.getValue();
Set<String> propertyNames = getPropertyNames();
@@ -682,10 +708,10 @@
defns = Collections.<AbstractManagedObjectDefinition<?, ?>> singleton(d);
}
- if (!app.isVerbose()) {
- displayNonVerbose(app, out, err, defns, propertyNames);
+ if (!getConsoleApplication().isVerbose()) {
+ displayNonVerbose(defns, propertyNames);
} else {
- displayVerbose(app, out, err, defns, propertyNames);
+ displayVerbose(defns, propertyNames);
}
return 0;
}
@@ -693,10 +719,11 @@
// Output property summary table.
- private void displayNonVerbose(DSConfig app, PrintStream out,
- PrintStream err, Collection<AbstractManagedObjectDefinition<?, ?>> defns,
+ private void displayNonVerbose(
+ Collection<AbstractManagedObjectDefinition<?, ?>> defns,
Set<String> propertyNames) {
- if (!app.isScriptFriendly()) {
+ PrintStream out = getConsoleApplication().getOutputStream();
+ if (!getConsoleApplication().isScriptFriendly()) {
out.println(DESCRIPTION_OPTIONS_TITLE);
out.println();
out.print(" r -- ");
@@ -728,7 +755,7 @@
// Generate the table content.
for (AbstractManagedObjectDefinition<?, ?> mod : defns) {
Collection<PropertyDefinition<?>> pds;
- if (app.isScriptFriendly()) {
+ if (getConsoleApplication().isScriptFriendly()) {
pds = mod.getAllPropertyDefinitions();
} else {
pds = mod.getPropertyDefinitions();
@@ -767,7 +794,7 @@
}
TablePrinter printer;
- if (app.isScriptFriendly()) {
+ if (getConsoleApplication().isScriptFriendly()) {
printer = createScriptFriendlyTablePrinter(out);
} else {
printer = new TextTablePrinter(out);
@@ -778,9 +805,11 @@
// Display detailed help on managed objects and their properties.
- private void displayVerbose(DSConfig app, PrintStream out, PrintStream err,
+ private void displayVerbose(
Collection<AbstractManagedObjectDefinition<?, ?>> defns,
Set<String> propertyNames) {
+ PrintStream out = getConsoleApplication().getOutputStream();
+
// Construct line used to separate consecutive sections.
char[] c1 = new char[MAX_LINE_WIDTH];
Arrays.fill(c1, '=');
@@ -843,71 +872,6 @@
- // Display description of the single managed object.
- /*private void displaySummaryForSingleManagedObject(DSConfig app,
- PrintStream out, PrintStream err,
- AbstractManagedObjectDefinition<?, ?> d, Set<String> propertyNames) {
-
- // Display the title.
- out.println(wrapText(String.format(HEADING_MANAGED_OBJECT, d
- .getUserFriendlyName()), MAX_LINE_WIDTH));
-
- out.println();
- out.println(wrapText(d.getSynopsis(), MAX_LINE_WIDTH));
- if (d.getDescription() != null) {
- out.println();
- out.println(wrapText(d.getDescription(), MAX_LINE_WIDTH));
- }
-
- // Output table of properties.
- TableBuilder builder = new TableBuilder();
-
- // Headings.
- builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_NAME));
- builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_OPTIONS));
- builder.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_SYNTAX));
-
- // Sort keys.
- builder.addSortKey(0);
-
- // Generate the table content.
- for (String name : propertyNames) {
- PropertyDefinition<?> pd = d.getPropertyDefinition(name);
-
- if (pd.hasOption(PropertyOption.HIDDEN)) {
- continue;
- }
-
- // Display a property.
- builder.startRow();
- builder.appendCell(pd.getName());
-
- // Display the options.
- builder.appendCell(getPropertyOptionSummary(pd));
-
- // Display the syntax.
- PropertyDefinitionUsageBuilder v =
- new PropertyDefinitionUsageBuilder(false);
- String syntax = v.getUsage(pd);
- if (syntax.length() < 40) {
- builder.appendCell(syntax);
- } else {
- String msg = getMessage(MSGID_DSCFG_DESCRIPTION_PROPERTY_SYNTAX_HELP);
- builder.appendCell(msg);
- }
- }
-
- TextTablePrinter factory = new TextTablePrinter(out);
-
- // Let the syntax column be expandable.
- factory.setColumnWidth(2, 0);
-
- out.println();
- builder.print(factory);
- }*/
-
-
-
// Compute the options field.
private String getPropertyOptionSummary(PropertyDefinition<?> pd) {
StringBuilder b = new StringBuilder();
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/InternalManagementContextFactory.java b/opends/src/server/org/opends/server/tools/dsconfig/InternalManagementContextFactory.java
index 98ee7ca..27874ed 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/InternalManagementContextFactory.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/InternalManagementContextFactory.java
@@ -63,7 +63,7 @@
/**
* {@inheritDoc}
*/
- public ManagementContext getManagementContext(DSConfig app)
+ public ManagementContext getManagementContext(ConsoleApplication app)
throws ArgumentException, ClientException {
return context;
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/LDAPManagementContextFactory.java b/opends/src/server/org/opends/server/tools/dsconfig/LDAPManagementContextFactory.java
index b6804f8..4954fb0 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/LDAPManagementContextFactory.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/LDAPManagementContextFactory.java
@@ -94,7 +94,7 @@
/**
* {@inheritDoc}
*/
- public ManagementContext getManagementContext(DSConfig app)
+ public ManagementContext getManagementContext(ConsoleApplication app)
throws ArgumentException, ClientException {
// Lazily create the LDAP management context.
if (context == null) {
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java
index 5bb2598..68cc6dc 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java
@@ -51,7 +51,6 @@
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
-import org.opends.server.admin.client.ManagementContext;
import org.opends.server.protocols.ldap.LDAPResultCode;
import org.opends.server.tools.ClientException;
import org.opends.server.util.args.ArgumentException;
@@ -75,6 +74,8 @@
/**
* Creates a new list-xxx sub-command for an instantiable relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param p
@@ -85,10 +86,10 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static ListSubCommandHandler create(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<?, ?> r)
- throws ArgumentException {
- return new ListSubCommandHandler(parser, p, r, r.getPluralName(), r
+ public static ListSubCommandHandler create(ConsoleApplication app,
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ InstantiableRelationDefinition<?, ?> r) throws ArgumentException {
+ return new ListSubCommandHandler(app, parser, p, r, r.getPluralName(), r
.getUserFriendlyPluralName());
}
@@ -97,6 +98,8 @@
/**
* Creates a new list-xxx sub-command for an optional relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param p
@@ -107,10 +110,10 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static ListSubCommandHandler create(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> p, OptionalRelationDefinition<?, ?> r)
- throws ArgumentException {
- return new ListSubCommandHandler(parser, p, r, r.getName(), r
+ public static ListSubCommandHandler create(ConsoleApplication app,
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ OptionalRelationDefinition<?, ?> r) throws ArgumentException {
+ return new ListSubCommandHandler(app, parser, p, r, r.getName(), r
.getUserFriendlyName());
}
@@ -129,9 +132,12 @@
// Private constructor.
- private ListSubCommandHandler(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> p, RelationDefinition<?, ?> r, String rname,
- String rufn) throws ArgumentException {
+ private ListSubCommandHandler(ConsoleApplication app,
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> p,
+ RelationDefinition<?, ?> r, String rname, String rufn)
+ throws ArgumentException {
+ super(app);
+
this.path = p;
this.relation = r;
@@ -169,7 +175,7 @@
* {@inheritDoc}
*/
@Override
- public int run(DSConfig app, PrintStream out, PrintStream err)
+ public int run()
throws ArgumentException, ClientException {
// Get the property names.
Set<String> propertyNames = getPropertyNames();
@@ -181,7 +187,7 @@
}
PropertyValuePrinter valuePrinter = new PropertyValuePrinter(getSizeUnit(),
- getTimeUnit(), app.isScriptFriendly());
+ getTimeUnit(), getConsoleApplication().isScriptFriendly());
// Get the naming argument values.
List<String> names = getNamingArgValues(namingArgs);
@@ -196,10 +202,9 @@
}
// List the children.
- ManagementContext context = app.getManagementContext();
ManagedObject<?> parent;
try {
- parent = getManagedObject(context, path, names);
+ parent = getManagedObject(path, names);
} catch (AuthorizationException e) {
int msgID = MSGID_DSCFG_ERROR_LIST_AUTHZ;
String msg = getMessage(msgID, ufn);
@@ -315,8 +320,9 @@
}
// Output the results.
- if (app.isScriptFriendly()) {
+ if (getConsoleApplication().isScriptFriendly()) {
// Output just the names of the children.
+ PrintStream out = getConsoleApplication().getOutputStream();
for (String name : children.keySet()) {
out.println(name);
}
@@ -359,11 +365,11 @@
for (String propertyName : propertyNames) {
try {
PropertyDefinition<?> pd = d.getPropertyDefinition(propertyName);
- displayProperty(app, builder, child, pd, valuePrinter);
+ displayProperty(builder, child, pd, valuePrinter);
} catch (IllegalArgumentException e) {
// Assume this child managed object does not support this
// property.
- if (app.isScriptFriendly()) {
+ if (getConsoleApplication().isScriptFriendly()) {
builder.appendCell();
} else {
builder.appendCell("-");
@@ -372,7 +378,8 @@
}
}
- if (app.isScriptFriendly()) {
+ PrintStream out = getConsoleApplication().getOutputStream();
+ if (getConsoleApplication().isScriptFriendly()) {
TablePrinter printer = createScriptFriendlyTablePrinter(out);
builder.print(printer);
} else {
@@ -388,12 +395,11 @@
// Display the set of values associated with a property.
- private <T> void displayProperty(DSConfig app, TableBuilder builder,
- ManagedObject<?> mo, PropertyDefinition<T> pd,
- PropertyValuePrinter valuePrinter) {
+ private <T> void displayProperty(TableBuilder builder, ManagedObject<?> mo,
+ PropertyDefinition<T> pd, PropertyValuePrinter valuePrinter) {
SortedSet<T> values = mo.getPropertyValues(pd);
if (values.isEmpty()) {
- if (app.isScriptFriendly()) {
+ if (getConsoleApplication().isScriptFriendly()) {
builder.appendCell();
} else {
builder.appendCell("-");
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/ManagementContextFactory.java b/opends/src/server/org/opends/server/tools/dsconfig/ManagementContextFactory.java
index c4372f7..05aa008 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/ManagementContextFactory.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/ManagementContextFactory.java
@@ -59,8 +59,8 @@
* @throws ClientException
* If the management context could not be created.
*/
- ManagementContext getManagementContext(DSConfig app) throws ArgumentException,
- ClientException;
+ ManagementContext getManagementContext(ConsoleApplication app)
+ throws ArgumentException, ClientException;
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
index fac8445..7a99ff4 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/SetPropSubCommandHandler.java
@@ -31,7 +31,6 @@
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ToolMessages.*;
-import java.io.PrintStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -57,7 +56,6 @@
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.ManagedObjectDecodingException;
-import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.protocols.ldap.LDAPResultCode;
@@ -144,6 +142,8 @@
* Creates a new set-xxx-prop sub-command for an instantiable
* relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param path
@@ -154,10 +154,10 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static SetPropSubCommandHandler create(
+ public static SetPropSubCommandHandler create(ConsoleApplication app,
SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
InstantiableRelationDefinition<?, ?> r) throws ArgumentException {
- return new SetPropSubCommandHandler(parser, path.child(r, "DUMMY"), r);
+ return new SetPropSubCommandHandler(app, parser, path.child(r, "DUMMY"), r);
}
@@ -165,6 +165,8 @@
/**
* Creates a new set-xxx-prop sub-command for an optional relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param path
@@ -175,10 +177,10 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static SetPropSubCommandHandler create(
+ public static SetPropSubCommandHandler create(ConsoleApplication app,
SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
OptionalRelationDefinition<?, ?> r) throws ArgumentException {
- return new SetPropSubCommandHandler(parser, path.child(r), r);
+ return new SetPropSubCommandHandler(app, parser, path.child(r), r);
}
@@ -186,6 +188,8 @@
/**
* Creates a new set-xxx-prop sub-command for a singleton relation.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @param path
@@ -196,10 +200,10 @@
* @throws ArgumentException
* If the sub-command could not be created successfully.
*/
- public static SetPropSubCommandHandler create(
+ public static SetPropSubCommandHandler create(ConsoleApplication app,
SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
SingletonRelationDefinition<?, ?> r) throws ArgumentException {
- return new SetPropSubCommandHandler(parser, path.child(r), r);
+ return new SetPropSubCommandHandler(app, parser, path.child(r), r);
}
// The sub-commands naming arguments.
@@ -230,9 +234,11 @@
// Private constructor.
- private SetPropSubCommandHandler(SubCommandArgumentParser parser,
- ManagedObjectPath<?, ?> path, RelationDefinition<?, ?> r)
- throws ArgumentException {
+ private SetPropSubCommandHandler(ConsoleApplication app,
+ SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path,
+ RelationDefinition<?, ?> r) throws ArgumentException {
+ super(app);
+
this.path = path;
// Create the sub-command.
@@ -289,15 +295,14 @@
*/
@SuppressWarnings("unchecked")
@Override
- public int run(DSConfig app, PrintStream out, PrintStream err)
+ public int run()
throws ArgumentException, ClientException {
// Get the naming argument values.
List<String> names = getNamingArgValues(namingArgs);
- ManagementContext context = app.getManagementContext();
ManagedObject<?> child;
try {
- child = getManagedObject(context, path, names);
+ child = getManagedObject(path, names);
} catch (AuthorizationException e) {
int msgID = MSGID_DSCFG_ERROR_MODIFY_AUTHZ;
String ufn = path.getManagedObjectDefinition().getUserFriendlyName();
@@ -493,11 +498,11 @@
// Confirm commit.
String prompt = String.format(Messages.getString("modify.confirm"), d
.getUserFriendlyName());
- if (!app.confirmAction(prompt)) {
+ if (!getConsoleApplication().confirmAction(prompt)) {
// Output failure message.
String msg = String.format(Messages.getString("modify.failed"), d
.getUserFriendlyName());
- app.displayVerboseMessage(msg);
+ getConsoleApplication().printVerboseMessage(msg);
return 1;
}
@@ -506,7 +511,7 @@
// Output success message.
String msg = String.format(Messages.getString("modify.done"), d
.getUserFriendlyName());
- app.displayVerboseMessage(msg);
+ getConsoleApplication().printVerboseMessage(msg);
} catch (MissingMandatoryPropertiesException e) {
throw ArgumentExceptionFactory.adaptMissingMandatoryPropertiesException(
e, d);
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandBuilder.java b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandBuilder.java
index 30dd180..665d789 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandBuilder.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandBuilder.java
@@ -61,6 +61,9 @@
private static final class Visitor implements
RelationDefinitionVisitor<Void, ManagedObjectPath<?, ?>> {
+ // The application.
+ private final ConsoleApplication app;
+
// Any exception that occurred whilst creating the sub-commands.
private ArgumentException exception = null;
@@ -74,7 +77,8 @@
private final SubCommandArgumentParser parser;
// Private constructor.
- private Visitor(SubCommandArgumentParser parser) {
+ private Visitor(ConsoleApplication app, SubCommandArgumentParser parser) {
+ this.app = app;
this.parser = parser;
}
@@ -93,7 +97,7 @@
handlers = new LinkedList<SubCommandHandler>();
// We always need a help properties sub-command handler.
- helpHandler = HelpSubCommandHandler.create(parser);
+ helpHandler = HelpSubCommandHandler.create(app, parser);
handlers.add(helpHandler);
processPath(ManagedObjectPath.emptyPath());
@@ -126,11 +130,11 @@
ManagedObjectPath<?, ?> p) {
try {
// Create the sub-commands.
- handlers.add(CreateSubCommandHandler.create(parser, p, r));
- handlers.add(DeleteSubCommandHandler.create(parser, p, r));
- handlers.add(ListSubCommandHandler.create(parser, p, r));
- handlers.add(GetPropSubCommandHandler.create(parser, p, r));
- handlers.add(SetPropSubCommandHandler.create(parser, p, r));
+ handlers.add(CreateSubCommandHandler.create(app, parser, p, r));
+ handlers.add(DeleteSubCommandHandler.create(app, parser, p, r));
+ handlers.add(ListSubCommandHandler.create(app, parser, p, r));
+ handlers.add(GetPropSubCommandHandler.create(app, parser, p, r));
+ handlers.add(SetPropSubCommandHandler.create(app, parser, p, r));
// Process the referenced managed object definition and its
// sub-types.
@@ -151,11 +155,11 @@
ManagedObjectPath<?, ?> p) {
try {
// Create the sub-commands.
- handlers.add(CreateSubCommandHandler.create(parser, p, r));
- handlers.add(DeleteSubCommandHandler.create(parser, p, r));
- handlers.add(ListSubCommandHandler.create(parser, p, r));
- handlers.add(GetPropSubCommandHandler.create(parser, p, r));
- handlers.add(SetPropSubCommandHandler.create(parser, p, r));
+ handlers.add(CreateSubCommandHandler.create(app, parser, p, r));
+ handlers.add(DeleteSubCommandHandler.create(app, parser, p, r));
+ handlers.add(ListSubCommandHandler.create(app, parser, p, r));
+ handlers.add(GetPropSubCommandHandler.create(app, parser, p, r));
+ handlers.add(SetPropSubCommandHandler.create(app, parser, p, r));
// Process the referenced managed object definition and its
// sub-types.
@@ -176,8 +180,8 @@
ManagedObjectPath<?, ?> p) {
try {
// Create the sub-commands.
- handlers.add(GetPropSubCommandHandler.create(parser, p, r));
- handlers.add(SetPropSubCommandHandler.create(parser, p, r));
+ handlers.add(GetPropSubCommandHandler.create(app, parser, p, r));
+ handlers.add(SetPropSubCommandHandler.create(app, parser, p, r));
// Process the referenced managed object definition and its
// sub-types.
@@ -281,6 +285,8 @@
/**
* Get the set of sub-command handlers constructed by this builder.
*
+ * @param app
+ * The console application.
* @param parser
* The sub-command argument parser.
* @return Returns the set of sub-command handlers constructed by
@@ -289,8 +295,9 @@
* If a sub-command could not be created successfully.
*/
public Collection<SubCommandHandler> getSubCommandHandlers(
- SubCommandArgumentParser parser) throws ArgumentException {
- Visitor v = new Visitor(parser);
+ ConsoleApplication app, SubCommandArgumentParser parser)
+ throws ArgumentException {
+ Visitor v = new Visitor(app, parser);
return v.getSubCommandHandlers();
}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java
index a82d0d6..ac32ec1 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java
@@ -82,12 +82,10 @@
* A path serializer which is used to retrieve a managed object
* based on a path and a list of path arguments.
*/
- private static class ManagedObjectFinder implements
- ManagedObjectPathSerializer {
+ private class ManagedObjectFinder implements ManagedObjectPathSerializer {
// Any argument exception that was caught when attempting to find
- // the
- // managed object.
+ // the managed object.
private ArgumentException ae;
// The index of the next path argument to be retrieved.
@@ -103,8 +101,7 @@
private ConcurrentModificationException cme;
// Any operation exception that was caught when attempting to find
- // the
- // managed object.
+ // the managed object.
private DefinitionDecodingException dde;
// Flag indicating whether or not an exception occurred during
@@ -133,6 +130,18 @@
String childName = args.get(argIndex++);
try {
+ // If the name is null then we must be interactive - so let
+ // the user choose.
+ if (childName == null) {
+ try {
+ childName = readChildName(managedObject, r, d);
+ } catch (ArgumentException e) {
+ ae = e;
+ gotException = true;
+ return;
+ }
+ }
+
ManagedObject<?> child = managedObject.getChild(r, childName);
// Check that child is a sub-type of the specified
@@ -377,14 +386,14 @@
// arguments.
private ArgumentException e = null;
- // The sub-command.
- private final SubCommand subCommand;
-
// Indicates whether the sub-command is a create-xxx
// sub-command, in which case the final path element will
// have different usage information.
private final boolean isCreate;
+ // The sub-command.
+ private final SubCommand subCommand;
+
// The number of path elements to expect.
private int sz;
@@ -435,17 +444,17 @@
PropertyDefinitionUsageBuilder b =
new PropertyDefinitionUsageBuilder(false);
String usage = "{" + b.getUsage(pd) + "}";
- arg = new StringArgument(argName, null, argName, true, true, usage,
- MSGID_DSCFG_DESCRIPTION_NAME_CREATE_EXT, d
+ arg = new StringArgument(argName, null, argName, false, true,
+ usage, MSGID_DSCFG_DESCRIPTION_NAME_CREATE_EXT, d
.getUserFriendlyName(), pd.getName(), pd.getSynopsis());
} else {
- arg = new StringArgument(argName, null, argName, true, true,
+ arg = new StringArgument(argName, null, argName, false, true,
"{NAME}", MSGID_DSCFG_DESCRIPTION_NAME_CREATE, d
.getUserFriendlyName());
}
} else {
// A normal naming argument.
- arg = new StringArgument(argName, null, argName, true, true,
+ arg = new StringArgument(argName, null, argName, false, true,
"{NAME}", MSGID_DSCFG_DESCRIPTION_NAME, d.getUserFriendlyName());
}
subCommand.addArgument(arg);
@@ -534,6 +543,9 @@
// The argument which should be used to request advanced mode.
private BooleanArgument advancedModeArgument;
+ // The application instance.
+ private final ConsoleApplication app;
+
// The argument which should be used to specify zero or more
// property names.
private StringArgument propertyArgument;
@@ -554,9 +566,12 @@
/**
* Create a new sub-command handler.
+ *
+ * @param app
+ * The application instance.
*/
- protected SubCommandHandler() {
- // No implementation required.
+ protected SubCommandHandler(ConsoleApplication app) {
+ this.app = app;
}
@@ -585,12 +600,6 @@
/**
* Run this sub-command handler.
*
- * @param app
- * The application.
- * @param out
- * The application output stream.
- * @param err
- * The application error stream.
* @return Returns zero if the sub-command completed successfully or
* non-zero if it did not.
* @throws ArgumentException
@@ -599,8 +608,7 @@
* @throws ClientException
* If the management context could not be created.
*/
- public abstract int run(DSConfig app, PrintStream out, PrintStream err)
- throws ArgumentException, ClientException;
+ public abstract int run() throws ArgumentException, ClientException;
@@ -685,11 +693,20 @@
/**
+ * Gets the console application instance.
+ *
+ * @return Returns the console application instance.
+ */
+ protected final ConsoleApplication getConsoleApplication() {
+ return app;
+ }
+
+
+
+ /**
* Get the managed object referenced by the provided managed object
* path.
*
- * @param context
- * The management context.
* @param path
* The managed object path.
* @param args
@@ -718,15 +735,17 @@
* @throws ArgumentException
* If one of the naming arguments referenced a managed
* object of the wrong type.
+ * @throws ClientException
+ * If the management context could not be created.
*/
- protected final ManagedObject<?> getManagedObject(ManagementContext context,
+ protected final ManagedObject<?> getManagedObject(
ManagedObjectPath<?, ?> path, List<String> args)
throws ArgumentException, AuthorizationException,
DefinitionDecodingException, ManagedObjectDecodingException,
CommunicationException, ConcurrentModificationException,
- ManagedObjectNotFoundException {
+ ManagedObjectNotFoundException, ClientException {
ManagedObjectFinder finder = new ManagedObjectFinder();
- return finder.find(context, path, args);
+ return finder.find(app.getManagementContext(), path, args);
}
@@ -737,12 +756,22 @@
* @param namingArgs
* The naming arguments.
* @return Returns the values of the naming arguments.
+ * @throws ArgumentException
+ * If one of the naming arguments is missing and the
+ * application is non-interactive.
*/
protected final List<String> getNamingArgValues(
- List<StringArgument> namingArgs) {
+ List<StringArgument> namingArgs) throws ArgumentException {
ArrayList<String> values = new ArrayList<String>(namingArgs.size());
for (StringArgument arg : namingArgs) {
- values.add(arg.getValue());
+ String value = arg.getValue();
+
+ if (value == null && !app.isInteractive()) {
+ throw ArgumentExceptionFactory
+ .missingMandatoryNonInteractiveArgument(arg);
+ } else {
+ values.add(value);
+ }
}
return values;
}
@@ -854,6 +883,81 @@
/**
+ * Interactively prompts the user to select from a choice of child
+ * managed objects.
+ * <p>
+ * This method will adapt according to the available choice. For
+ * example, if there is only one choice, then a question will be
+ * asked. If there are no children then an
+ * <code>ArgumentException</code> will be thrown.
+ *
+ * @param <C>
+ * The type of child client configuration.
+ * @param <S>
+ * The type of child server configuration.
+ * @param parent
+ * The parent managed object.
+ * @param r
+ * The relation between the parent and the children.
+ * @param d
+ * The type of child managed object to choose from.
+ * @return Returns the name of the managed object that the user
+ * selected.
+ * @throws CommunicationException
+ * If the server cannot be contacted.
+ * @throws ConcurrentModificationException
+ * If the parent managed object has been deleted.
+ * @throws AuthorizationException
+ * If the children cannot be listed due to an
+ * authorization failure.
+ * @throws ArgumentException
+ * If the user input can be read from the console or if
+ * there are no children.
+ */
+ protected final <C extends ConfigurationClient, S extends Configuration>
+ String readChildName(ManagedObject<?> parent,
+ InstantiableRelationDefinition<C, S> r,
+ AbstractManagedObjectDefinition<? extends C, ? extends S> d)
+ throws AuthorizationException, ConcurrentModificationException,
+ CommunicationException, ArgumentException {
+ if (d == null) {
+ d = r.getChildDefinition();
+ }
+
+ String[] children = parent.listChildren(r, d);
+ switch (children.length) {
+ case 0: {
+ // No options available - abort.
+ int msgID = MSGID_DSCFG_ERROR_FINDER_NO_CHILDREN;
+ String msg = getMessage(msgID, d.getUserFriendlyPluralName());
+ throw new ArgumentException(msgID, msg);
+ }
+ case 1: {
+ // Only one option available so confirm that the user wishes to
+ // access it.
+ int msgID = MSGID_DSCFG_FINDER_PROMPT_SINGLE;
+ String msg = getMessage(msgID, d.getUserFriendlyName(), children[0]);
+ if (getConsoleApplication().confirmAction(msg)) {
+ return children[0];
+ } else {
+ msgID = MSGID_DSCFG_ERROR_FINDER_SINGLE_CHILD_REJECTED;
+ msg = getMessage(msgID, d.getUserFriendlyName());
+ throw new ArgumentException(msgID, msg);
+ }
+ }
+ default: {
+ // Display a menu.
+ List<String> choices = Arrays.asList(children);
+ int msgID = MSGID_DSCFG_FINDER_PROMPT_MANY;
+ String msg = getMessage(msgID, d.getUserFriendlyName());
+ return getConsoleApplication().readChoice(msg, choices, choices, null);
+ }
+ }
+ }
+
+
+
+ /**
* Registers the advanced mode argument with the sub-command.
*
* @param subCommand
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/ValidationCallback.java b/opends/src/server/org/opends/server/tools/dsconfig/ValidationCallback.java
new file mode 100644
index 0000000..a8f7750
--- /dev/null
+++ b/opends/src/server/org/opends/server/tools/dsconfig/ValidationCallback.java
@@ -0,0 +1,59 @@
+/*
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * 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
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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
+ *
+ *
+ * Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+package org.opends.server.tools.dsconfig;
+
+import org.opends.server.tools.ClientException;
+
+
+
+/**
+ * An interface for validating user input.
+ *
+ * @param <T>
+ * The type of the decoded input.
+ */
+interface ValidationCallback<T> {
+
+ /**
+ * Validates and decodes the user-provided input. Implementations
+ * must validate <code>input</code> and return the decoded value
+ * if the input is acceptable. If the input is unacceptable,
+ * implementations must return <code>null</code> and output a user
+ * friendly error message to the provided application console.
+ *
+ * @param app
+ * The console application.
+ * @param input
+ * The user input to be validated.
+ * @return Returns the decoded input if the input is valid, or
+ * <code>null</code> if it is not.
+ * @throws ClientException
+ * If an unexpected error occurred which prevented
+ * validation.
+ */
+ T validate(ConsoleApplication app, String input) throws ClientException;
+}
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/messages.properties b/opends/src/server/org/opends/server/tools/dsconfig/messages.properties
index 7f69963..1d7d440 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/messages.properties
+++ b/opends/src/server/org/opends/server/tools/dsconfig/messages.properties
@@ -1,6 +1,3 @@
-general.no=no
-general.yes=yes
-general.confirm.error=Invalid response. Please enter "%s" or "%s".
help-properties.field.enum=one of the following values:
help-properties.field.undefined=undefined
help-properties.field.inherits.abs=inherits from the property "%s" in the %s.
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java
index e574a5c..79b53db 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgClient.java
@@ -244,7 +244,7 @@
* If the name is invalid.
*/
<C extends TestChildCfgClient> C createTestChild(
- ManagedObjectDefinition<C, ?> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException;
+ ManagedObjectDefinition<C, ? extends TestChildCfg> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException;
@@ -343,7 +343,7 @@
* @return Returns a new Optional Test Child configuration instance.
*/
<C extends TestChildCfgClient> C createOptionalTestChild(
- ManagedObjectDefinition<C, ?> d, Collection<DefaultBehaviorException> exceptions);
+ ManagedObjectDefinition<C, ? extends TestChildCfg> d, Collection<DefaultBehaviorException> exceptions);
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
index f169502..c0e9042 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/TestParentCfgDefn.java
@@ -427,7 +427,7 @@
* {@inheritDoc}
*/
public <M extends TestChildCfgClient> M createTestChild(
- ManagedObjectDefinition<M, ?> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException {
+ ManagedObjectDefinition<M, ? extends TestChildCfg> d, String name, Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException {
return impl.createChild(INSTANCE.getTestChildrenRelationDefinition(), d, name, exceptions).getConfiguration();
}
@@ -470,7 +470,7 @@
* {@inheritDoc}
*/
public <M extends TestChildCfgClient> M createOptionalTestChild(
- ManagedObjectDefinition<M, ?> d, Collection<DefaultBehaviorException> exceptions) {
+ ManagedObjectDefinition<M, ? extends TestChildCfg> d, Collection<DefaultBehaviorException> exceptions) {
return impl.createChild(INSTANCE.getOptionalTestChildRelationDefinition(), d, exceptions).getConfiguration();
}
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java
index cda4bc3..1b2589d 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/ldap/MockLDAPConnection.java
@@ -209,7 +209,7 @@
* {@inheritDoc}
*/
@Override
- public Collection<LdapName> listEntries(LdapName dn) throws NamingException {
+ public Collection<LdapName> listEntries(LdapName dn, String filter) throws NamingException {
MockEntry entry = getEntry(dn);
if (entry == null) {
--
Gitblit v1.10.0