Partial fix for issue 1831 - dsconfig interactive mode.
With this change, dsconfig now prompts for component names if they are not specified on the command-line. Where more than one choice is available, dsconfig displays a list of choices. For create-xxx sub-commands dsconfig also prompts for the component type (-t flag) if it is not specified. Users can, at this point, request help which displays a detailed description of each type.
A subsequent change will add support for interactively setting property values.
A major part of this change includes improvements to the type-safety of the client admin APIs (e.g. use of raw types), which were being flagged in the latest version of Eclipse (apologies: I should have committed these separately, but they got too tangled up in this change).
3 files added
48 files modified
| | |
| | | </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> |
| | |
| | | </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> |
| | |
| | | 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> |
| | |
| | | ' * {@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> |
| | |
| | | ' * {@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> |
| | |
| | | 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; |
| | |
| | | * @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; |
| | | } |
| | | |
| | |
| | | * 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"); |
| | |
| | | * 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"); |
| | |
| | | * @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); |
| | |
| | | * @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); |
| | |
| | | * @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); |
| | |
| | | |
| | | // 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; |
| | |
| | | * The path identifying the location of the referenced |
| | | * managed objects. |
| | | */ |
| | | public void setPath(ManagedObjectPath path) { |
| | | public void setPath(ManagedObjectPath<?, ?> path) { |
| | | this.path = path; |
| | | } |
| | | |
| | |
| | | |
| | | // 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; |
| | |
| | | |
| | | // 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); |
| | | |
| | |
| | | * @return Returns the path identifying the location of the |
| | | * referenced managed objects. |
| | | */ |
| | | public ManagedObjectPath getPath() { |
| | | public ManagedObjectPath<?, ?> getPath() { |
| | | return path; |
| | | } |
| | | |
| | |
| | | * 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; |
| | | } |
| | |
| | | * @param value |
| | | * The illegal property value. |
| | | */ |
| | | public IllegalPropertyValueException(PropertyDefinition d, Object value) { |
| | | public IllegalPropertyValueException(PropertyDefinition<?> d, Object value) { |
| | | super(d); |
| | | this.value = value; |
| | | } |
| | |
| | | * @param value |
| | | * The illegal property value string. |
| | | */ |
| | | public IllegalPropertyValueStringException(PropertyDefinition d, |
| | | public IllegalPropertyValueStringException(PropertyDefinition<?> d, |
| | | String value) { |
| | | super(d); |
| | | this.value = value; |
| | |
| | | |
| | | |
| | | // Mapping from definition to locale-based resource bundle. |
| | | private final Map<AbstractManagedObjectDefinition, |
| | | private final Map<AbstractManagedObjectDefinition<?, ?>, |
| | | Map<Locale, ResourceBundle>> resources; |
| | | |
| | | |
| | |
| | | |
| | | // Private constructor. |
| | | private ManagedObjectDefinitionI18NResource(String prefix) { |
| | | this.resources = new HashMap<AbstractManagedObjectDefinition, |
| | | this.resources = new HashMap<AbstractManagedObjectDefinition<?, ?>, |
| | | Map<Locale, ResourceBundle>>(); |
| | | this.prefix = prefix; |
| | | } |
| | |
| | | * @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); |
| | | } |
| | |
| | | * @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); |
| | | } |
| | |
| | | * @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); |
| | |
| | | * @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); |
| | | } |
| | |
| | | // 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. |
| | |
| | | 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; |
| | |
| | | // Private constructor. |
| | | private ManagedObjectDefinitionResource(String prefix) { |
| | | this.properties = |
| | | new HashMap<AbstractManagedObjectDefinition, Properties>(); |
| | | new HashMap<AbstractManagedObjectDefinition<?, ?>, Properties>(); |
| | | this.prefix = prefix; |
| | | } |
| | | |
| | |
| | | * @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); |
| | |
| | | // lazily |
| | | // loading it if necessary. |
| | | private synchronized Properties getProperties( |
| | | AbstractManagedObjectDefinition d) |
| | | AbstractManagedObjectDefinition<?, ?> d) |
| | | throws MissingResourceException { |
| | | Properties p = properties.get(d); |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public InstantiableRelationDefinition<? super C, ? super S> |
| | | getRelationDefinition() { |
| | | return r; |
| | |
| | | |
| | | |
| | | // 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()); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String visitUnknown(PropertyDefinition d, Void p) |
| | | public String visitUnknown(PropertyDefinition<?> d, Void p) |
| | | throws UnknownPropertyDefinitionException { |
| | | return "?"; |
| | | } |
| | |
| | | * 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); |
| | | } |
| | |
| | | * @param d |
| | | * The property definition. |
| | | */ |
| | | public PropertyIsMandatoryException(PropertyDefinition d) { |
| | | public PropertyIsMandatoryException(PropertyDefinition<?> d) { |
| | | super(d); |
| | | } |
| | | |
| | |
| | | * @param d |
| | | * The property definition. |
| | | */ |
| | | public PropertyIsReadOnlyException(PropertyDefinition d) { |
| | | public PropertyIsReadOnlyException(PropertyDefinition<?> d) { |
| | | super(d); |
| | | } |
| | | |
| | |
| | | * @param d |
| | | * The property definition. |
| | | */ |
| | | public PropertyIsSingleValuedException(PropertyDefinition d) { |
| | | public PropertyIsSingleValuedException(PropertyDefinition<?> d) { |
| | | super(d); |
| | | } |
| | | |
| | |
| | | * @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); |
| | | } |
| | | |
| | |
| | | * @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; |
| | | } |
| | |
| | | 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; |
| | |
| | | * <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 { |
| | | |
| | | /** |
| | |
| | | * 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 |
| | |
| | | * 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; |
| | | |
| | | |
| | |
| | | * 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 |
| | |
| | | * 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; |
| | | |
| | |
| | | /** |
| | | * 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. |
| | |
| | | * 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; |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * 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 |
| | |
| | | * 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; |
| | | |
| | | |
| | | |
| | |
| | | * @return Returns a client configuration view of this managed |
| | | * object. |
| | | */ |
| | | C getConfiguration(); |
| | | T getConfiguration(); |
| | | |
| | | |
| | | |
| | |
| | | * @return Returns the definition associated with this managed |
| | | * object. |
| | | */ |
| | | ManagedObjectDefinition<C, ?> getManagedObjectDefinition(); |
| | | ManagedObjectDefinition<T, ? extends Configuration> |
| | | getManagedObjectDefinition(); |
| | | |
| | | |
| | | |
| | |
| | | * |
| | | * @return Returns the path of this managed object. |
| | | */ |
| | | ManagedObjectPath getManagedObjectPath(); |
| | | ManagedObjectPath<T, ? extends Configuration> getManagedObjectPath(); |
| | | |
| | | |
| | | |
| | |
| | | * 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 |
| | |
| | | * 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; |
| | | |
| | | |
| | |
| | | * 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. |
| | |
| | | * 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; |
| | | |
| | | |
| | |
| | | * 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. |
| | |
| | | * 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; |
| | | |
| | |
| | | * 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 |
| | |
| | | * 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; |
| | | |
| | |
| | | /** |
| | | * 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. |
| | |
| | | * 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; |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * 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; |
| | | |
| | | |
| | | |
| | |
| | | * 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 |
| | |
| | | * 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; |
| | | |
| | |
| | | * 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 |
| | |
| | | * 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; |
| | |
| | | } |
| | | |
| | | // The properties. |
| | | private final Map<PropertyDefinition, MyProperty> properties; |
| | | private final Map<PropertyDefinition<?>, MyProperty<?>> properties; |
| | | |
| | | |
| | | |
| | |
| | | * Creates a new empty property set. |
| | | */ |
| | | public PropertySet() { |
| | | this.properties = new HashMap<PropertyDefinition, MyProperty>(); |
| | | this.properties = new HashMap<PropertyDefinition<?>, MyProperty<?>>(); |
| | | } |
| | | |
| | | |
| | |
| | | throw new IllegalArgumentException("Unknown property " + d.getName()); |
| | | } |
| | | |
| | | return properties.get(d); |
| | | return (Property<T>) properties.get(d); |
| | | } |
| | | |
| | | |
| | |
| | | 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('='); |
| | |
| | | @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); |
| | | } |
| | | |
| | |
| | | * {@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); |
| | | |
| | |
| | | * |
| | | * @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; |
| | | |
| | | |
| | |
| | | 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; |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * 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); |
| | |
| | | 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; |
| | |
| | | |
| | | // Private constructor. |
| | | private DefaultValueFinder(LDAPManagementContext context, |
| | | ManagedObjectPath p, boolean isCreate) { |
| | | ManagedObjectPath<?, ?> p, boolean isCreate) { |
| | | this.context = context; |
| | | this.firstPath = p; |
| | | this.isCreate = isCreate; |
| | |
| | | |
| | | |
| | | // 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; |
| | |
| | | |
| | | // 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")); |
| | |
| | | |
| | | // 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 |
| | |
| | | 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; |
| | |
| | | |
| | | // 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; |
| | |
| | | /** |
| | | * {@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); |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | ManagedObjectPath childPath = path.child(r, name); |
| | | ManagedObjectPath<CC, ? extends S> childPath = path.child(r, d, name); |
| | | return createNewManagedObject(d, childPath, pd, name, exceptions); |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@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)); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@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)); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ManagedObjectDefinition<C, ?> getManagedObjectDefinition() { |
| | | public ManagedObjectDefinition<T, ? extends Configuration> |
| | | getManagedObjectDefinition() { |
| | | return definition; |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ManagedObjectPath getManagedObjectPath() { |
| | | public ManagedObjectPath<T, ? extends Configuration> getManagedObjectPath() { |
| | | return path; |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | |
| | | /** |
| | | * {@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) { |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@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)); |
| | | } |
| | | } |
| | | |
| | |
| | | /** |
| | | * {@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); |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | // 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()) { |
| | |
| | | |
| | | // 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); |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | // 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; |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | // 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)); |
| | |
| | | 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); |
| | | } |
| | |
| | | } |
| | | |
| | | // Get the property's default values. |
| | | Collection<T> defaultValues; |
| | | Collection<P> defaultValues; |
| | | try { |
| | | defaultValues = DefaultValueFinder.getDefaultValues(context, p, pd, |
| | | false); |
| | |
| | | |
| | | |
| | | // 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)); |
| | | } |
| | | } |
| | |
| | | |
| | | // 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()) { |
| | |
| | | |
| | | // 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 { |
| | |
| | | |
| | | |
| | | // 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()); |
| | |
| | | // 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()); |
| | |
| | | * @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(); |
| | |
| | | * @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); |
| | |
| | | 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); |
| | |
| | | OptionalRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement((RelationDefinition) r); |
| | | appendManagedObjectPathElement((RelationDefinition<?, ?>) r); |
| | | } |
| | | |
| | | |
| | |
| | | SingletonRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement((RelationDefinition) r); |
| | | appendManagedObjectPathElement((RelationDefinition<?, ?>) r); |
| | | } |
| | | |
| | | |
| | |
| | | * @param listener |
| | | * The underlying add listener. |
| | | */ |
| | | public ConfigAddListenerAdaptor(ManagedObjectPath path, |
| | | public ConfigAddListenerAdaptor(ManagedObjectPath<?, ?> path, |
| | | InstantiableRelationDefinition<?, S> relation, |
| | | ConfigurationAddListener<S> listener) { |
| | | this.path = path; |
| | |
| | | * @param listener |
| | | * The underlying add listener. |
| | | */ |
| | | public ConfigAddListenerAdaptor(ManagedObjectPath path, |
| | | public ConfigAddListenerAdaptor(ManagedObjectPath<?, ?> path, |
| | | OptionalRelationDefinition<?, S> relation, |
| | | ConfigurationAddListener<S> listener) { |
| | | this.path = path; |
| | |
| | | // 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. |
| | |
| | | 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); |
| | |
| | | * 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 |
| | |
| | | * @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(); |
| | |
| | | * {@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 |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public Void visitAlias(AliasDefaultBehaviorProvider<T> d, |
| | | ManagedObjectPath p) { |
| | | ManagedObjectPath<?, ?> p) { |
| | | return null; |
| | | } |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public Void visitDefined(DefinedDefaultBehaviorProvider<T> d, |
| | | ManagedObjectPath p) { |
| | | ManagedObjectPath<?, ?> p) { |
| | | return null; |
| | | } |
| | | |
| | |
| | | * {@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 |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public Void visitUndefined(UndefinedDefaultBehaviorProvider<T> d, |
| | | ManagedObjectPath p) { |
| | | ManagedObjectPath<?, ?> p) { |
| | | return null; |
| | | } |
| | | } |
| | |
| | | private final ConfigurationChangeListener<? super S> listener; |
| | | |
| | | // The managed object path. |
| | | private final ManagedObjectPath path; |
| | | private final ManagedObjectPath<?, ?> path; |
| | | |
| | | |
| | | |
| | |
| | | * @param listener |
| | | * The underlying change listener. |
| | | */ |
| | | public ConfigChangeListenerAdaptor(ManagedObjectPath path, |
| | | public ConfigChangeListenerAdaptor(ManagedObjectPath<?, ?> path, |
| | | AbstractManagedObjectDefinition<?, S> d, |
| | | ConfigurationChangeListener<? super S> listener) { |
| | | this.path = path; |
| | |
| | | * @param listener |
| | | * The underlying delete listener. |
| | | */ |
| | | public ConfigDeleteListenerAdaptor(ManagedObjectPath path, |
| | | public ConfigDeleteListenerAdaptor(ManagedObjectPath<?, ?> path, |
| | | InstantiableRelationDefinition<?, S> relation, |
| | | ConfigurationDeleteListener<S> listener) { |
| | | this.path = path; |
| | |
| | | * @param listener |
| | | * The underlying delete listener. |
| | | */ |
| | | public ConfigDeleteListenerAdaptor(ManagedObjectPath path, |
| | | public ConfigDeleteListenerAdaptor(ManagedObjectPath<?, ?> path, |
| | | OptionalRelationDefinition<?, S> relation, |
| | | ConfigurationDeleteListener<S> listener) { |
| | | this.path = path; |
| | |
| | | // 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. |
| | |
| | | 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); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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() { |
| | |
| | | * 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(); |
| | |
| | | * @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); |
| | |
| | | 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); |
| | |
| | | OptionalRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement((RelationDefinition) r); |
| | | appendManagedObjectPathElement((RelationDefinition<?, ?>) r); |
| | | } |
| | | |
| | | |
| | |
| | | SingletonRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement((RelationDefinition) r); |
| | | appendManagedObjectPathElement((RelationDefinition<?, ?>) r); |
| | | } |
| | | |
| | | |
| | |
| | | * 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); |
| | |
| | | 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; |
| | |
| | | |
| | | |
| | | // 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; |
| | | |
| | |
| | | * 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); |
| | |
| | | * 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. |
| | |
| | | |
| | | // 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); |
| | |
| | | // 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; |
| | |
| | | |
| | | |
| | | // Create an new server side managed object. |
| | | private ServerManagedObject(ManagedObjectPath path, |
| | | private ServerManagedObject(ManagedObjectPath<?, ?> path, |
| | | ManagedObjectDefinition<?, S> d, |
| | | Map<PropertyDefinition<?>, SortedSet<?>> properties, |
| | | ConfigEntry configEntry) { |
| | |
| | | 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); |
| | | } |
| | |
| | | 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); |
| | | } |
| | | |
| | |
| | | OptionalRelationDefinition<?, M> d) throws IllegalArgumentException, |
| | | ConfigException { |
| | | validateRelationDefinition(d); |
| | | ManagedObjectPath childPath = path.child(d); |
| | | ManagedObjectPath<?, ?> childPath = path.child(d); |
| | | return getChild(childPath, d); |
| | | } |
| | | |
| | |
| | | SingletonRelationDefinition<?, M> d) throws IllegalArgumentException, |
| | | ConfigException { |
| | | validateRelationDefinition(d); |
| | | ManagedObjectPath childPath = path.child(d); |
| | | ManagedObjectPath<?, ?> childPath = path.child(d); |
| | | return getChild(childPath, d); |
| | | } |
| | | |
| | |
| | | * |
| | | * @return Returns the path of this server managed object. |
| | | */ |
| | | public ManagedObjectPath getManagedObjectPath() { |
| | | public ManagedObjectPath<?, ?> getManagedObjectPath() { |
| | | return path; |
| | | } |
| | | |
| | |
| | | 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); |
| | | } |
| | |
| | | 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); |
| | | } |
| | |
| | | |
| | | // 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); |
| | |
| | | // 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()); |
| | |
| | | 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 |
| | |
| | | "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"); |
| | |
| | | "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"); |
| | | |
| | |
| | | "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"); |
| | |
| | | "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"); |
| | |
| | | "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\""); |
| | | } |
| | | } |
| | | |
| | |
| | | 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; |
| | | |
| | | |
| | |
| | | * @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(); |
| | | |
| | |
| | | */ |
| | | public static ArgumentException adaptMissingMandatoryPropertiesException( |
| | | MissingMandatoryPropertiesException e, |
| | | AbstractManagedObjectDefinition d) { |
| | | AbstractManagedObjectDefinition<?, ?> d) { |
| | | int msgID = MSGID_DSCFG_ERROR_CREATE_MMPE; |
| | | StringBuilder builder = new StringBuilder(); |
| | | boolean isFirst = true; |
| | |
| | | * @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); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | |
| | | * @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); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | * @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); |
| | |
| | | * 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(), |
| | |
| | | * 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()); |
| | |
| | | * 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()); |
| | |
| | | * 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()); |
| | |
| | | * 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()); |
| | |
| | | * 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 |
| | |
| | | * 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 |
| | |
| | | * 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 |
| New file |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | | |
| | | |
| | |
| | | * |
| | | * @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 |
| | |
| | | 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<?>>(); |
| | | |
| | | |
| | | |
| | |
| | | * @return Returns the set of parsed property definitions that |
| | | * have values specified. |
| | | */ |
| | | public Set<PropertyDefinition> getProperties() { |
| | | public Set<PropertyDefinition<?>> getProperties() { |
| | | return properties.keySet(); |
| | | } |
| | | |
| | |
| | | @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 { |
| | |
| | | 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>(); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | |
| | | * |
| | | * @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 |
| | |
| | | * @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")); |
| | | } |
| | | |
| | |
| | | * |
| | | * @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 |
| | |
| | | * @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. |
| | |
| | | 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; |
| | |
| | | // 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; |
| | |
| | | |
| | | |
| | | // 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; |
| | |
| | | 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 { |
| | |
| | | * {@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); |
| | |
| | | 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()); |
| | |
| | | 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); |
| | | 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); |
| | | } |
| | | |
| | |
| | | // 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; |
| | | } |
| | | |
| | |
| | | // 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); |
| | |
| | | |
| | | |
| | | |
| | | // 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 |
| | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | | |
| | | |
| | |
| | | * 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. |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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; |
| | | } |
| | | } |
| | |
| | | // 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; |
| | |
| | | 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; |
| | | |
| | |
| | | */ |
| | | 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. |
| | | * |
| | |
| | | |
| | | |
| | | /** |
| | | * 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(); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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(); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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(); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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(); |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * |
| | |
| | | |
| | | // Register the global arguments. |
| | | parser.addGlobalArgument(showUsageArgument); |
| | | parser.setUsageArgument(showUsageArgument, out); |
| | | parser.setUsageArgument(showUsageArgument, getOutputStream()); |
| | | parser.addGlobalArgument(verboseArgument); |
| | | parser.addGlobalArgument(quietArgument); |
| | | parser.addGlobalArgument(scriptFriendlyArgument); |
| | |
| | | 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); |
| | |
| | | } 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; |
| | | } |
| | | |
| | |
| | | } 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; |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | 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; |
| | |
| | | if (debugEnabled()) { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | err.println(wrapText(StaticUtils.stackTraceToString(e), MAX_LINE_WIDTH)); |
| | | printMessage(StaticUtils.stackTraceToString(e)); |
| | | return 1; |
| | | } |
| | | } |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | * 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 |
| | |
| | | * @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")); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * @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. |
| | |
| | | |
| | | |
| | | // 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; |
| | | |
| | |
| | | * {@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()); |
| | |
| | | } 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()) { |
| | |
| | | |
| | | 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; |
| | | |
| | | if (confirmDeletion()) { |
| | | parent.removeChild(orelation); |
| | | } else { |
| | | return 1; |
| | | } |
| | | } |
| | | } catch (AuthorizationException e) { |
| | | int msgID = MSGID_DSCFG_ERROR_DELETE_AUTHZ; |
| | |
| | | // 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; |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | * 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 |
| | |
| | | * @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 |
| | |
| | | * @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 |
| | |
| | | * @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. |
| | |
| | | |
| | | |
| | | // 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. |
| | |
| | | * {@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(); |
| | |
| | | } |
| | | |
| | | 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 { |
| | |
| | | |
| | | |
| | | // 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 |
| | |
| | | |
| | | |
| | | public String visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) { |
| | | if (app.isVerbose()) { |
| | | if (getConsoleApplication().isVerbose()) { |
| | | return d.getSynopsis(); |
| | | } else { |
| | | return null; |
| | |
| | | |
| | | String content = pd.getDefaultBehaviorProvider().accept(visitor, null); |
| | | if (content == null) { |
| | | if (app.isScriptFriendly()) { |
| | | if (getConsoleApplication().isScriptFriendly()) { |
| | | builder.appendCell(); |
| | | } else { |
| | | builder.appendCell("-"); |
| | |
| | | builder.startRow(); |
| | | builder.appendCell(pd.getName()); |
| | | |
| | | if (app.isScriptFriendly()) { |
| | | if (getConsoleApplication().isScriptFriendly()) { |
| | | for (T value : values) { |
| | | builder.appendCell(valuePrinter.print(pd, value)); |
| | | } |
| New file |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Void visitUnknown(PropertyDefinition d, PrintStream p) |
| | | public Void visitUnknown(PropertyDefinition<?> d, PrintStream p) |
| | | throws UnknownPropertyDefinitionException { |
| | | PropertyDefinitionUsageBuilder usageBuilder = |
| | | new PropertyDefinitionUsageBuilder(true); |
| | |
| | | /** |
| | | * 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; |
| | | |
| | |
| | | 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; |
| | |
| | | * {@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(); |
| | |
| | | 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; |
| | | } |
| | |
| | | |
| | | |
| | | // 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 -- "); |
| | |
| | | // Generate the table content. |
| | | for (AbstractManagedObjectDefinition<?, ?> mod : defns) { |
| | | Collection<PropertyDefinition<?>> pds; |
| | | if (app.isScriptFriendly()) { |
| | | if (getConsoleApplication().isScriptFriendly()) { |
| | | pds = mod.getAllPropertyDefinitions(); |
| | | } else { |
| | | pds = mod.getPropertyDefinitions(); |
| | |
| | | } |
| | | |
| | | TablePrinter printer; |
| | | if (app.isScriptFriendly()) { |
| | | if (getConsoleApplication().isScriptFriendly()) { |
| | | printer = createScriptFriendlyTablePrinter(out); |
| | | } else { |
| | | printer = new TextTablePrinter(out); |
| | |
| | | |
| | | |
| | | // 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, '='); |
| | |
| | | |
| | | |
| | | |
| | | // 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(); |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ManagementContext getManagementContext(DSConfig app) |
| | | public ManagementContext getManagementContext(ConsoleApplication app) |
| | | throws ArgumentException, ClientException { |
| | | return context; |
| | | } |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ManagementContext getManagementContext(DSConfig app) |
| | | public ManagementContext getManagementContext(ConsoleApplication app) |
| | | throws ArgumentException, ClientException { |
| | | // Lazily create the LDAP management context. |
| | | if (context == null) { |
| | |
| | | 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; |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * @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()); |
| | | } |
| | | |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * @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()); |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | // 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; |
| | | |
| | |
| | | * {@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(); |
| | |
| | | } |
| | | |
| | | PropertyValuePrinter valuePrinter = new PropertyValuePrinter(getSizeUnit(), |
| | | getTimeUnit(), app.isScriptFriendly()); |
| | | getTimeUnit(), getConsoleApplication().isScriptFriendly()); |
| | | |
| | | // Get the naming argument values. |
| | | List<String> names = getNamingArgValues(namingArgs); |
| | |
| | | } |
| | | |
| | | // 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); |
| | |
| | | } |
| | | |
| | | // 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); |
| | | } |
| | |
| | | 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("-"); |
| | |
| | | } |
| | | } |
| | | |
| | | if (app.isScriptFriendly()) { |
| | | PrintStream out = getConsoleApplication().getOutputStream(); |
| | | if (getConsoleApplication().isScriptFriendly()) { |
| | | TablePrinter printer = createScriptFriendlyTablePrinter(out); |
| | | builder.print(printer); |
| | | } else { |
| | |
| | | |
| | | |
| | | // 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("-"); |
| | |
| | | * @throws ClientException |
| | | * If the management context could not be created. |
| | | */ |
| | | ManagementContext getManagementContext(DSConfig app) throws ArgumentException, |
| | | ClientException; |
| | | ManagementContext getManagementContext(ConsoleApplication app) |
| | | throws ArgumentException, ClientException; |
| | | |
| | | |
| | | |
| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | * 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 |
| | |
| | | * @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); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * @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); |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * @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. |
| | |
| | | |
| | | |
| | | // 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. |
| | |
| | | */ |
| | | @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(); |
| | |
| | | // 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; |
| | | } |
| | | |
| | |
| | | // 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); |
| | |
| | | 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; |
| | | |
| | |
| | | private final SubCommandArgumentParser parser; |
| | | |
| | | // Private constructor. |
| | | private Visitor(SubCommandArgumentParser parser) { |
| | | private Visitor(ConsoleApplication app, SubCommandArgumentParser parser) { |
| | | this.app = app; |
| | | this.parser = parser; |
| | | } |
| | | |
| | |
| | | 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()); |
| | |
| | | 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. |
| | |
| | | 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. |
| | |
| | | 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. |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * 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(); |
| | | } |
| | | |
| | |
| | | * 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. |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | // 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; |
| | | |
| | |
| | | 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); |
| | |
| | | // 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; |
| | |
| | | |
| | | /** |
| | | * Create a new sub-command handler. |
| | | * |
| | | * @param app |
| | | * The application instance. |
| | | */ |
| | | protected SubCommandHandler() { |
| | | // No implementation required. |
| | | protected SubCommandHandler(ConsoleApplication app) { |
| | | this.app = app; |
| | | } |
| | | |
| | | |
| | |
| | | /** |
| | | * 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 |
| | |
| | | * @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; |
| | | |
| | | |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| | |
| | | * @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); |
| | | } |
| | | |
| | | |
| | |
| | | * @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; |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * 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 |
| New file |
| | |
| | | /* |
| | | * 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; |
| | | } |
| | |
| | | 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. |
| | |
| | | * 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; |
| | | |
| | | |
| | | |
| | |
| | | * @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); |
| | | |
| | | |
| | | |
| | |
| | | * {@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(); |
| | | } |
| | | |
| | |
| | | * {@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(); |
| | | } |
| | | |
| | |
| | | * {@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) { |