Reorganize opendj-config packaging, removing all references to opends and renaming admin to config
361 files deleted
36 files modified
2 files renamed
361 files added
| | |
| | | public class OpendjConfigMojo extends AbstractBuildMojo { |
| | | |
| | | /** |
| | | * Package path in which artefacts are generated. |
| | | * Package name for which artifacts are generated. |
| | | * <p> |
| | | * This relative path is used to locate xml definition files and to locate |
| | | * generated artefacts. |
| | | * generated artifacts. |
| | | * |
| | | * @parameter default-value="org/forgerock/opendj/admin" |
| | | * @parameter |
| | | * @required |
| | | */ |
| | | private String packagePath; |
| | | private String packageName; |
| | | |
| | | /** |
| | | * Root directory where definitions of configuration as xml files are |
| | |
| | | /** |
| | | * Root directory containing generated sources for configuration. |
| | | * |
| | | * @parameter default-value="${project.build.directory}/generated-sources/admin" |
| | | * @parameter default-value="${project.build.directory}/generated-sources/config" |
| | | * @required |
| | | */ |
| | | private String generatedSourcesRootDir; |
| | |
| | | * Temporary directory containing generated manifests. |
| | | * <p> |
| | | * There is one manifest file generated by component. It is the |
| | | * responsability of project that use this plugin to concatenate all |
| | | * responsibility of project that use this plugin to concatenate all |
| | | * generated files into a single file. |
| | | * |
| | | * @parameter default-value="${project.build.directory}/tmp" |
| | |
| | | /** |
| | | * Root directory containing generated messages for configuration. |
| | | * |
| | | * @parameter default-value="${basedir}/src/main/resources/admin/messages" |
| | | * @parameter default-value="${basedir}/src/main/resources/config/messages" |
| | | * @required |
| | | */ |
| | | private String generatedMessagesRootDir; |
| | |
| | | /** |
| | | * Root directory containing generated profiles for configuration. |
| | | * |
| | | * @parameter default-value="${project.build.outputDirectory}/admin/profiles" |
| | | * @parameter default-value="${project.build.outputDirectory}/config/profiles" |
| | | * @required |
| | | */ |
| | | private String generatedProfilesRootDir; |
| | | |
| | | /** |
| | | * Returns the package path in which artefacts are generated. |
| | | * <p> |
| | | * The package path is a relative path. |
| | | * Returns the package name in which artifacts are generated. |
| | | * |
| | | * @return the package name |
| | | */ |
| | | public final String getPackageName() { |
| | | return packageName; |
| | | } |
| | | |
| | | /** |
| | | * Returns the package path in which artifacts are generated. |
| | | * |
| | | * @return the package path |
| | | */ |
| | | public final String getPackagePath() { |
| | | return packagePath; |
| | | return packageName.replace('.', '/'); |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return the directory containing xml configuration files |
| | | */ |
| | | public final File getXmlDefinitionsDirectory() { |
| | | return new File(getXmlDefinitionsRootDirectory(), packagePath); |
| | | return new File(getXmlDefinitionsRootDirectory(), getPackagePath()); |
| | | } |
| | | |
| | | /** |
| | |
| | | <configuration> |
| | | <sources> |
| | | <source>${project.build.directory}/generated-sources/java</source> |
| | | <source>${project.build.directory}/generated-sources/admin</source> |
| | | <source>${project.build.directory}/generated-sources/config</source> |
| | | </sources> |
| | | </configuration> |
| | | </execution> |
| | |
| | | <goals> |
| | | <goal>generate</goal> |
| | | </goals> |
| | | <configuration> |
| | | <configuration> |
| | | <packageName>org.forgerock.opendj.server.config</packageName> |
| | | </configuration> |
| | | </execution> |
| | | </executions> |
| | |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-surefire-plugin</artifactId> |
| | | </plugin> |
| | | <plugin> |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-source-plugin</artifactId> |
| | | </plugin> |
| | | </plugins> |
| | | </build> |
| | | <reporting> |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2013 ForgeRock AS |
| | | */ |
| | | package org.forgerock.opendj.server.util; |
| | | |
| | | /** |
| | | * This file contains a number of constants that are used throughout the |
| | | * Directory Server source. It was dynamically generated as part of the |
| | | * build process and should not be edited directly. |
| | | */ |
| | | public final class DynamicConstants { |
| | | |
| | | /** |
| | | * The official full product name for the Directory Server. |
| | | */ |
| | | public static String PRODUCT_NAME = "${serverProductName}"; |
| | | |
| | | /** |
| | | * The short product name for the Directory Server. |
| | | */ |
| | | public static String SHORT_NAME = "${serverShortProductName}"; |
| | | |
| | | /** |
| | | * The major version number for the Directory Server. |
| | | */ |
| | | public static int MAJOR_VERSION = ${parsedVersion.majorVersion}; |
| | | |
| | | /** |
| | | * The minor version number for the Directory Server. |
| | | */ |
| | | public static int MINOR_VERSION = ${parsedVersion.minorVersion}; |
| | | |
| | | /** |
| | | * The point version number for the Directory Server. |
| | | */ |
| | | public static int POINT_VERSION = ${parsedVersion.incrementalVersion}; |
| | | |
| | | /** |
| | | * The official build number for the Directory Server. |
| | | */ |
| | | public static int BUILD_NUMBER = ${parsedVersion.buildNumber}; |
| | | |
| | | /** |
| | | * The version qualifier string for the Directory Server. |
| | | */ |
| | | public static String VERSION_QUALIFIER = "${parsedVersion.qualifier}"; |
| | | |
| | | /** |
| | | * The set of bug IDs for fixes included in this build of the Directory |
| | | * Server. |
| | | */ |
| | | public static String FIX_IDS = "${issuesFixIds}"; |
| | | |
| | | /** |
| | | * The build ID for the generated build of the Directory Server. |
| | | */ |
| | | public static String BUILD_ID = "${buildDateTime}"; |
| | | |
| | | /** |
| | | * The username of the user that created this build. |
| | | */ |
| | | public static String BUILD_USER = "${user.name}"; |
| | | |
| | | /** |
| | | * The Java version used to generate this build. |
| | | */ |
| | | public static String BUILD_JAVA_VERSION = "${java.version}"; |
| | | |
| | | /** |
| | | * The vendor for the Java version used to generate this build. |
| | | */ |
| | | public static String BUILD_JAVA_VENDOR = "${java.vendor}"; |
| | | |
| | | /** |
| | | * The JVM version used to generate this build. |
| | | */ |
| | | public static String BUILD_JVM_VERSION = "${java.vm.version}"; |
| | | |
| | | /** |
| | | * The vendor for the JVM used to generate this build. |
| | | */ |
| | | public static String BUILD_JVM_VENDOR = "${java.vm.vendor}"; |
| | | |
| | | /** |
| | | * The operating system on which this build was generated. |
| | | */ |
| | | public static String BUILD_OS = "${os.name} ${os.version} ${os.arch}"; |
| | | |
| | | /** |
| | | * Indicates whether this is a debug build of the Directory Server that may |
| | | * include additional debugging facilities not available in standard release |
| | | * versions. |
| | | */ |
| | | public static boolean DEBUG_BUILD = ${isDebugBuild}; |
| | | |
| | | /** |
| | | * The Subversion revision number on which this build is based. |
| | | */ |
| | | public static long REVISION_NUMBER = ${buildRevision}; |
| | | |
| | | /** |
| | | * The Subversion url repository location on which this build is based. |
| | | */ |
| | | public static String URL_REPOSITORY = "${scm.url}"; |
| | | |
| | | /** |
| | | * The documentation home. |
| | | */ |
| | | public static String DOC_REFERENCE_HOME = "${docReferenceHome}"; |
| | | |
| | | /** |
| | | * The documentation url. |
| | | */ |
| | | public static String DOC_REFERENCE_WIKI = "${docReferenceWiki}"; |
| | | |
| | | /** |
| | | * The documentation url. |
| | | */ |
| | | public static String DOC_QUICK_REFERENCE_GUIDE = "${docQuickRefGuide}"; |
| | | |
| | | /** |
| | | * The administration guide. |
| | | */ |
| | | public static String ADMINISTRATION_GUIDE_URL = "${adminGuideUrl}"; |
| | | |
| | | /** |
| | | * A string representation of the version number. |
| | | */ |
| | | public static String VERSION_NUMBER_STRING = "${project.version}"; |
| | | |
| | | /** |
| | | * A string representation of the version number. |
| | | */ |
| | | public static String OPENDJ_NUMBER_STRING = "${project.version}"; |
| | | |
| | | /** |
| | | * A string representation of the release version. |
| | | */ |
| | | public static String RELEASE_VERSION_STRING = OPENDJ_NUMBER_STRING; |
| | | |
| | | /** |
| | | * A compact version string for this product, suitable for use in path names |
| | | * and similar cases. |
| | | */ |
| | | public static String COMPACT_VERSION_STRING = SHORT_NAME + "-" + VERSION_NUMBER_STRING; |
| | | |
| | | /** |
| | | * A full version string for this product. |
| | | */ |
| | | public static String FULL_VERSION_STRING = PRODUCT_NAME + " " + RELEASE_VERSION_STRING |
| | | + (((FIX_IDS != null) && (FIX_IDS.length() > 0)) ? "+" + FIX_IDS : ""); |
| | | |
| | | /** |
| | | * A printable version string for this product. |
| | | */ |
| | | public static final String PRINTABLE_VERSION_STRING = FULL_VERSION_STRING + System.getProperty("line.separator") |
| | | + "Build " + BUILD_ID + System.getProperty("line.separator"); |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import org.opends.server.authorization.dseecompat.Aci; |
| | | import org.opends.server.authorization.dseecompat.AciException; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | |
| | | import java.util.EnumSet; |
| | | |
| | | /** |
| | | * ACI property definition. |
| | | */ |
| | | public final class ACIPropertyDefinition extends PropertyDefinition<Aci> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing ACI property definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<Aci, ACIPropertyDefinition> { |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected ACIPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Aci> defaultBehavior) { |
| | | return new ACIPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Create a ACI property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new ACI property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private ACIPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Aci> defaultBehavior) { |
| | | super(d, Aci.class, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(Aci value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // No additional validation required. |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Aci decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | try { |
| | | return Aci.decode(ByteString.valueOf(value), DN.rootDN()); |
| | | } catch (AciException e) { |
| | | // TODO: it would be nice to throw the cause. |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitACI(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, Aci value, P p) { |
| | | return v.visitACI(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(Aci o1, Aci o2) { |
| | | return o1.toString().compareTo(o2.toString()); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A default behavior provider which retrieves default values from a managed |
| | | * object in an absolute location. It should be used by properties which inherit |
| | | * their default value(s) from properties held in an other managed object. |
| | | * |
| | | * @param <T> |
| | | * The type of values represented by this provider. |
| | | */ |
| | | public final class AbsoluteInheritedDefaultBehaviorProvider<T> extends DefaultBehaviorProvider<T> { |
| | | |
| | | // The absolute path to the managed object containing the property. |
| | | private ManagedObjectPath<?, ?> path = null; |
| | | |
| | | // The string representation of the managed object path specifying |
| | | // the absolute location of the managed object. |
| | | private final String pathString; |
| | | |
| | | // The name of the property containing the inherited default values. |
| | | private final String propertyName; |
| | | |
| | | /** |
| | | * Create an absolute inherited default behavior provider associated with |
| | | * the managed object at the specified absolute location. |
| | | * |
| | | * @param pathString |
| | | * The string representation of the managed object path |
| | | * specifying the absolute location of the managed object. |
| | | * @param propertyName |
| | | * The name of the property containing the inherited default |
| | | * values. |
| | | */ |
| | | public AbsoluteInheritedDefaultBehaviorProvider(String pathString, String propertyName) { |
| | | this.pathString = pathString; |
| | | this.propertyName = propertyName; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <R, P> R accept(DefaultBehaviorProviderVisitor<T, R, P> v, P p) { |
| | | return v.visitAbsoluteInherited(this, p); |
| | | } |
| | | |
| | | /** |
| | | * Get the definition of the parent managed object containing the inherited |
| | | * default values. |
| | | * |
| | | * @return Returns the definition of the parent managed object containing |
| | | * the inherited default values. |
| | | */ |
| | | public AbstractManagedObjectDefinition<?, ?> getManagedObjectDefinition() { |
| | | return path.getManagedObjectDefinition(); |
| | | } |
| | | |
| | | /** |
| | | * Get the absolute path of the managed object containing the property which |
| | | * has the default values. |
| | | * |
| | | * @return Returns the absolute path of the managed object containing the |
| | | * property which has the default values. |
| | | */ |
| | | public ManagedObjectPath<?, ?> getManagedObjectPath() { |
| | | return path; |
| | | } |
| | | |
| | | /** |
| | | * Gets the name of the property containing the inherited default values. |
| | | * |
| | | * @return Returns the name of the property containing the inherited default |
| | | * values. |
| | | */ |
| | | public String getPropertyName() { |
| | | return propertyName; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | // Decode the path. |
| | | path = ManagedObjectPath.valueOf(pathString); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2007-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.EnumSet; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.MissingResourceException; |
| | | import java.util.Set; |
| | | import java.util.Vector; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException.Reason; |
| | | |
| | | /** |
| | | * Defines the structure of an abstract managed object. Abstract managed objects |
| | | * cannot be instantiated. |
| | | * <p> |
| | | * Applications can query a managed object definition in order to determine the |
| | | * overall configuration model of an application. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * definition represents. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * definition represents. |
| | | */ |
| | | public abstract class AbstractManagedObjectDefinition<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | // The name of the definition. |
| | | private final String name; |
| | | |
| | | // The parent managed object definition if applicable. |
| | | private final AbstractManagedObjectDefinition<? super C, ? super S> parent; |
| | | |
| | | // The set of constraints associated with this managed object |
| | | // definition. |
| | | private final Collection<Constraint> constraints; |
| | | |
| | | // The set of property definitions applicable to this managed object |
| | | // definition. |
| | | private final Map<String, PropertyDefinition<?>> propertyDefinitions; |
| | | |
| | | // The set of relation definitions applicable to this managed object |
| | | // definition. |
| | | private final Map<String, RelationDefinition<?, ?>> relationDefinitions; |
| | | |
| | | // The set of relation definitions directly referencing this managed |
| | | // object definition. |
| | | private final Set<RelationDefinition<C, S>> reverseRelationDefinitions; |
| | | |
| | | // The set of all property definitions associated with this managed |
| | | // object definition including inherited property definitions. |
| | | private final Map<String, PropertyDefinition<?>> allPropertyDefinitions; |
| | | |
| | | // The set of all relation definitions associated with this managed |
| | | // object definition including inherited relation definitions. |
| | | private final Map<String, RelationDefinition<?, ?>> allRelationDefinitions; |
| | | |
| | | // The set of aggregation property definitions applicable to this |
| | | // managed object definition. |
| | | private final Map<String, AggregationPropertyDefinition<?, ?>> aggregationPropertyDefinitions; |
| | | |
| | | // The set of aggregation property definitions directly referencing this |
| | | // managed object definition. |
| | | private final Vector<AggregationPropertyDefinition<?, ?>> reverseAggregationPropertyDefinitions; |
| | | |
| | | // The set of all aggregation property definitions associated with this |
| | | // managed object definition including inherited relation definitions. |
| | | private final Map<String, AggregationPropertyDefinition<?, ?>> allAggregationPropertyDefinitions; |
| | | |
| | | // The set of tags associated with this managed object. |
| | | private final Set<Tag> allTags; |
| | | |
| | | // Options applicable to this definition. |
| | | private final Set<ManagedObjectOption> options; |
| | | |
| | | // The set of managed object definitions which inherit from this definition. |
| | | private final Map<String, AbstractManagedObjectDefinition<? extends C, ? extends S>> children; |
| | | |
| | | /** |
| | | * Create a new abstract managed object definition. |
| | | * |
| | | * @param name |
| | | * The name of the definition. |
| | | * @param parent |
| | | * The parent definition, or <code>null</code> if there is no |
| | | * parent (only the {@link TopCfgDefn} should have a |
| | | * <code>null</code> parent, unless the definition is being used |
| | | * for testing). |
| | | */ |
| | | protected AbstractManagedObjectDefinition(String name, |
| | | AbstractManagedObjectDefinition<? super C, ? super S> parent) { |
| | | this.name = name; |
| | | this.parent = parent; |
| | | this.constraints = new LinkedList<Constraint>(); |
| | | this.propertyDefinitions = new HashMap<String, PropertyDefinition<?>>(); |
| | | this.relationDefinitions = new HashMap<String, RelationDefinition<?, ?>>(); |
| | | this.reverseRelationDefinitions = new HashSet<RelationDefinition<C, S>>(); |
| | | this.allPropertyDefinitions = new HashMap<String, PropertyDefinition<?>>(); |
| | | this.allRelationDefinitions = new HashMap<String, RelationDefinition<?, ?>>(); |
| | | this.aggregationPropertyDefinitions = new HashMap<String, AggregationPropertyDefinition<?, ?>>(); |
| | | this.reverseAggregationPropertyDefinitions = new Vector<AggregationPropertyDefinition<?, ?>>(); |
| | | this.allAggregationPropertyDefinitions = new HashMap<String, AggregationPropertyDefinition<?, ?>>(); |
| | | this.allTags = new HashSet<Tag>(); |
| | | this.options = EnumSet.noneOf(ManagedObjectOption.class); |
| | | |
| | | this.children = new HashMap<String, AbstractManagedObjectDefinition<? extends C, ? extends S>>(); |
| | | |
| | | // If we have a parent definition then inherit its features. |
| | | if (parent != null) { |
| | | registerInParent(); |
| | | |
| | | for (PropertyDefinition<?> pd : parent.getAllPropertyDefinitions()) { |
| | | allPropertyDefinitions.put(pd.getName(), pd); |
| | | } |
| | | |
| | | for (RelationDefinition<?, ?> rd : parent.getAllRelationDefinitions()) { |
| | | allRelationDefinitions.put(rd.getName(), rd); |
| | | } |
| | | |
| | | for (AggregationPropertyDefinition<?, ?> apd : parent.getAllAggregationPropertyDefinitions()) { |
| | | |
| | | allAggregationPropertyDefinitions.put(apd.getName(), apd); |
| | | } |
| | | |
| | | // Tag inheritance is performed during preprocessing. |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get all the child managed object definitions which inherit from this |
| | | * managed object definition. |
| | | * |
| | | * @return Returns an unmodifiable collection containing all the subordinate |
| | | * managed object definitions which inherit from this managed object |
| | | * definition. |
| | | */ |
| | | public final Collection<AbstractManagedObjectDefinition<? extends C, ? extends S>> getAllChildren() { |
| | | List<AbstractManagedObjectDefinition<? extends C, ? extends S>> list = |
| | | new ArrayList<AbstractManagedObjectDefinition<? extends C, ? extends S>>(children.values()); |
| | | |
| | | for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : children.values()) { |
| | | list.addAll(child.getAllChildren()); |
| | | } |
| | | |
| | | return Collections.unmodifiableCollection(list); |
| | | } |
| | | |
| | | /** |
| | | * Get all the constraints associated with this type of managed object. The |
| | | * returned collection will contain inherited constraints. |
| | | * |
| | | * @return Returns a collection containing all the constraints associated |
| | | * with this type of managed object. The caller is free to modify |
| | | * the collection if required. |
| | | */ |
| | | public final Collection<Constraint> getAllConstraints() { |
| | | // This method does not used a cached set of constraints because |
| | | // constraints may be updated after child definitions have been |
| | | // defined. |
| | | List<Constraint> allConstraints = new LinkedList<Constraint>(); |
| | | |
| | | if (parent != null) { |
| | | allConstraints.addAll(parent.getAllConstraints()); |
| | | } |
| | | allConstraints.addAll(constraints); |
| | | |
| | | return allConstraints; |
| | | } |
| | | |
| | | /** |
| | | * Get all the property definitions associated with this type of managed |
| | | * object. The returned collection will contain inherited property |
| | | * definitions. |
| | | * |
| | | * @return Returns an unmodifiable collection containing all the property |
| | | * definitions associated with this type of managed object. |
| | | */ |
| | | public final Collection<PropertyDefinition<?>> getAllPropertyDefinitions() { |
| | | return Collections.unmodifiableCollection(allPropertyDefinitions.values()); |
| | | } |
| | | |
| | | /** |
| | | * Get all the relation definitions associated with this type of managed |
| | | * object. The returned collection will contain inherited relation |
| | | * definitions. |
| | | * |
| | | * @return Returns an unmodifiable collection containing all the relation |
| | | * definitions associated with this type of managed object. |
| | | */ |
| | | public final Collection<RelationDefinition<?, ?>> getAllRelationDefinitions() { |
| | | return Collections.unmodifiableCollection(allRelationDefinitions.values()); |
| | | } |
| | | |
| | | /** |
| | | * Get all the relation definitions which refer to this managed object |
| | | * definition. The returned collection will contain relation definitions |
| | | * which refer to parents of this managed object definition. |
| | | * |
| | | * @return Returns a collection containing all the relation definitions |
| | | * which refer to this managed object definition. The caller is free |
| | | * to modify the collection if required. |
| | | */ |
| | | public final Collection<RelationDefinition<? super C, ? super S>> getAllReverseRelationDefinitions() { |
| | | // This method does not used a cached set of relations because |
| | | // relations may be updated after child definitions have been |
| | | // defined. |
| | | List<RelationDefinition<? super C, ? super S>> rdlist = |
| | | new LinkedList<RelationDefinition<? super C, ? super S>>(); |
| | | |
| | | if (parent != null) { |
| | | rdlist.addAll(parent.getAllReverseRelationDefinitions()); |
| | | } |
| | | rdlist.addAll(reverseRelationDefinitions); |
| | | |
| | | return rdlist; |
| | | } |
| | | |
| | | /** |
| | | * Get all the aggregation property definitions associated with this type of |
| | | * managed object. The returned collection will contain inherited |
| | | * aggregation property definitions. |
| | | * |
| | | * @return Returns an unmodifiable collection containing all the aggregation |
| | | * property definitions associated with this type of managed object. |
| | | */ |
| | | public final Collection<AggregationPropertyDefinition<?, ?>> getAllAggregationPropertyDefinitions() { |
| | | return Collections.unmodifiableCollection(allAggregationPropertyDefinitions.values()); |
| | | } |
| | | |
| | | /** |
| | | * Get all the aggregation property definitions which refer to this managed |
| | | * object definition. The returned collection will contain aggregation |
| | | * property definitions which refer to parents of this managed object |
| | | * definition. |
| | | * |
| | | * @return Returns a collection containing all the aggregation property |
| | | * definitions which refer to this managed object definition. The |
| | | * caller is free to modify the collection if required. |
| | | */ |
| | | public final Collection<AggregationPropertyDefinition<?, ?>> getAllReverseAggregationPropertyDefinitions() { |
| | | // This method does not used a cached set of aggregation properties |
| | | // because |
| | | // aggregation properties may be updated after child definitions have |
| | | // been |
| | | // defined. |
| | | List<AggregationPropertyDefinition<?, ?>> apdlist = new LinkedList<AggregationPropertyDefinition<?, ?>>(); |
| | | |
| | | if (parent != null) { |
| | | apdlist.addAll(parent.getAllReverseAggregationPropertyDefinitions()); |
| | | } |
| | | apdlist.addAll(reverseAggregationPropertyDefinitions); |
| | | |
| | | return apdlist; |
| | | } |
| | | |
| | | /** |
| | | * Get all the tags associated with this type of managed object. The |
| | | * returned collection will contain inherited tags. |
| | | * |
| | | * @return Returns an unmodifiable collection containing all the tags |
| | | * associated with this type of managed object. |
| | | */ |
| | | public final Collection<Tag> getAllTags() { |
| | | return Collections.unmodifiableCollection(allTags); |
| | | } |
| | | |
| | | /** |
| | | * Get the named child managed object definition which inherits from this |
| | | * managed object definition. This method will recursively search down |
| | | * through the inheritance hierarchy. |
| | | * |
| | | * @param name |
| | | * The name of the managed object definition sub-type. |
| | | * @return Returns the named child managed object definition which inherits |
| | | * from this managed object definition. |
| | | * @throws IllegalArgumentException |
| | | * If the specified managed object definition name was null or |
| | | * empty or if the requested subordinate managed object |
| | | * definition was not found. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<? extends C, ? extends S> getChild(String name) { |
| | | if ((name == null) || (name.length() == 0)) { |
| | | throw new IllegalArgumentException("null or empty managed object name"); |
| | | } |
| | | |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d = children.get(name); |
| | | |
| | | if (d == null) { |
| | | // Recursively search. |
| | | for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : children.values()) { |
| | | try { |
| | | d = child.getChild(name); |
| | | break; |
| | | } catch (IllegalArgumentException e) { |
| | | // Try the next child. |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (d == null) { |
| | | throw new IllegalArgumentException("child managed object definition \"" + name + "\" not found"); |
| | | } |
| | | |
| | | return d; |
| | | } |
| | | |
| | | /** |
| | | * Get the child managed object definitions which inherit directly from this |
| | | * managed object definition. |
| | | * |
| | | * @return Returns an unmodifiable collection containing the subordinate |
| | | * managed object definitions which inherit directly from this |
| | | * managed object definition. |
| | | */ |
| | | public final Collection<AbstractManagedObjectDefinition<? extends C, ? extends S>> getChildren() { |
| | | return Collections.unmodifiableCollection(children.values()); |
| | | } |
| | | |
| | | /** |
| | | * Get the constraints defined by this managed object definition. The |
| | | * returned collection will not contain inherited constraints. |
| | | * |
| | | * @return Returns an unmodifiable collection containing the constraints |
| | | * defined by this managed object definition. |
| | | */ |
| | | public final Collection<Constraint> getConstraints() { |
| | | return Collections.unmodifiableCollection(constraints); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional description of this managed object definition in the |
| | | * default locale. |
| | | * |
| | | * @return Returns the description of this managed object definition in the |
| | | * default locale, or <code>null</code> if there is no description. |
| | | * @throws UnsupportedOperationException |
| | | * If this managed object definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final LocalizableMessage getDescription() { |
| | | return getDescription(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional description of this managed object definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the description of this managed object definition in the |
| | | * specified locale, or <code>null</code> if there is no |
| | | * description. |
| | | * @throws UnsupportedOperationException |
| | | * If this managed object definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final LocalizableMessage getDescription(Locale locale) { |
| | | try { |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(this, "description", locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the name of the definition. |
| | | * |
| | | * @return Returns the name of the definition. |
| | | */ |
| | | public final String getName() { |
| | | return name; |
| | | } |
| | | |
| | | /** |
| | | * Get the parent managed object definition, if applicable. |
| | | * |
| | | * @return Returns the parent of this managed object definition, or |
| | | * <code>null</code> if this definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<? super C, ? super S> getParent() { |
| | | return parent; |
| | | } |
| | | |
| | | /** |
| | | * Get the specified property definition associated with this type of |
| | | * managed object. The search will include any inherited property |
| | | * definitions. |
| | | * |
| | | * @param name |
| | | * The name of the property definition to be retrieved. |
| | | * @return Returns the specified property definition associated with this |
| | | * type of managed object. |
| | | * @throws IllegalArgumentException |
| | | * If the specified property name was null or empty or if the |
| | | * requested property definition was not found. |
| | | */ |
| | | public final PropertyDefinition<?> getPropertyDefinition(String name) { |
| | | if ((name == null) || (name.length() == 0)) { |
| | | throw new IllegalArgumentException("null or empty property name"); |
| | | } |
| | | |
| | | PropertyDefinition<?> d = allPropertyDefinitions.get(name); |
| | | if (d == null) { |
| | | throw new IllegalArgumentException("property definition \"" + name + "\" not found"); |
| | | } |
| | | |
| | | return d; |
| | | } |
| | | |
| | | /** |
| | | * Get the property definitions defined by this managed object definition. |
| | | * The returned collection will not contain inherited property definitions. |
| | | * |
| | | * @return Returns an unmodifiable collection containing the property |
| | | * definitions defined by this managed object definition. |
| | | */ |
| | | public final Collection<PropertyDefinition<?>> getPropertyDefinitions() { |
| | | return Collections.unmodifiableCollection(propertyDefinitions.values()); |
| | | } |
| | | |
| | | /** |
| | | * Get the specified relation definition associated with this type of |
| | | * managed object.The search will include any inherited relation |
| | | * definitions. |
| | | * |
| | | * @param name |
| | | * The name of the relation definition to be retrieved. |
| | | * @return Returns the specified relation definition associated with this |
| | | * type of managed object. |
| | | * @throws IllegalArgumentException |
| | | * If the specified relation name was null or empty or if the |
| | | * requested relation definition was not found. |
| | | */ |
| | | public final RelationDefinition<?, ?> getRelationDefinition(String name) { |
| | | if ((name == null) || (name.length() == 0)) { |
| | | throw new IllegalArgumentException("null or empty relation name"); |
| | | } |
| | | |
| | | RelationDefinition<?, ?> d = allRelationDefinitions.get(name); |
| | | if (d == null) { |
| | | throw new IllegalArgumentException("relation definition \"" + name + "\" not found"); |
| | | } |
| | | |
| | | return d; |
| | | } |
| | | |
| | | /** |
| | | * Get the relation definitions defined by this managed object definition. |
| | | * The returned collection will not contain inherited relation definitions. |
| | | * |
| | | * @return Returns an unmodifiable collection containing the relation |
| | | * definitions defined by this managed object definition. |
| | | */ |
| | | public final Collection<RelationDefinition<?, ?>> getRelationDefinitions() { |
| | | return Collections.unmodifiableCollection(relationDefinitions.values()); |
| | | } |
| | | |
| | | /** |
| | | * Get the relation definitions which refer directly to this managed object |
| | | * definition. The returned collection will not contain relation definitions |
| | | * which refer to parents of this managed object definition. |
| | | * |
| | | * @return Returns an unmodifiable collection containing the relation |
| | | * definitions which refer directly to this managed object |
| | | * definition. |
| | | */ |
| | | public final Collection<RelationDefinition<C, S>> getReverseRelationDefinitions() { |
| | | return Collections.unmodifiableCollection(reverseRelationDefinitions); |
| | | } |
| | | |
| | | /** |
| | | * Get the specified aggregation property definition associated with this |
| | | * type of managed object.The search will include any inherited aggregation |
| | | * property definitions. |
| | | * |
| | | * @param name |
| | | * The name of the aggregation property definition to be |
| | | * retrieved. |
| | | * @return Returns the specified aggregation property definition associated |
| | | * with this type of managed object. |
| | | * @throws IllegalArgumentException |
| | | * If the specified aggregation property name was null or empty |
| | | * or if the requested aggregation property definition was not |
| | | * found. |
| | | */ |
| | | public final AggregationPropertyDefinition<?, ?> getAggregationPropertyDefinition(String name) { |
| | | if ((name == null) || (name.length() == 0)) { |
| | | throw new IllegalArgumentException("null or empty aggregation property name"); |
| | | } |
| | | |
| | | AggregationPropertyDefinition<?, ?> d = allAggregationPropertyDefinitions.get(name); |
| | | if (d == null) { |
| | | throw new IllegalArgumentException("aggregation property definition \"" + name + "\" not found"); |
| | | } |
| | | |
| | | return d; |
| | | } |
| | | |
| | | /** |
| | | * Get the aggregation property definitions defined by this managed object |
| | | * definition. The returned collection will not contain inherited |
| | | * aggregation property definitions. |
| | | * |
| | | * @return Returns an unmodifiable collection containing the aggregation |
| | | * property definitions defined by this managed object definition. |
| | | */ |
| | | public final Collection<AggregationPropertyDefinition<?, ?>> getAggregationPropertyDefinitions() { |
| | | return Collections.unmodifiableCollection(aggregationPropertyDefinitions.values()); |
| | | } |
| | | |
| | | /** |
| | | * Get the aggregation property definitions which refer directly to this |
| | | * managed object definition. The returned collection will not contain |
| | | * aggregation property definitions which refer to parents of this managed |
| | | * object definition. |
| | | * |
| | | * @return Returns an unmodifiable collection containing the aggregation |
| | | * property definitions which refer directly to this managed object |
| | | * definition. |
| | | */ |
| | | public final Collection<AggregationPropertyDefinition<?, ?>> getReverseAggregationPropertyDefinitions() { |
| | | return Collections.unmodifiableCollection(reverseAggregationPropertyDefinitions); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this managed object definition in the default |
| | | * locale. |
| | | * |
| | | * @return Returns the synopsis of this managed object definition in the |
| | | * default locale. |
| | | * @throws UnsupportedOperationException |
| | | * If this managed object definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final LocalizableMessage getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this managed object definition in the specified |
| | | * locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this managed object definition in the |
| | | * specified locale. |
| | | * @throws UnsupportedOperationException |
| | | * If this managed object definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final LocalizableMessage getSynopsis(Locale locale) { |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(this, "synopsis", locale); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly name of this managed object definition in the |
| | | * default locale. |
| | | * |
| | | * @return Returns the user friendly name of this managed object definition |
| | | * in the default locale. |
| | | * @throws UnsupportedOperationException |
| | | * If this managed object definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final LocalizableMessage getUserFriendlyName() { |
| | | return getUserFriendlyName(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly name of this managed object definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the user friendly name of this managed object definition |
| | | * in the specified locale. |
| | | * @throws UnsupportedOperationException |
| | | * If this managed object definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final LocalizableMessage getUserFriendlyName(Locale locale) { |
| | | return LocalizableMessage.raw(ManagedObjectDefinitionI18NResource.getInstance().getMessage(this, |
| | | "user-friendly-name", locale)); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly plural name of this managed object definition in |
| | | * the default locale. |
| | | * |
| | | * @return Returns the user friendly plural name of this managed object |
| | | * definition in the default locale. |
| | | * @throws UnsupportedOperationException |
| | | * If this managed object definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final LocalizableMessage getUserFriendlyPluralName() { |
| | | return getUserFriendlyPluralName(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly plural name of this managed object definition in |
| | | * the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the user friendly plural name of this managed object |
| | | * definition in the specified locale. |
| | | * @throws UnsupportedOperationException |
| | | * If this managed object definition is the {@link TopCfgDefn}. |
| | | */ |
| | | public final LocalizableMessage getUserFriendlyPluralName(Locale locale) { |
| | | return ManagedObjectDefinitionI18NResource.getInstance() |
| | | .getMessage(this, "user-friendly-plural-name", locale); |
| | | } |
| | | |
| | | /** |
| | | * Determine whether there are any child managed object definitions which |
| | | * inherit from this managed object definition. |
| | | * |
| | | * @return Returns <code>true</code> if this type of managed object has any |
| | | * child managed object definitions, <code>false</code> otherwise. |
| | | */ |
| | | public final boolean hasChildren() { |
| | | return !children.isEmpty(); |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not this managed object definition has the |
| | | * specified option. |
| | | * |
| | | * @param option |
| | | * The option to test. |
| | | * @return Returns <code>true</code> if the option is set, or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public final boolean hasOption(ManagedObjectOption option) { |
| | | return options.contains(option); |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not this managed object definition has the |
| | | * specified tag. |
| | | * |
| | | * @param t |
| | | * The tag definition. |
| | | * @return Returns <code>true</code> if this managed object definition has |
| | | * the specified tag. |
| | | */ |
| | | public final boolean hasTag(Tag t) { |
| | | return allTags.contains(t); |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not this managed object definition is a sub-type of |
| | | * the provided managed object definition. This managed object definition is |
| | | * a sub-type of the provided managed object definition if they are both the |
| | | * same or if the provided managed object definition can be obtained by |
| | | * recursive invocations of the {@link #getParent()} method. |
| | | * |
| | | * @param d |
| | | * The managed object definition to be checked. |
| | | * @return Returns <code>true</code> if this managed object definition is a |
| | | * sub-type of the provided managed object definition. |
| | | */ |
| | | public final boolean isChildOf(AbstractManagedObjectDefinition<?, ?> d) { |
| | | AbstractManagedObjectDefinition<?, ?> i; |
| | | for (i = this; i != null; i = i.parent) { |
| | | if (i == d) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not this managed object definition is a super-type |
| | | * of the provided managed object definition. This managed object definition |
| | | * is a super-type of the provided managed object definition if they are |
| | | * both the same or if the provided managed object definition is a member of |
| | | * the set of children returned from {@link #getAllChildren()}. |
| | | * |
| | | * @param d |
| | | * The managed object definition to be checked. |
| | | * @return Returns <code>true</code> if this managed object definition is a |
| | | * super-type of the provided managed object definition. |
| | | */ |
| | | public final boolean isParentOf(AbstractManagedObjectDefinition<?, ?> d) { |
| | | return d.isChildOf(this); |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not this managed object definition is the |
| | | * {@link TopCfgDefn}. |
| | | * |
| | | * @return Returns <code>true</code> if this managed object definition is |
| | | * the {@link TopCfgDefn}. |
| | | */ |
| | | public final boolean isTop() { |
| | | return (this instanceof TopCfgDefn); |
| | | } |
| | | |
| | | /** |
| | | * Finds a sub-type of this managed object definition which most closely |
| | | * corresponds to the matching criteria of the provided definition resolver. |
| | | * |
| | | * @param r |
| | | * The definition resolver. |
| | | * @return Returns the sub-type of this managed object definition which most |
| | | * closely corresponds to the matching criteria of the provided |
| | | * definition resolver. |
| | | * @throws DefinitionDecodingException |
| | | * If no matching sub-type could be found or if the resolved |
| | | * definition was abstract. |
| | | * @see DefinitionResolver |
| | | */ |
| | | public final ManagedObjectDefinition<? extends C, ? extends S> resolveManagedObjectDefinition(DefinitionResolver r) |
| | | throws DefinitionDecodingException { |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> rd; |
| | | rd = resolveManagedObjectDefinitionAux(this, r); |
| | | if (rd == null) { |
| | | // Unable to resolve the definition. |
| | | throw new DefinitionDecodingException(this, Reason.WRONG_TYPE_INFORMATION); |
| | | } else if (rd instanceof ManagedObjectDefinition) { |
| | | return (ManagedObjectDefinition<? extends C, ? extends S>) rd; |
| | | } else { |
| | | // Resolved definition was abstract. |
| | | throw new DefinitionDecodingException(this, Reason.ABSTRACT_TYPE_INFORMATION); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | toString(builder); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Append a string representation of the managed object definition to the |
| | | * provided string builder. |
| | | * |
| | | * @param builder |
| | | * The string builder where the string representation should be |
| | | * appended. |
| | | */ |
| | | public final void toString(StringBuilder builder) { |
| | | builder.append(getName()); |
| | | } |
| | | |
| | | /** |
| | | * Initializes all of the components associated with this managed object |
| | | * definition. |
| | | * |
| | | * @throws Exception |
| | | * If this managed object definition could not be initialized. |
| | | */ |
| | | protected final void initialize() throws Exception { |
| | | for (PropertyDefinition<?> pd : getAllPropertyDefinitions()) { |
| | | pd.initialize(); |
| | | pd.getDefaultBehaviorProvider().initialize(); |
| | | } |
| | | |
| | | for (RelationDefinition<?, ?> rd : getAllRelationDefinitions()) { |
| | | rd.initialize(); |
| | | } |
| | | |
| | | for (AggregationPropertyDefinition<?, ?> apd : getAllAggregationPropertyDefinitions()) { |
| | | |
| | | apd.initialize(); |
| | | // Now register the aggregation property in the referenced managed |
| | | // object |
| | | // definition for reverse lookups. |
| | | registerReverseAggregationPropertyDefinition(apd); |
| | | } |
| | | |
| | | for (Constraint constraint : getAllConstraints()) { |
| | | constraint.initialize(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Register a constraint with this managed object definition. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications. |
| | | * |
| | | * @param constraint |
| | | * The constraint to be registered. |
| | | */ |
| | | protected final void registerConstraint(Constraint constraint) { |
| | | constraints.add(constraint); |
| | | } |
| | | |
| | | /** |
| | | * Register a property definition with this managed object definition, |
| | | * overriding any existing property definition with the same name. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications. |
| | | * |
| | | * @param d |
| | | * The property definition to be registered. |
| | | */ |
| | | protected final void registerPropertyDefinition(PropertyDefinition<?> d) { |
| | | String propName = d.getName(); |
| | | |
| | | propertyDefinitions.put(propName, d); |
| | | allPropertyDefinitions.put(propName, d); |
| | | |
| | | if (d instanceof AggregationPropertyDefinition<?, ?>) { |
| | | AggregationPropertyDefinition<?, ?> apd = (AggregationPropertyDefinition<?, ?>) d; |
| | | aggregationPropertyDefinitions.put(propName, apd); |
| | | // The key must also contain the managed object name, since several |
| | | // MOs |
| | | // in an inheritance tree may aggregate the same aggregation |
| | | // property name |
| | | allAggregationPropertyDefinitions.put(apd.getManagedObjectDefinition().getName() + ":" + propName, apd); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Register a relation definition with this managed object definition, |
| | | * overriding any existing relation definition with the same name. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications. |
| | | * |
| | | * @param d |
| | | * The relation definition to be registered. |
| | | */ |
| | | protected final void registerRelationDefinition(RelationDefinition<?, ?> d) { |
| | | // Register the relation in this managed object definition. |
| | | String relName = d.getName(); |
| | | |
| | | relationDefinitions.put(relName, d); |
| | | allRelationDefinitions.put(relName, d); |
| | | |
| | | // Now register the relation in the referenced managed object |
| | | // definition for reverse lookups. |
| | | registerReverseRelationDefinition(d); |
| | | } |
| | | |
| | | /** |
| | | * Register an option with this managed object definition. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications. |
| | | * |
| | | * @param option |
| | | * The option to be registered. |
| | | */ |
| | | protected final void registerOption(ManagedObjectOption option) { |
| | | options.add(option); |
| | | } |
| | | |
| | | /** |
| | | * Register a tag with this managed object definition. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications. |
| | | * |
| | | * @param tag |
| | | * The tag to be registered. |
| | | */ |
| | | protected final void registerTag(Tag tag) { |
| | | allTags.add(tag); |
| | | } |
| | | |
| | | /** |
| | | * Deregister a constraint from the managed object definition. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications and is only |
| | | * intended for internal testing. |
| | | * |
| | | * @param constraint |
| | | * The constraint to be deregistered. |
| | | */ |
| | | final void deregisterConstraint(Constraint constraint) { |
| | | if (!constraints.remove(constraint)) { |
| | | throw new RuntimeException("Failed to deregister a constraint"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Deregister a relation definition from the managed object definition. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications and is only |
| | | * intended for internal testing. |
| | | * |
| | | * @param d |
| | | * The relation definition to be deregistered. |
| | | */ |
| | | final void deregisterRelationDefinition(RelationDefinition<?, ?> d) { |
| | | // Deregister the relation from this managed object definition. |
| | | String relName = d.getName(); |
| | | relationDefinitions.remove(relName); |
| | | allRelationDefinitions.remove(relName); |
| | | |
| | | // Now deregister the relation from the referenced managed object |
| | | // definition for reverse lookups. |
| | | d.getChildDefinition().reverseRelationDefinitions.remove(d); |
| | | } |
| | | |
| | | /** |
| | | * Register this managed object definition in its parent. |
| | | * <p> |
| | | * This method <b>must not</b> be called by applications and is only |
| | | * intended for internal testing. |
| | | */ |
| | | final void registerInParent() { |
| | | if (parent != null) { |
| | | parent.children.put(name, this); |
| | | } |
| | | } |
| | | |
| | | // Register a relation definition in the referenced managed object |
| | | // definition's reverse lookup table. |
| | | private <C1 extends ConfigurationClient, S1 extends Configuration> void registerReverseRelationDefinition( |
| | | RelationDefinition<C1, S1> rd) { |
| | | rd.getChildDefinition().reverseRelationDefinitions.add(rd); |
| | | } |
| | | |
| | | // Register a aggregation property definition in the referenced managed |
| | | // object |
| | | // definition's reverse lookup table. |
| | | private void registerReverseAggregationPropertyDefinition(AggregationPropertyDefinition<?, ?> apd) { |
| | | |
| | | apd.getRelationDefinition().getChildDefinition().reverseAggregationPropertyDefinitions.add(apd); |
| | | } |
| | | |
| | | // Recursively descend definition hierarchy to find the best match |
| | | // definition. |
| | | private AbstractManagedObjectDefinition<? extends C, ? extends S> resolveManagedObjectDefinitionAux( |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d, DefinitionResolver r) { |
| | | if (!r.matches(d)) { |
| | | return null; |
| | | } |
| | | |
| | | for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : d.getChildren()) { |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> rd = |
| | | resolveManagedObjectDefinitionAux(child, r); |
| | | if (rd != null) { |
| | | return rd; |
| | | } |
| | | } |
| | | |
| | | return d; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.opends.server.types.OpenDsException; |
| | | |
| | | /** |
| | | * Exceptions thrown when interacting with administration framework. |
| | | */ |
| | | public abstract class AdminException extends OpenDsException { |
| | | |
| | | /** |
| | | * Fake serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * Create an admin exception with a message and cause. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | protected AdminException(LocalizableMessage message, Throwable cause) { |
| | | super(message, cause); |
| | | } |
| | | |
| | | /** |
| | | * Create an admin exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | protected AdminException(LocalizableMessage message) { |
| | | super(message); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Exceptions thrown when interacting with administration framework that |
| | | * applications are not expected to catch. |
| | | */ |
| | | public abstract class AdminRuntimeException extends RuntimeException { |
| | | |
| | | /** |
| | | * Fake serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | // LocalizableMessage that explains the problem. |
| | | private final LocalizableMessage message; |
| | | |
| | | /** |
| | | * Create an admin runtime exception with a message and cause. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | protected AdminRuntimeException(LocalizableMessage message, Throwable cause) { |
| | | super(message.toString(), cause); |
| | | this.message = message; |
| | | } |
| | | |
| | | /** |
| | | * Create an admin runtime exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | protected AdminRuntimeException(LocalizableMessage message) { |
| | | super(message.toString()); |
| | | this.message = message; |
| | | } |
| | | |
| | | /** |
| | | * Returns the message that explains the problem that occurred. |
| | | * |
| | | * @return Returns the message describing the problem that occurred (never |
| | | * <code>null</code>). |
| | | */ |
| | | public LocalizableMessage getLocalizableMessageObject() { |
| | | return this.message; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Locale; |
| | | import java.util.MissingResourceException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Defines an optional action which administators must perform after they have |
| | | * modified a property. By default modifications to properties are assumed to |
| | | * take effect immediately and require no additional administrative action. |
| | | * Developers should be aware that, where feasible, they should implement |
| | | * components such that property modifications require no additional |
| | | * administrative action. This is required in order to minimize server downtime |
| | | * during administration and provide a more user-friendly experience. |
| | | */ |
| | | public final class AdministratorAction { |
| | | |
| | | /** |
| | | * Specifies the type of administrator action which must be performed in |
| | | * order for pending changes to take effect. |
| | | */ |
| | | public static enum Type { |
| | | /** |
| | | * Used when modifications to a property require a component restart in |
| | | * order to take effect (usually by disabling and re-enabling the |
| | | * component). May have a description describing any additional |
| | | * administrator action that is required when the component is |
| | | * restarted. |
| | | */ |
| | | COMPONENT_RESTART("component-restart"), |
| | | |
| | | /** |
| | | * Used when modifications to a property take effect immediately, and no |
| | | * additional administrator action is required. May have a description |
| | | * describing how changes to the modified property will take effect. |
| | | */ |
| | | NONE("none"), |
| | | |
| | | /** |
| | | * Used when modifications to a property require an additional |
| | | * administrative action in order to take effect. This should be used |
| | | * when neither a server restart nor a component restart are applicable. |
| | | * Always has a description which describes the additional administrator |
| | | * action which is required when the property is modified. |
| | | */ |
| | | OTHER("other"), |
| | | |
| | | /** |
| | | * Used when modifications to a property require a server restart in |
| | | * order to take effect. May have a description describing any |
| | | * additional administrator action that is required when the component |
| | | * is restarted. |
| | | */ |
| | | SERVER_RESTART("server-restart"); |
| | | |
| | | // The user-friendly name of the type. |
| | | private final String name; |
| | | |
| | | // Private constructor. |
| | | private Type(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return name; |
| | | } |
| | | |
| | | } |
| | | |
| | | // The managed object definition associated with this administrator |
| | | // action. |
| | | private final AbstractManagedObjectDefinition<?, ?> definition; |
| | | |
| | | // The name of the property definition associated with this |
| | | // administrator action. |
| | | private final String propertyName; |
| | | |
| | | // The type of administration action. |
| | | private final Type type; |
| | | |
| | | /** |
| | | * Create a new administrator action. |
| | | * |
| | | * @param type |
| | | * The type of this administration action. |
| | | * @param d |
| | | * The managed object definition associated with this |
| | | * administrator action. |
| | | * @param propertyName |
| | | * The name of the property definition associated with this |
| | | * administrator action. |
| | | */ |
| | | public AdministratorAction(Type type, AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | this.type = type; |
| | | this.definition = d; |
| | | this.propertyName = propertyName; |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this administrator action in the default locale. |
| | | * |
| | | * @return Returns the synopsis of this administrator action in the default |
| | | * locale, or <code>null</code> if there is no synopsis defined. |
| | | */ |
| | | public final LocalizableMessage getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this administrator action in the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this administrator action in the |
| | | * specified locale, or <code>null</code> if there is no synopsis |
| | | * defined. |
| | | */ |
| | | public final LocalizableMessage getSynopsis(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "property." + propertyName + ".requires-admin-action.synopsis"; |
| | | try { |
| | | return resource.getMessage(definition, property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the type of this administrator action. |
| | | * |
| | | * @return Returns the type of this administrator action. |
| | | */ |
| | | public final Type getType() { |
| | | return type; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2007-2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | import static com.forgerock.opendj.util.StaticUtils.*; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.EnumSet; |
| | | import java.util.HashMap; |
| | | import java.util.Iterator; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.MissingResourceException; |
| | | import java.util.SortedSet; |
| | | |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.forgerock.opendj.server.config.meta.RootCfgDefn; |
| | | import org.forgerock.opendj.config.client.ClientConstraintHandler; |
| | | import org.forgerock.opendj.config.client.ManagedObject; |
| | | import org.forgerock.opendj.config.client.ManagedObjectDecodingException; |
| | | import org.forgerock.opendj.config.client.ManagementContext; |
| | | import org.forgerock.opendj.config.conditions.Condition; |
| | | import org.forgerock.opendj.config.conditions.Conditions; |
| | | import org.forgerock.opendj.config.server.ConfigChangeResult; |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | import org.forgerock.opendj.config.server.ConfigurationDeleteListener; |
| | | import org.forgerock.opendj.config.server.ServerConstraintHandler; |
| | | import org.forgerock.opendj.config.server.ServerManagedObject; |
| | | import org.forgerock.opendj.config.server.ServerManagedObjectChangeListener; |
| | | import org.forgerock.opendj.config.server.ServerManagementContext; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | import org.forgerock.opendj.ldap.ResultCode; |
| | | |
| | | /** |
| | | * Aggregation property definition. |
| | | * <p> |
| | | * An aggregation property names one or more managed objects which are required |
| | | * by the managed object associated with this property. An aggregation property |
| | | * definition takes care to perform referential integrity checks: referenced |
| | | * managed objects cannot be deleted. Nor can an aggregation reference |
| | | * non-existent managed objects. Referential integrity checks are <b>not</b> |
| | | * performed during value validation. Instead they are performed when changes to |
| | | * the managed object are committed. |
| | | * <p> |
| | | * An aggregation property definition can optionally identify two properties: |
| | | * <ul> |
| | | * <li>an <code>enabled</code> property in the aggregated managed object - the |
| | | * property must be a {@link BooleanPropertyDefinition} and indicate whether the |
| | | * aggregated managed object is enabled or not. If specified, the administration |
| | | * framework will prevent the aggregated managed object from being disabled |
| | | * while it is referenced |
| | | * <li>an <code>enabled</code> property in this property's managed object - the |
| | | * property must be a {@link BooleanPropertyDefinition} and indicate whether |
| | | * this property's managed object is enabled or not. If specified, and as long |
| | | * as there is an equivalent <code>enabled</code> property defined for the |
| | | * aggregated managed object, the <code>enabled</code> property in the |
| | | * aggregated managed object will only be checked when this property is true. |
| | | * </ul> |
| | | * In other words, these properties can be used to make sure that referenced |
| | | * managed objects are not disabled while they are referenced. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | */ |
| | | public final class AggregationPropertyDefinition<C extends ConfigurationClient, S extends Configuration> extends |
| | | PropertyDefinition<String> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing aggregation property |
| | | * definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | */ |
| | | public static final class Builder<C extends ConfigurationClient, S extends Configuration> extends |
| | | AbstractBuilder<String, AggregationPropertyDefinition<C, S>> { |
| | | |
| | | // The string representation of the managed object path specifying |
| | | // the parent of the aggregated managed objects. |
| | | private String parentPathString = null; |
| | | |
| | | // The name of a relation in the parent managed object which |
| | | // contains the aggregated managed objects. |
| | | private String rdName = null; |
| | | |
| | | // The condition which is used to determine if a referenced |
| | | // managed object is enabled. |
| | | private Condition targetIsEnabledCondition = Conditions.TRUE; |
| | | |
| | | // The condition which is used to determine whether or not |
| | | // referenced managed objects need to be enabled. |
| | | private Condition targetNeedsEnablingCondition = Conditions.TRUE; |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * Sets the name of the managed object which is the parent of the |
| | | * aggregated managed objects. |
| | | * <p> |
| | | * This must be defined before the property definition can be built. |
| | | * |
| | | * @param pathString |
| | | * The string representation of the managed object path |
| | | * specifying the parent of the aggregated managed objects. |
| | | */ |
| | | public final void setParentPath(String pathString) { |
| | | this.parentPathString = pathString; |
| | | } |
| | | |
| | | /** |
| | | * Sets the relation in the parent managed object which contains the |
| | | * aggregated managed objects. |
| | | * <p> |
| | | * This must be defined before the property definition can be built. |
| | | * |
| | | * @param rdName |
| | | * The name of a relation in the parent managed object which |
| | | * contains the aggregated managed objects. |
| | | */ |
| | | public final void setRelationDefinition(String rdName) { |
| | | this.rdName = rdName; |
| | | } |
| | | |
| | | /** |
| | | * Sets the condition which is used to determine if a referenced managed |
| | | * object is enabled. By default referenced managed objects are assumed |
| | | * to always be enabled. |
| | | * |
| | | * @param condition |
| | | * The condition which is used to determine if a referenced |
| | | * managed object is enabled. |
| | | */ |
| | | public final void setTargetIsEnabledCondition(Condition condition) { |
| | | this.targetIsEnabledCondition = condition; |
| | | } |
| | | |
| | | /** |
| | | * Sets the condition which is used to determine whether or not |
| | | * referenced managed objects need to be enabled. By default referenced |
| | | * managed objects must always be enabled. |
| | | * |
| | | * @param condition |
| | | * The condition which is used to determine whether or not |
| | | * referenced managed objects need to be enabled. |
| | | */ |
| | | public final void setTargetNeedsEnablingCondition(Condition condition) { |
| | | this.targetNeedsEnablingCondition = condition; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected AggregationPropertyDefinition<C, S> buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<String> defaultBehavior) { |
| | | // Make sure that the parent path has been defined. |
| | | if (parentPathString == null) { |
| | | throw new IllegalStateException("Parent path undefined"); |
| | | } |
| | | |
| | | // Make sure that the relation definition has been defined. |
| | | if (rdName == null) { |
| | | throw new IllegalStateException("Relation definition undefined"); |
| | | } |
| | | |
| | | return new AggregationPropertyDefinition<C, S>(d, propertyName, options, adminAction, defaultBehavior, |
| | | parentPathString, rdName, targetNeedsEnablingCondition, targetIsEnabledCondition); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * A change listener which prevents the named component from being disabled. |
| | | */ |
| | | private final class ReferentialIntegrityChangeListener implements ServerManagedObjectChangeListener<S> { |
| | | |
| | | // The error message which should be returned if an attempt is |
| | | // made to disable the referenced component. |
| | | private final LocalizableMessage message; |
| | | |
| | | // The path of the referenced component. |
| | | private final ManagedObjectPath<C, S> path; |
| | | |
| | | // Creates a new referential integrity delete listener. |
| | | private ReferentialIntegrityChangeListener(ManagedObjectPath<C, S> path, LocalizableMessage message) { |
| | | this.path = path; |
| | | this.message = message; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConfigChangeResult applyConfigurationChange(ServerManagedObject<? extends S> mo) { |
| | | try { |
| | | if (targetIsEnabledCondition.evaluate(mo)) { |
| | | return new ConfigChangeResult(ResultCode.SUCCESS, false); |
| | | } |
| | | } catch (ConfigException e) { |
| | | // This should not happen - ignore it and throw an exception |
| | | // anyway below. |
| | | } |
| | | |
| | | // This should not happen - the previous call-back should have |
| | | // trapped this. |
| | | throw new IllegalStateException("Attempting to disable a referenced " |
| | | + relationDefinition.getChildDefinition().getUserFriendlyName()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isConfigurationChangeAcceptable(ServerManagedObject<? extends S> mo, |
| | | List<LocalizableMessage> unacceptableReasons) { |
| | | // Always prevent the referenced component from being |
| | | // disabled. |
| | | try { |
| | | if (!targetIsEnabledCondition.evaluate(mo)) { |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } else { |
| | | return true; |
| | | } |
| | | } catch (ConfigException e) { |
| | | // The condition could not be evaluated. |
| | | debugLogger.trace("Unable to perform post add", e); |
| | | LocalizableMessage message = |
| | | ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.get(mo.getManagedObjectDefinition() |
| | | .getUserFriendlyName(), String.valueOf(mo.getDN()), getExceptionMessage(e)); |
| | | LocalizedLogger logger = |
| | | LocalizedLogger.getLocalizedLogger(ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.resourceName()); |
| | | logger.error(message); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // Gets the path associated with this listener. |
| | | private ManagedObjectPath<C, S> getManagedObjectPath() { |
| | | return path; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * A delete listener which prevents the named component from being deleted. |
| | | */ |
| | | private final class ReferentialIntegrityDeleteListener implements ConfigurationDeleteListener<S> { |
| | | |
| | | // The DN of the referenced configuration entry. |
| | | private final DN dn; |
| | | |
| | | // The error message which should be returned if an attempt is |
| | | // made to delete the referenced component. |
| | | private final LocalizableMessage message; |
| | | |
| | | // Creates a new referential integrity delete listener. |
| | | private ReferentialIntegrityDeleteListener(DN dn, LocalizableMessage message) { |
| | | this.dn = dn; |
| | | this.message = message; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConfigChangeResult applyConfigurationDelete(S configuration) { |
| | | // This should not happen - the |
| | | // isConfigurationDeleteAcceptable() call-back should have |
| | | // trapped this. |
| | | if (configuration.dn().equals(dn)) { |
| | | // This should not happen - the |
| | | // isConfigurationDeleteAcceptable() call-back should have |
| | | // trapped this. |
| | | throw new IllegalStateException("Attempting to delete a referenced " |
| | | + relationDefinition.getChildDefinition().getUserFriendlyName()); |
| | | } else { |
| | | return new ConfigChangeResult(ResultCode.SUCCESS, false); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isConfigurationDeleteAcceptable(S configuration, List<LocalizableMessage> unacceptableReasons) { |
| | | if (configuration.dn().equals(dn)) { |
| | | // Always prevent deletion of the referenced component. |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * The server-side constraint handler implementation. |
| | | */ |
| | | private class ServerHandler extends ServerConstraintHandler { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isUsable(ServerManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ConfigException { |
| | | SortedSet<String> names = managedObject.getPropertyValues(AggregationPropertyDefinition.this); |
| | | ServerManagementContext context = managedObject.getServerContext(); |
| | | LocalizableMessage thisUFN = managedObject.getManagedObjectDefinition().getUserFriendlyName(); |
| | | String thisDN = managedObject.getDN().toString(); |
| | | LocalizableMessage thatUFN = getRelationDefinition().getUserFriendlyName(); |
| | | |
| | | boolean isUsable = true; |
| | | boolean needsEnabling = targetNeedsEnablingCondition.evaluate(managedObject); |
| | | for (String name : names) { |
| | | ManagedObjectPath<C, S> path = getChildPath(name); |
| | | String thatDN = path.toDN().toString(); |
| | | |
| | | if (!context.managedObjectExists(path)) { |
| | | LocalizableMessage msg = |
| | | ERR_SERVER_REFINT_DANGLING_REFERENCE.get(name, getName(), thisUFN, thisDN, thatUFN, thatDN); |
| | | unacceptableReasons.add(msg); |
| | | isUsable = false; |
| | | } else if (needsEnabling) { |
| | | // Check that the referenced component is enabled if |
| | | // required. |
| | | ServerManagedObject<? extends S> ref = context.getManagedObject(path); |
| | | if (!targetIsEnabledCondition.evaluate(ref)) { |
| | | LocalizableMessage msg = |
| | | ERR_SERVER_REFINT_TARGET_DISABLED.get(name, getName(), thisUFN, thisDN, thatUFN, thatDN); |
| | | unacceptableReasons.add(msg); |
| | | isUsable = false; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return isUsable; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void performPostAdd(ServerManagedObject<?> managedObject) throws ConfigException { |
| | | // First make sure existing listeners associated with this |
| | | // managed object are removed. This is required in order to |
| | | // prevent multiple change listener registrations from |
| | | // occurring, for example if this call-back is invoked multiple |
| | | // times after the same add event. |
| | | performPostDelete(managedObject); |
| | | |
| | | // Add change and delete listeners against all referenced |
| | | // components. |
| | | LocalizableMessage thisUFN = managedObject.getManagedObjectDefinition().getUserFriendlyName(); |
| | | String thisDN = managedObject.getDN().toString(); |
| | | LocalizableMessage thatUFN = getRelationDefinition().getUserFriendlyName(); |
| | | |
| | | // Referenced managed objects will only need a change listener |
| | | // if they have can be disabled. |
| | | boolean needsChangeListeners = targetNeedsEnablingCondition.evaluate(managedObject); |
| | | |
| | | // Delete listeners need to be registered against the parent |
| | | // entry of the referenced components. |
| | | ServerManagementContext context = managedObject.getServerContext(); |
| | | ManagedObjectPath<?, ?> parentPath = getParentPath(); |
| | | ServerManagedObject<?> parent = context.getManagedObject(parentPath); |
| | | |
| | | // Create entries in the listener tables. |
| | | List<ReferentialIntegrityDeleteListener> dlist = new LinkedList<ReferentialIntegrityDeleteListener>(); |
| | | deleteListeners.put(managedObject.getDN(), dlist); |
| | | |
| | | List<ReferentialIntegrityChangeListener> clist = new LinkedList<ReferentialIntegrityChangeListener>(); |
| | | changeListeners.put(managedObject.getDN(), clist); |
| | | |
| | | for (String name : managedObject.getPropertyValues(AggregationPropertyDefinition.this)) { |
| | | ManagedObjectPath<C, S> path = getChildPath(name); |
| | | DN dn = path.toDN(); |
| | | String thatDN = dn.toString(); |
| | | |
| | | // Register the delete listener. |
| | | LocalizableMessage msg = |
| | | ERR_SERVER_REFINT_CANNOT_DELETE.get(thatUFN, thatDN, getName(), thisUFN, thisDN); |
| | | ReferentialIntegrityDeleteListener dl = new ReferentialIntegrityDeleteListener(dn, msg); |
| | | parent.registerDeleteListener(getRelationDefinition(), dl); |
| | | dlist.add(dl); |
| | | |
| | | // Register the change listener if required. |
| | | if (needsChangeListeners) { |
| | | ServerManagedObject<? extends S> ref = context.getManagedObject(path); |
| | | msg = ERR_SERVER_REFINT_CANNOT_DISABLE.get(thatUFN, thatDN, getName(), thisUFN, thisDN); |
| | | ReferentialIntegrityChangeListener cl = new ReferentialIntegrityChangeListener(path, msg); |
| | | ref.registerChangeListener(cl); |
| | | clist.add(cl); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void performPostDelete(ServerManagedObject<?> managedObject) throws ConfigException { |
| | | // Remove any registered delete and change listeners. |
| | | ServerManagementContext context = managedObject.getServerContext(); |
| | | DN dn = managedObject.getDN(); |
| | | |
| | | // Delete listeners need to be deregistered against the parent |
| | | // entry of the referenced components. |
| | | ManagedObjectPath<?, ?> parentPath = getParentPath(); |
| | | ServerManagedObject<?> parent = context.getManagedObject(parentPath); |
| | | if (deleteListeners.containsKey(dn)) { |
| | | for (ReferentialIntegrityDeleteListener dl : deleteListeners.get(dn)) { |
| | | parent.deregisterDeleteListener(getRelationDefinition(), dl); |
| | | } |
| | | deleteListeners.remove(dn); |
| | | } |
| | | |
| | | // Change listeners need to be deregistered from their |
| | | // associated referenced component. |
| | | if (changeListeners.containsKey(dn)) { |
| | | for (ReferentialIntegrityChangeListener cl : changeListeners.get(dn)) { |
| | | ManagedObjectPath<C, S> path = cl.getManagedObjectPath(); |
| | | ServerManagedObject<? extends S> ref = context.getManagedObject(path); |
| | | ref.deregisterChangeListener(cl); |
| | | } |
| | | changeListeners.remove(dn); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void performPostModify(ServerManagedObject<?> managedObject) throws ConfigException { |
| | | // Remove all the constraints associated with this managed |
| | | // object and then re-register them. |
| | | performPostDelete(managedObject); |
| | | performPostAdd(managedObject); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * The client-side constraint handler implementation which enforces |
| | | * referential integrity when aggregating managed objects are added or |
| | | * modified. |
| | | */ |
| | | private class SourceClientHandler extends ClientConstraintHandler { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isAddAcceptable(ManagementContext context, ManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | // If all of this managed object's "enabled" properties are true |
| | | // then any referenced managed objects must also be enabled. |
| | | boolean needsEnabling = targetNeedsEnablingCondition.evaluate(context, managedObject); |
| | | |
| | | // Check the referenced managed objects exist and, if required, |
| | | // are enabled. |
| | | boolean isAcceptable = true; |
| | | LocalizableMessage ufn = getRelationDefinition().getUserFriendlyName(); |
| | | for (String name : managedObject.getPropertyValues(AggregationPropertyDefinition.this)) { |
| | | // Retrieve the referenced managed object and make sure it |
| | | // exists. |
| | | ManagedObjectPath<?, ?> path = getChildPath(name); |
| | | ManagedObject<?> ref; |
| | | try { |
| | | ref = context.getManagedObject(path); |
| | | } catch (DefinitionDecodingException e) { |
| | | LocalizableMessage msg = |
| | | ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name, getName(), e.getMessageObject()); |
| | | unacceptableReasons.add(msg); |
| | | isAcceptable = false; |
| | | continue; |
| | | } catch (ManagedObjectDecodingException e) { |
| | | LocalizableMessage msg = |
| | | ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name, getName(), e.getMessageObject()); |
| | | unacceptableReasons.add(msg); |
| | | isAcceptable = false; |
| | | continue; |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_DANGLING_REFERENCE.get(ufn, name, getName()); |
| | | unacceptableReasons.add(msg); |
| | | isAcceptable = false; |
| | | continue; |
| | | } |
| | | |
| | | // Make sure the reference managed object is enabled. |
| | | if (needsEnabling) { |
| | | if (!targetIsEnabledCondition.evaluate(context, ref)) { |
| | | LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_DISABLED.get(ufn, name, getName()); |
| | | unacceptableReasons.add(msg); |
| | | isAcceptable = false; |
| | | } |
| | | } |
| | | } |
| | | return isAcceptable; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isModifyAcceptable(ManagementContext context, ManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | // The same constraint applies as for adds. |
| | | return isAddAcceptable(context, managedObject, unacceptableReasons); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * The client-side constraint handler implementation which enforces |
| | | * referential integrity when aggregated managed objects are deleted or |
| | | * modified. |
| | | */ |
| | | private class TargetClientHandler extends ClientConstraintHandler { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isDeleteAcceptable(ManagementContext context, ManagedObjectPath<?, ?> path, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | // Any references to the deleted managed object should cause a |
| | | // constraint violation. |
| | | boolean isAcceptable = true; |
| | | for (ManagedObject<?> mo : findReferences(context, getManagedObjectDefinition(), path.getName())) { |
| | | String name = mo.getManagedObjectPath().getName(); |
| | | if (name == null) { |
| | | LocalizableMessage msg = |
| | | ERR_CLIENT_REFINT_CANNOT_DELETE_WITHOUT_NAME.get(getName(), mo.getManagedObjectDefinition() |
| | | .getUserFriendlyName(), getManagedObjectDefinition().getUserFriendlyName()); |
| | | unacceptableReasons.add(msg); |
| | | } else { |
| | | LocalizableMessage msg = |
| | | ERR_CLIENT_REFINT_CANNOT_DELETE_WITH_NAME.get(getName(), mo.getManagedObjectDefinition() |
| | | .getUserFriendlyName(), name, getManagedObjectDefinition().getUserFriendlyName()); |
| | | unacceptableReasons.add(msg); |
| | | } |
| | | isAcceptable = false; |
| | | } |
| | | return isAcceptable; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isModifyAcceptable(ManagementContext context, ManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | // If the modified managed object is disabled and there are some |
| | | // active references then refuse the change. |
| | | if (targetIsEnabledCondition.evaluate(context, managedObject)) { |
| | | return true; |
| | | } |
| | | |
| | | // The referenced managed object is disabled. Need to check for |
| | | // active references. |
| | | boolean isAcceptable = true; |
| | | for (ManagedObject<?> mo : findReferences(context, getManagedObjectDefinition(), managedObject |
| | | .getManagedObjectPath().getName())) { |
| | | if (targetNeedsEnablingCondition.evaluate(context, mo)) { |
| | | String name = mo.getManagedObjectPath().getName(); |
| | | if (name == null) { |
| | | LocalizableMessage msg = |
| | | ERR_CLIENT_REFINT_CANNOT_DISABLE_WITHOUT_NAME.get(managedObject |
| | | .getManagedObjectDefinition().getUserFriendlyName(), getName(), mo |
| | | .getManagedObjectDefinition().getUserFriendlyName()); |
| | | unacceptableReasons.add(msg); |
| | | } else { |
| | | LocalizableMessage msg = |
| | | ERR_CLIENT_REFINT_CANNOT_DISABLE_WITH_NAME.get( |
| | | managedObject.getManagedObjectDefinition().getUserFriendlyName(), getName(), |
| | | mo.getManagedObjectDefinition().getUserFriendlyName(), name); |
| | | unacceptableReasons.add(msg); |
| | | } |
| | | isAcceptable = false; |
| | | } |
| | | } |
| | | return isAcceptable; |
| | | } |
| | | |
| | | // Find all managed objects which reference the named managed |
| | | // object using this property. |
| | | private <C1 extends ConfigurationClient> List<ManagedObject<? extends C1>> findReferences( |
| | | ManagementContext context, AbstractManagedObjectDefinition<C1, ?> mod, String name) |
| | | throws ErrorResultException { |
| | | List<ManagedObject<? extends C1>> instances = findInstances(context, mod); |
| | | |
| | | Iterator<ManagedObject<? extends C1>> i = instances.iterator(); |
| | | while (i.hasNext()) { |
| | | ManagedObject<? extends C1> mo = i.next(); |
| | | boolean hasReference = false; |
| | | |
| | | for (String value : mo.getPropertyValues(AggregationPropertyDefinition.this)) { |
| | | if (compare(value, name) == 0) { |
| | | hasReference = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!hasReference) { |
| | | i.remove(); |
| | | } |
| | | } |
| | | |
| | | return instances; |
| | | } |
| | | |
| | | // Find all instances of a specific type of managed object. |
| | | @SuppressWarnings("unchecked") |
| | | private <C1 extends ConfigurationClient> List<ManagedObject<? extends C1>> findInstances( |
| | | ManagementContext context, AbstractManagedObjectDefinition<C1, ?> mod) throws ErrorResultException { |
| | | List<ManagedObject<? extends C1>> instances = new LinkedList<ManagedObject<? extends C1>>(); |
| | | |
| | | if (mod == RootCfgDefn.getInstance()) { |
| | | instances.add((ManagedObject<? extends C1>) context.getRootConfigurationManagedObject()); |
| | | } else { |
| | | for (RelationDefinition<? super C1, ?> rd : mod.getAllReverseRelationDefinitions()) { |
| | | for (ManagedObject<?> parent : findInstances(context, rd.getParentDefinition())) { |
| | | try { |
| | | if (rd instanceof SingletonRelationDefinition) { |
| | | SingletonRelationDefinition<? super C1, ?> srd = |
| | | (SingletonRelationDefinition<? super C1, ?>) rd; |
| | | ManagedObject<?> mo = parent.getChild(srd); |
| | | if (mo.getManagedObjectDefinition().isChildOf(mod)) { |
| | | instances.add((ManagedObject<? extends C1>) mo); |
| | | } |
| | | } else if (rd instanceof OptionalRelationDefinition) { |
| | | OptionalRelationDefinition<? super C1, ?> ord = |
| | | (OptionalRelationDefinition<? super C1, ?>) rd; |
| | | ManagedObject<?> mo = parent.getChild(ord); |
| | | if (mo.getManagedObjectDefinition().isChildOf(mod)) { |
| | | instances.add((ManagedObject<? extends C1>) mo); |
| | | } |
| | | } else if (rd instanceof InstantiableRelationDefinition) { |
| | | InstantiableRelationDefinition<? super C1, ?> ird = |
| | | (InstantiableRelationDefinition<? super C1, ?>) rd; |
| | | |
| | | for (String name : parent.listChildren(ird)) { |
| | | ManagedObject<?> mo = parent.getChild(ird, name); |
| | | if (mo.getManagedObjectDefinition().isChildOf(mod)) { |
| | | instances.add((ManagedObject<? extends C1>) mo); |
| | | } |
| | | } |
| | | } |
| | | } catch (OperationsException e) { |
| | | // Ignore all operations exceptions. |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return instances; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Creates an aggregation property definition builder. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new aggregation property definition builder. |
| | | */ |
| | | public static <C extends ConfigurationClient, S extends Configuration> Builder<C, S> createBuilder( |
| | | AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder<C, S>(d, propertyName); |
| | | } |
| | | |
| | | private static final Logger debugLogger = LoggerFactory.getLogger(AggregationPropertyDefinition.class); |
| | | |
| | | // The active server-side referential integrity change listeners |
| | | // associated with this property. |
| | | private final Map<DN, List<ReferentialIntegrityChangeListener>> changeListeners = |
| | | new HashMap<DN, List<ReferentialIntegrityChangeListener>>(); |
| | | |
| | | // The active server-side referential integrity delete listeners |
| | | // associated with this property. |
| | | private final Map<DN, List<ReferentialIntegrityDeleteListener>> deleteListeners = |
| | | new HashMap<DN, List<ReferentialIntegrityDeleteListener>>(); |
| | | |
| | | // The name of the managed object which is the parent of the |
| | | // aggregated managed objects. |
| | | private ManagedObjectPath<?, ?> parentPath; |
| | | |
| | | // The string representation of the managed object path specifying |
| | | // the parent of the aggregated managed objects. |
| | | private final String parentPathString; |
| | | |
| | | // The name of a relation in the parent managed object which |
| | | // contains the aggregated managed objects. |
| | | private final String rdName; |
| | | |
| | | // The relation in the parent managed object which contains the |
| | | // aggregated managed objects. |
| | | private InstantiableRelationDefinition<C, S> relationDefinition; |
| | | |
| | | // The source constraint. |
| | | private final Constraint sourceConstraint; |
| | | |
| | | // The condition which is used to determine if a referenced managed |
| | | // object is enabled. |
| | | private final Condition targetIsEnabledCondition; |
| | | |
| | | // The condition which is used to determine whether or not |
| | | // referenced managed objects need to be enabled. |
| | | private final Condition targetNeedsEnablingCondition; |
| | | |
| | | // Private constructor. |
| | | private AggregationPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<String> defaultBehavior, String parentPathString, String rdName, |
| | | Condition targetNeedsEnablingCondition, Condition targetIsEnabledCondition) { |
| | | super(d, String.class, propertyName, options, adminAction, defaultBehavior); |
| | | |
| | | this.parentPathString = parentPathString; |
| | | this.rdName = rdName; |
| | | this.targetNeedsEnablingCondition = targetNeedsEnablingCondition; |
| | | this.targetIsEnabledCondition = targetIsEnabledCondition; |
| | | this.sourceConstraint = new Constraint() { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<ClientConstraintHandler> getClientConstraintHandlers() { |
| | | ClientConstraintHandler handler = new SourceClientHandler(); |
| | | return Collections.singleton(handler); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<ServerConstraintHandler> getServerConstraintHandlers() { |
| | | ServerConstraintHandler handler = new ServerHandler(); |
| | | return Collections.singleton(handler); |
| | | } |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitAggregation(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) { |
| | | return v.visitAggregation(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | try { |
| | | validateValue(value, options); |
| | | return value; |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Constructs a DN for a referenced managed object having the provided name. |
| | | * This method is implemented by first calling {@link #getChildPath(String)} |
| | | * and then invoking {@code ManagedObjectPath.toDN()} on the returned path. |
| | | * |
| | | * @param name |
| | | * The name of the child managed object. |
| | | * @return Returns a DN for a referenced managed object having the provided |
| | | * name. |
| | | */ |
| | | public final DN getChildDN(String name) { |
| | | return getChildPath(name).toDN(); |
| | | } |
| | | |
| | | /** |
| | | * Constructs a managed object path for a referenced managed object having |
| | | * the provided name. |
| | | * |
| | | * @param name |
| | | * The name of the child managed object. |
| | | * @return Returns a managed object path for a referenced managed object |
| | | * having the provided name. |
| | | */ |
| | | public final ManagedObjectPath<C, S> getChildPath(String name) { |
| | | return parentPath.child(relationDefinition, name); |
| | | } |
| | | |
| | | /** |
| | | * Gets the name of the managed object which is the parent of the aggregated |
| | | * managed objects. |
| | | * |
| | | * @return Returns the name of the managed object which is the parent of the |
| | | * aggregated managed objects. |
| | | */ |
| | | public final ManagedObjectPath<?, ?> getParentPath() { |
| | | return parentPath; |
| | | } |
| | | |
| | | /** |
| | | * Gets the relation in the parent managed object which contains the |
| | | * aggregated managed objects. |
| | | * |
| | | * @return Returns the relation in the parent managed object which contains |
| | | * the aggregated managed objects. |
| | | */ |
| | | public final InstantiableRelationDefinition<C, S> getRelationDefinition() { |
| | | return relationDefinition; |
| | | } |
| | | |
| | | /** |
| | | * Gets the constraint which should be enforced on the aggregating managed |
| | | * object. |
| | | * |
| | | * @return Returns the constraint which should be enforced on the |
| | | * aggregating managed object. |
| | | */ |
| | | public final Constraint getSourceConstraint() { |
| | | return sourceConstraint; |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional constraint synopsis of this aggregation property |
| | | * definition in the default locale. The constraint synopsis describes when |
| | | * and how referenced managed objects must be enabled. When there are no |
| | | * constraints between the source managed object and the objects it |
| | | * references through this aggregation, <code>null</code> is returned. |
| | | * |
| | | * @return Returns the optional constraint synopsis of this aggregation |
| | | * property definition in the default locale, or <code>null</code> |
| | | * if there is no constraint synopsis. |
| | | */ |
| | | public final LocalizableMessage getSourceConstraintSynopsis() { |
| | | return getSourceConstraintSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional constraint synopsis of this aggregation property |
| | | * definition in the specified locale.The constraint synopsis describes when |
| | | * and how referenced managed objects must be enabled. When there are no |
| | | * constraints between the source managed object and the objects it |
| | | * references through this aggregation, <code>null</code> is returned. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the optional constraint synopsis of this aggregation |
| | | * property definition in the specified locale, or <code>null</code> |
| | | * if there is no constraint synopsis. |
| | | */ |
| | | public final LocalizableMessage getSourceConstraintSynopsis(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "property." + getName() + ".syntax.aggregation.constraint-synopsis"; |
| | | try { |
| | | return resource.getMessage(getManagedObjectDefinition(), property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the condition which is used to determine if a referenced managed |
| | | * object is enabled. |
| | | * |
| | | * @return Returns the condition which is used to determine if a referenced |
| | | * managed object is enabled. |
| | | */ |
| | | public final Condition getTargetIsEnabledCondition() { |
| | | return targetIsEnabledCondition; |
| | | } |
| | | |
| | | /** |
| | | * Gets the condition which is used to determine whether or not referenced |
| | | * managed objects need to be enabled. |
| | | * |
| | | * @return Returns the condition which is used to determine whether or not |
| | | * referenced managed objects need to be enabled. |
| | | */ |
| | | public final Condition getTargetNeedsEnablingCondition() { |
| | | return targetNeedsEnablingCondition; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String normalizeValue(String value) { |
| | | try { |
| | | Reference<C, S> reference = Reference.parseName(parentPath, relationDefinition, value); |
| | | return reference.getNormalizedName(); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | super.toString(builder); |
| | | |
| | | builder.append(" parentPath="); |
| | | builder.append(parentPath); |
| | | |
| | | builder.append(" relationDefinition="); |
| | | builder.append(relationDefinition.getName()); |
| | | |
| | | builder.append(" targetNeedsEnablingCondition="); |
| | | builder.append(String.valueOf(targetNeedsEnablingCondition)); |
| | | |
| | | builder.append(" targetIsEnabledCondition="); |
| | | builder.append(String.valueOf(targetIsEnabledCondition)); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(String value, PropertyDefinitionsOptions options) { |
| | | try { |
| | | Reference.parseName(parentPath, relationDefinition, value); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | @Override |
| | | public void initialize() throws Exception { |
| | | // Decode the path. |
| | | parentPath = ManagedObjectPath.valueOf(parentPathString); |
| | | |
| | | // Decode the relation definition. |
| | | AbstractManagedObjectDefinition<?, ?> parent = parentPath.getManagedObjectDefinition(); |
| | | RelationDefinition<?, ?> rd = parent.getRelationDefinition(rdName); |
| | | relationDefinition = (InstantiableRelationDefinition<C, S>) rd; |
| | | |
| | | // Now decode the conditions. |
| | | targetNeedsEnablingCondition.initialize(getManagedObjectDefinition()); |
| | | targetIsEnabledCondition.initialize(rd.getChildDefinition()); |
| | | |
| | | // Register a client-side constraint with the referenced |
| | | // definition. This will be used to enforce referential integrity |
| | | // for actions performed against referenced managed objects. |
| | | Constraint constraint = new Constraint() { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<ClientConstraintHandler> getClientConstraintHandlers() { |
| | | ClientConstraintHandler handler = new TargetClientHandler(); |
| | | return Collections.singleton(handler); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<ServerConstraintHandler> getServerConstraintHandlers() { |
| | | return Collections.emptyList(); |
| | | } |
| | | }; |
| | | |
| | | rd.getChildDefinition().registerConstraint(constraint); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Locale; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * A default behavior provider which indicates special behavior. It should be |
| | | * used by properties which have a default behavior which cannot be directly |
| | | * represented using real values of the property. For example, a property |
| | | * containing a set of user names might default to "all users" when no values |
| | | * are provided. This meaning cannot be represented using a finite set of |
| | | * values. |
| | | * |
| | | * @param <T> |
| | | * The type of values represented by this provider. |
| | | */ |
| | | public final class AliasDefaultBehaviorProvider<T> extends DefaultBehaviorProvider<T> { |
| | | |
| | | // The managed object definition associated with this default |
| | | // behavior. |
| | | private final AbstractManagedObjectDefinition<?, ?> definition; |
| | | |
| | | // The name of the property definition associated with this default |
| | | // behavior. |
| | | private final String propertyName; |
| | | |
| | | /** |
| | | * Create an alias default behavior provider. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this default |
| | | * behavior. |
| | | * @param propertyName |
| | | * The name of the property definition associated with this |
| | | * default behavior. |
| | | */ |
| | | public AliasDefaultBehaviorProvider(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | this.definition = d; |
| | | this.propertyName = propertyName; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <R, P> R accept(DefaultBehaviorProviderVisitor<T, R, P> v, P p) { |
| | | return v.visitAlias(this, p); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this alias default behavior in the default locale. |
| | | * |
| | | * @return Returns the synopsis of this alias default behavior in the |
| | | * default locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this alias default behavior in the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this alias default behavior in the |
| | | * specified locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "property." + propertyName + ".default-behavior.alias.synopsis"; |
| | | return resource.getMessage(definition, property, locale); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | |
| | | import org.forgerock.opendj.ldap.schema.AttributeType; |
| | | import org.opends.server.core.DirectoryServer; |
| | | |
| | | /** |
| | | * Attribute type property definition. |
| | | */ |
| | | public final class AttributeTypePropertyDefinition extends PropertyDefinition<AttributeType> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing attribute type property |
| | | * definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<AttributeType, AttributeTypePropertyDefinition> { |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected AttributeTypePropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<AttributeType> defaultBehavior) { |
| | | return new AttributeTypePropertyDefinition(d, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Create a attribute type property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new attribute type property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private AttributeTypePropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<AttributeType> defaultBehavior) { |
| | | super(d, AttributeType.class, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitAttributeType(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, AttributeType value, P p) { |
| | | return v.visitAttributeType(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(AttributeType o1, AttributeType o2) { |
| | | return o1.getNameOrOID().compareToIgnoreCase(o2.getNameOrOID()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AttributeType decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | String name = value.trim().toLowerCase(); |
| | | AttributeType type = DirectoryServer.getAttributeType(name, !options.checkSchemaForAttributes()); |
| | | |
| | | if (type == null) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } else { |
| | | try { |
| | | validateValue(type, options); |
| | | return type; |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String encodeValue(AttributeType value) { |
| | | return value.getNameOrOID(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(AttributeType value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // No implementation required. |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Boolean property definition. |
| | | */ |
| | | public final class BooleanPropertyDefinition extends PropertyDefinition<Boolean> { |
| | | |
| | | /** |
| | | * Mapping used for parsing boolean values. This mapping is more flexible |
| | | * than the standard boolean string parser and supports common true/false |
| | | * synonyms used in configuration. |
| | | */ |
| | | private static final Map<String, Boolean> VALUE_MAP; |
| | | static { |
| | | VALUE_MAP = new HashMap<String, Boolean>(); |
| | | |
| | | // We could have more possibilities but decided against in issue 1960. |
| | | VALUE_MAP.put("false", Boolean.FALSE); |
| | | VALUE_MAP.put("true", Boolean.TRUE); |
| | | } |
| | | |
| | | /** |
| | | * An interface for incrementally constructing boolean property definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<Boolean, BooleanPropertyDefinition> { |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected BooleanPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Boolean> defaultBehavior) { |
| | | return new BooleanPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Create a boolean property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new boolean property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private BooleanPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Boolean> defaultBehavior) { |
| | | super(d, Boolean.class, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(Boolean value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // No additional validation required. |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Boolean decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | String nvalue = value.trim().toLowerCase(); |
| | | Boolean b = VALUE_MAP.get(nvalue); |
| | | |
| | | if (b == null) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } else { |
| | | return b; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitBoolean(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, Boolean value, P p) { |
| | | return v.visitBoolean(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(Boolean o1, Boolean o2) { |
| | | return o1.compareTo(o2); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2012 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | import static com.forgerock.opendj.ldap.ExtensionMessages.*; |
| | | import static com.forgerock.opendj.util.StaticUtils.*; |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.BufferedReader; |
| | | import java.io.File; |
| | | import java.io.FileFilter; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.io.PrintStream; |
| | | import java.lang.reflect.Method; |
| | | import java.net.MalformedURLException; |
| | | import java.net.URL; |
| | | import java.net.URLClassLoader; |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.jar.Attributes; |
| | | import java.util.jar.JarEntry; |
| | | import java.util.jar.JarFile; |
| | | import java.util.jar.Manifest; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.forgerock.opendj.server.config.meta.RootCfgDefn; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.forgerock.opendj.server.util.DynamicConstants; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import com.forgerock.opendj.ldap.AdminMessages; |
| | | |
| | | /** |
| | | * Manages the class loader which should be used for loading configuration |
| | | * definition classes and associated extensions. |
| | | * <p> |
| | | * For extensions which define their own extended configuration definitions, the |
| | | * class loader will make sure that the configuration definition classes are |
| | | * loaded and initialized. |
| | | * <p> |
| | | * Initially the class loader provider is disabled, and calls to the |
| | | * {@link #getClassLoader()} will return the system default class loader. |
| | | * <p> |
| | | * Applications <b>MUST NOT</b> maintain persistent references to the class |
| | | * loader as it can change at run-time. |
| | | */ |
| | | public final class ClassLoaderProvider { |
| | | |
| | | private static final LocalizedLogger adminLogger = LocalizedLogger.getLocalizedLogger(AdminMessages |
| | | .resourceName()); |
| | | private static final Logger debugLogger = LoggerFactory.getLogger(ClassLoaderProvider.class); |
| | | |
| | | /** |
| | | * Private URLClassLoader implementation. This is only required so that we |
| | | * can provide access to the addURL method. |
| | | */ |
| | | private static final class MyURLClassLoader extends URLClassLoader { |
| | | |
| | | /** |
| | | * Create a class loader with the default parent class loader. |
| | | */ |
| | | public MyURLClassLoader() { |
| | | super(new URL[0]); |
| | | } |
| | | |
| | | /** |
| | | * Create a class loader with the provided parent class loader. |
| | | * |
| | | * @param parent |
| | | * The parent class loader. |
| | | */ |
| | | public MyURLClassLoader(ClassLoader parent) { |
| | | super(new URL[0], parent); |
| | | } |
| | | |
| | | /** |
| | | * Add a Jar file to this class loader. |
| | | * |
| | | * @param jarFile |
| | | * The name of the Jar file. |
| | | * @throws MalformedURLException |
| | | * If a protocol handler for the URL could not be found, or |
| | | * if some other error occurred while constructing the URL. |
| | | * @throws SecurityException |
| | | * If a required system property value cannot be accessed. |
| | | */ |
| | | public void addJarFile(File jarFile) throws MalformedURLException { |
| | | addURL(jarFile.toURI().toURL()); |
| | | } |
| | | |
| | | } |
| | | |
| | | // The name of the manifest file listing the core configuration |
| | | // definition classes. |
| | | private static final String CORE_MANIFEST = "core.manifest"; |
| | | |
| | | // The name of the manifest file listing a extension's configuration |
| | | // definition classes. |
| | | private static final String EXTENSION_MANIFEST = "extension.manifest"; |
| | | |
| | | // The name of the lib directory. |
| | | private static final String LIB_DIR = "lib"; |
| | | |
| | | // The name of the extensions directory. |
| | | private static final String EXTENSIONS_DIR = "extensions"; |
| | | |
| | | // The singleton instance. |
| | | private static final ClassLoaderProvider INSTANCE = new ClassLoaderProvider(); |
| | | |
| | | // Attribute name in jar's MANIFEST corresponding to the revision number. |
| | | private static final String REVISION_NUMBER = "Revision-Number"; |
| | | |
| | | // The attribute names for build information is name, version and revision |
| | | // number |
| | | private static final String[] BUILD_INFORMATION_ATTRIBUTE_NAMES = |
| | | new String[] { Attributes.Name.EXTENSION_NAME.toString(), Attributes.Name.IMPLEMENTATION_VERSION.toString(), |
| | | REVISION_NUMBER }; |
| | | |
| | | /** |
| | | * Get the single application wide class loader provider instance. |
| | | * |
| | | * @return Returns the single application wide class loader provider |
| | | * instance. |
| | | */ |
| | | public static ClassLoaderProvider getInstance() { |
| | | return INSTANCE; |
| | | } |
| | | |
| | | // Set of registered Jar files. |
| | | private Set<File> jarFiles = new HashSet<File>(); |
| | | |
| | | // Underlying class loader used to load classes and resources (null |
| | | // if disabled). |
| | | // |
| | | // We contain a reference to the URLClassLoader rather than |
| | | // sub-class it so that it is possible to replace the loader at |
| | | // run-time. For example, when removing or replacing extension Jar |
| | | // files (the URLClassLoader only supports adding new |
| | | // URLs, not removal). |
| | | private MyURLClassLoader loader = null; |
| | | |
| | | // Private constructor. |
| | | private ClassLoaderProvider() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Add the named extensions to this class loader provider. |
| | | * |
| | | * @param extensions |
| | | * The names of the extensions to be loaded. The names should not |
| | | * contain any path elements and must be located within the |
| | | * extensions folder. |
| | | * @throws InitializationException |
| | | * If one of the extensions could not be loaded and initialized. |
| | | * @throws IllegalStateException |
| | | * If this class loader provider is disabled. |
| | | * @throws IllegalArgumentException |
| | | * If one of the extension names was not a single relative path |
| | | * name element or was an absolute path. |
| | | */ |
| | | public synchronized void addExtension(String... extensions) throws InitializationException { |
| | | Reject.ifNull(extensions); |
| | | |
| | | if (loader == null) { |
| | | throw new IllegalStateException("Class loader provider is disabled."); |
| | | } |
| | | |
| | | File libPath = new File(DirectoryServer.getInstanceRoot(), LIB_DIR); |
| | | File extensionsPath = new File(libPath, EXTENSIONS_DIR); |
| | | |
| | | ArrayList<File> files = new ArrayList<File>(extensions.length); |
| | | for (String extension : extensions) { |
| | | File file = new File(extensionsPath, extension); |
| | | |
| | | // For security reasons we need to make sure that the file name |
| | | // passed in did not contain any path elements and names a file |
| | | // in the extensions folder. |
| | | |
| | | // Can handle potential null parent. |
| | | if (!extensionsPath.equals(file.getParentFile())) { |
| | | throw new IllegalArgumentException("Illegal file name: " + extension); |
| | | } |
| | | |
| | | // The file is valid. |
| | | files.add(file); |
| | | } |
| | | |
| | | // Add the extensions. |
| | | addExtension(files.toArray(new File[files.size()])); |
| | | } |
| | | |
| | | /** |
| | | * Disable this class loader provider and removed any registered extensions. |
| | | * |
| | | * @throws IllegalStateException |
| | | * If this class loader provider is already disabled. |
| | | */ |
| | | public synchronized void disable() { |
| | | if (loader == null) { |
| | | throw new IllegalStateException("Class loader provider already disabled."); |
| | | } |
| | | loader = null; |
| | | jarFiles = new HashSet<File>(); |
| | | } |
| | | |
| | | /** |
| | | * Enable this class loader provider using the application's class loader as |
| | | * the parent class loader. |
| | | * |
| | | * @throws InitializationException |
| | | * If the class loader provider could not initialize |
| | | * successfully. |
| | | * @throws IllegalStateException |
| | | * If this class loader provider is already enabled. |
| | | */ |
| | | public synchronized void enable() throws InitializationException { |
| | | enable(RootCfgDefn.class.getClassLoader()); |
| | | } |
| | | |
| | | /** |
| | | * Enable this class loader provider using the provided parent class loader. |
| | | * |
| | | * @param parent |
| | | * The parent class loader. |
| | | * @throws InitializationException |
| | | * If the class loader provider could not initialize |
| | | * successfully. |
| | | * @throws IllegalStateException |
| | | * If this class loader provider is already enabled. |
| | | */ |
| | | public synchronized void enable(ClassLoader parent) throws InitializationException { |
| | | if (loader != null) { |
| | | throw new IllegalStateException("Class loader provider already enabled."); |
| | | } |
| | | |
| | | if (parent != null) { |
| | | loader = new MyURLClassLoader(parent); |
| | | } else { |
| | | loader = new MyURLClassLoader(); |
| | | } |
| | | |
| | | // Forcefully load all configuration definition classes in |
| | | // OpenDS.jar. |
| | | initializeCoreComponents(); |
| | | |
| | | // Put extensions jars into the class loader and load all |
| | | // configuration definition classes in that they contain. |
| | | // First load the extension from the install directory, then |
| | | // from the instance directory. |
| | | File libDir; |
| | | File installExtensionsPath; |
| | | File instanceExtensionsPath; |
| | | |
| | | // load install dir extension |
| | | libDir = new File(DirectoryServer.getServerRoot(), LIB_DIR); |
| | | try { |
| | | installExtensionsPath = new File(libDir, EXTENSIONS_DIR).getCanonicalFile(); |
| | | } catch (Exception e) { |
| | | installExtensionsPath = new File(libDir, EXTENSIONS_DIR); |
| | | } |
| | | initializeAllExtensions(installExtensionsPath); |
| | | |
| | | // load instance dir extension |
| | | libDir = new File(DirectoryServer.getInstanceRoot(), LIB_DIR); |
| | | try { |
| | | instanceExtensionsPath = new File(libDir, EXTENSIONS_DIR).getCanonicalFile(); |
| | | } catch (Exception e) { |
| | | instanceExtensionsPath = new File(libDir, EXTENSIONS_DIR); |
| | | } |
| | | if (!installExtensionsPath.getAbsolutePath().equals(instanceExtensionsPath.getAbsolutePath())) { |
| | | initializeAllExtensions(instanceExtensionsPath); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the class loader which should be used for loading classes and |
| | | * resources. When this class loader provider is disabled, the system |
| | | * default class loader will be returned by default. |
| | | * <p> |
| | | * Applications <b>MUST NOT</b> maintain persistent references to the class |
| | | * loader as it can change at run-time. |
| | | * |
| | | * @return Returns the class loader which should be used for loading classes |
| | | * and resources. |
| | | */ |
| | | public synchronized ClassLoader getClassLoader() { |
| | | if (loader != null) { |
| | | return loader; |
| | | } else { |
| | | return ClassLoader.getSystemClassLoader(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether this class loader provider is enabled. |
| | | * |
| | | * @return Returns <code>true</code> if this class loader provider is |
| | | * enabled. |
| | | */ |
| | | public synchronized boolean isEnabled() { |
| | | return loader != null; |
| | | } |
| | | |
| | | /** |
| | | * Add the named extensions to this class loader. |
| | | * |
| | | * @param extensions |
| | | * The names of the extensions to be loaded. |
| | | * @throws InitializationException |
| | | * If one of the extensions could not be loaded and initialized. |
| | | */ |
| | | private synchronized void addExtension(File... extensions) throws InitializationException { |
| | | // First add the Jar files to the class loader. |
| | | List<JarFile> jars = new LinkedList<JarFile>(); |
| | | for (File extension : extensions) { |
| | | if (jarFiles.contains(extension)) { |
| | | // Skip this file as it is already loaded. |
| | | continue; |
| | | } |
| | | |
| | | // Attempt to load it. |
| | | jars.add(loadJarFile(extension)); |
| | | |
| | | // Register the Jar file with the class loader. |
| | | try { |
| | | loader.addJarFile(extension); |
| | | } catch (Exception e) { |
| | | debugLogger.trace("Unable to register the jar file with the class loader", e); |
| | | LocalizableMessage message = |
| | | ERR_ADMIN_CANNOT_OPEN_JAR_FILE.get(extension.getName(), extension.getParent(), |
| | | stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD)); |
| | | throw new InitializationException(message); |
| | | } |
| | | jarFiles.add(extension); |
| | | } |
| | | |
| | | // Now forcefully load the configuration definition classes. |
| | | for (JarFile jar : jars) { |
| | | initializeExtension(jar); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Prints out all information about extensions. |
| | | * |
| | | * @return a String instance representing all information about extensions; |
| | | * <code>null</code> if there is no information available. |
| | | */ |
| | | public String printExtensionInformation() { |
| | | File extensionsPath = |
| | | new File(new StringBuilder(DirectoryServer.getServerRoot()).append(File.separator).append(LIB_DIR) |
| | | .append(File.separator).append(EXTENSIONS_DIR).toString()); |
| | | |
| | | if (!extensionsPath.exists() || !extensionsPath.isDirectory()) { |
| | | // no extensions' directory |
| | | return null; |
| | | } |
| | | |
| | | File[] extensions = extensionsPath.listFiles(new FileFilter() { |
| | | public boolean accept(File pathname) { |
| | | // only files with names ending with ".jar" |
| | | return pathname.isFile() && pathname.getName().endsWith(".jar"); |
| | | } |
| | | }); |
| | | |
| | | if (extensions.length == 0) { |
| | | return null; |
| | | } |
| | | |
| | | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| | | PrintStream ps = new PrintStream(baos); |
| | | // prints: |
| | | // -- |
| | | // Name Build number Revision number |
| | | ps.printf("--%s %-20s %-20s %-20s%s", EOL, "Name", "Build number", "Revision number", EOL); |
| | | |
| | | for (File extension : extensions) { |
| | | // retrieve MANIFEST entry and display name, build number and |
| | | // revision |
| | | // number |
| | | try { |
| | | JarFile jarFile = new JarFile(extension); |
| | | JarEntry entry = jarFile.getJarEntry("admin/" + EXTENSION_MANIFEST); |
| | | if (entry == null) { |
| | | continue; |
| | | } |
| | | |
| | | String[] information = getBuildInformation(jarFile); |
| | | |
| | | ps.append("Extension: "); |
| | | boolean addBlank = false; |
| | | for (String name : information) { |
| | | if (addBlank) { |
| | | ps.append(addBlank ? " " : ""); // add blank if not |
| | | // first append |
| | | } else { |
| | | addBlank = true; |
| | | } |
| | | |
| | | ps.printf("%-20s", name); |
| | | } |
| | | ps.append(EOL); |
| | | } catch (Exception e) { |
| | | // ignore extra information for this extension |
| | | } |
| | | } |
| | | |
| | | return baos.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Returns a String array with the following information : <br> |
| | | * index 0: the name of the extension. <br> |
| | | * index 1: the build number of the extension. <br> |
| | | * index 2: the revision number of the extension. |
| | | * |
| | | * @param extension |
| | | * the jar file of the extension |
| | | * @return a String array containing the name, the build number and the |
| | | * revision number of the extension given in argument |
| | | * @throws java.io.IOException |
| | | * thrown if the jar file has been closed. |
| | | */ |
| | | private String[] getBuildInformation(JarFile extension) throws IOException { |
| | | String[] result = new String[3]; |
| | | |
| | | // retrieve MANIFEST entry and display name, version and revision |
| | | Manifest manifest = extension.getManifest(); |
| | | |
| | | if (manifest != null) { |
| | | Attributes attributes = manifest.getMainAttributes(); |
| | | |
| | | int index = 0; |
| | | for (String name : BUILD_INFORMATION_ATTRIBUTE_NAMES) { |
| | | String value = attributes.getValue(name); |
| | | if (value == null) { |
| | | value = "<unknown>"; |
| | | } |
| | | result[index++] = value; |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * Put extensions jars into the class loader and load all configuration |
| | | * definition classes in that they contain. |
| | | * |
| | | * @param extensionsPath |
| | | * Indicates where extensions are located. |
| | | * @throws InitializationException |
| | | * If the extensions folder could not be accessed or if a |
| | | * extension jar file could not be accessed or if one of the |
| | | * configuration definition classes could not be initialized. |
| | | */ |
| | | private void initializeAllExtensions(File extensionsPath) throws InitializationException { |
| | | |
| | | try { |
| | | if (!extensionsPath.exists()) { |
| | | // The extensions directory does not exist. This is not a |
| | | // critical problem. |
| | | adminLogger.error(ERR_ADMIN_NO_EXTENSIONS_DIR, String.valueOf(extensionsPath)); |
| | | return; |
| | | } |
| | | |
| | | if (!extensionsPath.isDirectory()) { |
| | | // The extensions directory is not a directory. This is more |
| | | // critical. |
| | | LocalizableMessage message = |
| | | ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY.get(String.valueOf(extensionsPath)); |
| | | throw new InitializationException(message); |
| | | } |
| | | |
| | | // Get each extension file name. |
| | | FileFilter filter = new FileFilter() { |
| | | |
| | | /** |
| | | * Must be a Jar file. |
| | | */ |
| | | public boolean accept(File pathname) { |
| | | if (!pathname.isFile()) { |
| | | return false; |
| | | } |
| | | |
| | | String name = pathname.getName(); |
| | | return name.endsWith(".jar"); |
| | | } |
| | | |
| | | }; |
| | | |
| | | // Add and initialize the extensions. |
| | | addExtension(extensionsPath.listFiles(filter)); |
| | | } catch (InitializationException e) { |
| | | debugLogger.trace("Unable to initialize all extensions", e); |
| | | throw e; |
| | | } catch (Exception e) { |
| | | debugLogger.trace("Unable to initialize all extensions", e); |
| | | LocalizableMessage message = |
| | | ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES.get(String.valueOf(extensionsPath), |
| | | stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD)); |
| | | throw new InitializationException(message, e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Make sure all core configuration definitions are loaded. |
| | | * |
| | | * @throws InitializationException |
| | | * If the core manifest file could not be read or if one of the |
| | | * configuration definition classes could not be initialized. |
| | | */ |
| | | private void initializeCoreComponents() throws InitializationException { |
| | | InputStream is = RootCfgDefn.class.getResourceAsStream("/admin/" + CORE_MANIFEST); |
| | | |
| | | if (is == null) { |
| | | LocalizableMessage message = ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST.get(CORE_MANIFEST); |
| | | throw new InitializationException(message); |
| | | } |
| | | |
| | | try { |
| | | loadDefinitionClasses(is); |
| | | } catch (InitializationException e) { |
| | | debugLogger.trace("Unable to initialize core components", e); |
| | | LocalizableMessage message = |
| | | ERR_CLASS_LOADER_CANNOT_LOAD_CORE.get(CORE_MANIFEST, |
| | | stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD)); |
| | | throw new InitializationException(message); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Make sure all the configuration definition classes in a extension are |
| | | * loaded. |
| | | * |
| | | * @param jarFile |
| | | * The extension's Jar file. |
| | | * @throws InitializationException |
| | | * If the extension jar file could not be accessed or if one of |
| | | * the configuration definition classes could not be |
| | | * initialized. |
| | | */ |
| | | private void initializeExtension(JarFile jarFile) throws InitializationException { |
| | | JarEntry entry = jarFile.getJarEntry("admin/" + EXTENSION_MANIFEST); |
| | | if (entry != null) { |
| | | InputStream is; |
| | | try { |
| | | is = jarFile.getInputStream(entry); |
| | | } catch (Exception e) { |
| | | debugLogger.trace("Unable to get input stream from jar", e); |
| | | LocalizableMessage message = |
| | | ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST.get(EXTENSION_MANIFEST, jarFile.getName(), |
| | | stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD)); |
| | | throw new InitializationException(message); |
| | | } |
| | | |
| | | try { |
| | | loadDefinitionClasses(is); |
| | | } catch (InitializationException e) { |
| | | debugLogger.trace("Unable to load classes from input stream", e); |
| | | LocalizableMessage message = |
| | | ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION.get(jarFile.getName(), EXTENSION_MANIFEST, |
| | | stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD)); |
| | | throw new InitializationException(message); |
| | | } |
| | | try { |
| | | // Log build information of extensions in the error log |
| | | String[] information = getBuildInformation(jarFile); |
| | | LocalizableMessage message = |
| | | NOTE_LOG_EXTENSION_INFORMATION.get(jarFile.getName(), information[1], information[2]); |
| | | LocalizedLogger.getLocalizedLogger(message.resourceName()).error(message); |
| | | } catch (Exception e) { |
| | | // Do not log information for that extension |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Forcefully load configuration definition classes named in a manifest |
| | | * file. |
| | | * |
| | | * @param is |
| | | * The manifest file input stream. |
| | | * @throws InitializationException |
| | | * If the definition classes could not be loaded and |
| | | * initialized. |
| | | */ |
| | | private void loadDefinitionClasses(InputStream is) throws InitializationException { |
| | | BufferedReader reader = new BufferedReader(new InputStreamReader(is)); |
| | | List<AbstractManagedObjectDefinition<?, ?>> definitions = |
| | | new LinkedList<AbstractManagedObjectDefinition<?, ?>>(); |
| | | while (true) { |
| | | String className; |
| | | try { |
| | | className = reader.readLine(); |
| | | } catch (IOException e) { |
| | | LocalizableMessage msg = |
| | | ERR_CLASS_LOADER_CANNOT_READ_MANIFEST_FILE.get(String.valueOf(e.getMessage())); |
| | | throw new InitializationException(msg, e); |
| | | } |
| | | |
| | | // Break out when the end of the manifest is reached. |
| | | if (className == null) { |
| | | break; |
| | | } |
| | | |
| | | // Skip blank lines. |
| | | className = className.trim(); |
| | | if (className.length() == 0) { |
| | | continue; |
| | | } |
| | | |
| | | // Skip lines beginning with #. |
| | | if (className.startsWith("#")) { |
| | | continue; |
| | | } |
| | | |
| | | debugLogger.trace("Loading class " + className); |
| | | |
| | | // Load the class and get an instance of it if it is a definition. |
| | | Class<?> theClass; |
| | | try { |
| | | theClass = Class.forName(className, true, loader); |
| | | } catch (Exception e) { |
| | | LocalizableMessage msg = |
| | | ERR_CLASS_LOADER_CANNOT_LOAD_CLASS.get(className, String.valueOf(e.getMessage())); |
| | | throw new InitializationException(msg, e); |
| | | } |
| | | if (AbstractManagedObjectDefinition.class.isAssignableFrom(theClass)) { |
| | | // We need to instantiate it using its getInstance() static |
| | | // method. |
| | | Method method; |
| | | try { |
| | | method = theClass.getMethod("getInstance"); |
| | | } catch (Exception e) { |
| | | LocalizableMessage msg = |
| | | ERR_CLASS_LOADER_CANNOT_FIND_GET_INSTANCE_METHOD.get(className, |
| | | String.valueOf(e.getMessage())); |
| | | throw new InitializationException(msg, e); |
| | | } |
| | | |
| | | // Get the definition instance. |
| | | AbstractManagedObjectDefinition<?, ?> d; |
| | | try { |
| | | d = (AbstractManagedObjectDefinition<?, ?>) method.invoke(null); |
| | | } catch (Exception e) { |
| | | LocalizableMessage msg = |
| | | ERR_CLASS_LOADER_CANNOT_INVOKE_GET_INSTANCE_METHOD.get(className, |
| | | String.valueOf(e.getMessage())); |
| | | throw new InitializationException(msg, e); |
| | | } |
| | | definitions.add(d); |
| | | } |
| | | } |
| | | |
| | | // Initialize any definitions that were loaded. |
| | | for (AbstractManagedObjectDefinition<?, ?> d : definitions) { |
| | | try { |
| | | d.initialize(); |
| | | } catch (Exception e) { |
| | | LocalizableMessage msg = |
| | | ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN.get(d.getName(), d.getClass().getName(), |
| | | String.valueOf(e.getMessage())); |
| | | throw new InitializationException(msg, e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Load the named Jar file. |
| | | * |
| | | * @param jar |
| | | * The name of the Jar file to load. |
| | | * @return Returns the loaded Jar file. |
| | | * @throws InitializationException |
| | | * If the Jar file could not be loaded. |
| | | */ |
| | | private JarFile loadJarFile(File jar) throws InitializationException { |
| | | JarFile jarFile; |
| | | |
| | | try { |
| | | // Load the extension jar file. |
| | | jarFile = new JarFile(jar); |
| | | } catch (Exception e) { |
| | | debugLogger.trace("Unable to load jar file: " + jar, e); |
| | | |
| | | LocalizableMessage message = |
| | | ERR_ADMIN_CANNOT_OPEN_JAR_FILE.get(jar.getName(), jar.getParent(), |
| | | stackTraceToSingleLineString(e, DynamicConstants.DEBUG_BUILD)); |
| | | throw new InitializationException(message); |
| | | } |
| | | return jarFile; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2013 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.EnumSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Class property definition. |
| | | * <p> |
| | | * A class property definition defines a property whose values represent a Java |
| | | * class. It is possible to restrict the type of java class by specifying |
| | | * "instance of" constraints. |
| | | * <p> |
| | | * Note that in a client/server environment, the client is probably not capable |
| | | * of validating the Java class (e.g. it will not be able to load it nor have |
| | | * access to the interfaces it is supposed to implement). For this reason, it is |
| | | * possible to switch off validation in the client by using the appropriate |
| | | * {@link PropertyDefinitionsOptions}. |
| | | */ |
| | | public final class ClassPropertyDefinition extends PropertyDefinition<String> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing class property definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<String, ClassPropertyDefinition> { |
| | | |
| | | // List of interfaces which property values must implement. |
| | | private List<String> instanceOfInterfaces; |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | |
| | | this.instanceOfInterfaces = new LinkedList<String>(); |
| | | } |
| | | |
| | | /** |
| | | * Add an class name which property values must implement. |
| | | * |
| | | * @param className |
| | | * The name of a class which property values must implement. |
| | | */ |
| | | public final void addInstanceOf(String className) { |
| | | Reject.ifNull(className); |
| | | |
| | | /* |
| | | * Do some basic checks to make sure the string representation is |
| | | * valid. |
| | | */ |
| | | String value = className.trim(); |
| | | if (!value.matches(CLASS_RE)) { |
| | | throw new IllegalArgumentException("\"" + value + "\" is not a valid Java class name"); |
| | | } |
| | | |
| | | instanceOfInterfaces.add(value); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected ClassPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<String> defaultBehavior) { |
| | | return new ClassPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, |
| | | instanceOfInterfaces); |
| | | } |
| | | |
| | | } |
| | | |
| | | // Regular expression for validating class names. |
| | | private static final String CLASS_RE = "^([A-Za-z][A-Za-z0-9_]*\\.)*[A-Za-z][A-Za-z0-9_]*(\\$[A-Za-z0-9_]+)*$"; |
| | | |
| | | /** |
| | | * Create a class property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new class property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Load a named class. |
| | | private static Class<?> loadClass(String className, boolean initialize) throws ClassNotFoundException { |
| | | return Class.forName(className, initialize, ClassLoaderProvider.getInstance().getClassLoader()); |
| | | } |
| | | |
| | | // List of interfaces which property values must implement. |
| | | private final List<String> instanceOfInterfaces; |
| | | |
| | | // Private constructor. |
| | | private ClassPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<String> defaultBehavior, List<String> instanceOfInterfaces) { |
| | | super(d, String.class, propertyName, options, adminAction, defaultBehavior); |
| | | |
| | | this.instanceOfInterfaces = Collections.unmodifiableList(new LinkedList<String>(instanceOfInterfaces)); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitClass(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) { |
| | | return v.visitClass(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | try { |
| | | validateValue(value, options); |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value, e.getCause()); |
| | | } |
| | | |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * Get an unmodifiable list of classes which values of this property must |
| | | * implement. |
| | | * |
| | | * @return Returns an unmodifiable list of classes which values of this |
| | | * property must implement. |
| | | */ |
| | | public List<String> getInstanceOfInterface() { |
| | | return instanceOfInterfaces; |
| | | } |
| | | |
| | | /** |
| | | * Validate and load the named class, and cast it to a subclass of the |
| | | * specified class. |
| | | * |
| | | * @param <T> |
| | | * The requested type. |
| | | * @param className |
| | | * The name of the class to validate and load. |
| | | * @param instanceOf |
| | | * The class representing the requested type. |
| | | * @return Returns the named class cast to a subclass of the specified |
| | | * class. |
| | | * @throws IllegalPropertyValueException |
| | | * If the named class was invalid, could not be loaded, or did |
| | | * not implement the required interfaces. |
| | | * @throws ClassCastException |
| | | * If the referenced class does not implement the requested |
| | | * type. |
| | | */ |
| | | public <T> Class<? extends T> loadClass(String className, Class<T> instanceOf) { |
| | | Reject.ifNull(className, instanceOf); |
| | | |
| | | // Make sure that the named class is valid. |
| | | validateClassName(className); |
| | | Class<?> theClass = validateClassInterfaces(className, true); |
| | | |
| | | // Cast it to the required type. |
| | | return theClass.asSubclass(instanceOf); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String normalizeValue(String value) { |
| | | Reject.ifNull(value); |
| | | |
| | | return value.trim(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // Always make sure the name is a valid class name. |
| | | validateClassName(value); |
| | | |
| | | /* |
| | | * If additional validation is enabled then attempt to load the class |
| | | * and check the interfaces that it implements/extends. |
| | | */ |
| | | if (options.allowClassValidation()) { |
| | | validateClassInterfaces(value, false); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * Do some basic checks to make sure the string representation is valid. |
| | | */ |
| | | private void validateClassName(String className) { |
| | | String nvalue = className.trim(); |
| | | if (!nvalue.matches(CLASS_RE)) { |
| | | throw new IllegalPropertyValueException(this, className); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | * Make sure that named class implements the interfaces named by this |
| | | * definition. |
| | | */ |
| | | private Class<?> validateClassInterfaces(String className, boolean initialize) { |
| | | Class<?> theClass = loadClassForValidation(className, className, initialize); |
| | | for (String i : instanceOfInterfaces) { |
| | | Class<?> instanceOfClass = loadClassForValidation(className, i, initialize); |
| | | if (!instanceOfClass.isAssignableFrom(theClass)) { |
| | | throw new IllegalPropertyValueException(this, className); |
| | | } |
| | | } |
| | | return theClass; |
| | | } |
| | | |
| | | private Class<?> loadClassForValidation(String componentClassName, String classToBeLoaded, boolean initialize) { |
| | | try { |
| | | return loadClass(classToBeLoaded.trim(), initialize); |
| | | } catch (ClassNotFoundException e) { |
| | | // If the class cannot be loaded then it is an invalid value. |
| | | throw new IllegalPropertyValueException(this, componentClassName, e); |
| | | } catch (LinkageError e) { |
| | | // If the class cannot be initialized then it is an invalid value. |
| | | throw new IllegalPropertyValueException(this, componentClassName, 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2007-2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.opendj.ldap.DN; |
| | | |
| | | /** |
| | | * A common base interface for all server managed object configurations. |
| | | */ |
| | | public interface Configuration { |
| | | |
| | | /** |
| | | * Gets the DN of the LDAP entry associated with this configuration. |
| | | * |
| | | * @return Returns the DN of the LDAP entry associated with this |
| | | * configuration. |
| | | */ |
| | | DN dn(); |
| | | |
| | | /** |
| | | * Gets the configuration class associated with this configuration. |
| | | * |
| | | * @return Returns the configuration class associated with this |
| | | * configuration. |
| | | */ |
| | | Class<? extends Configuration> configurationClass(); |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.opendj.config.client.ConcurrentModificationException; |
| | | import org.forgerock.opendj.config.client.MissingMandatoryPropertiesException; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | |
| | | /** |
| | | * A common base interface for all managed object configuration clients. |
| | | */ |
| | | public interface ConfigurationClient { |
| | | |
| | | /** |
| | | * Get the configuration definition associated with this configuration. |
| | | * |
| | | * @return Returns the configuration definition associated with this |
| | | * configuration. |
| | | */ |
| | | ManagedObjectDefinition<? extends ConfigurationClient, ? extends Configuration> definition(); |
| | | |
| | | /** |
| | | * Get a property provider view of this configuration. |
| | | * |
| | | * @return Returns a property provider view of this configuration. |
| | | */ |
| | | PropertyProvider properties(); |
| | | |
| | | /** |
| | | * If this is a new configuration this method will attempt to add it to the |
| | | * server, otherwise it will commit any changes made to this configuration. |
| | | * |
| | | * @throws ManagedObjectAlreadyExistsException |
| | | * If this is a new configuration but it could not be added to |
| | | * the server because it already exists. |
| | | * @throws MissingMandatoryPropertiesException |
| | | * If this configuration contains some mandatory properties |
| | | * which have been left undefined. |
| | | * @throws ConcurrentModificationException |
| | | * If this is a new configuration which is being added to the |
| | | * server but its parent has been removed by another client, or |
| | | * if this configuration is being modified but it has been |
| | | * removed from the server by another client. |
| | | * @throws OperationRejectedException |
| | | * If the server refuses to add or modify this configuration due |
| | | * to some server-side constraint which cannot be satisfied. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | void commit() throws ManagedObjectAlreadyExistsException, MissingMandatoryPropertiesException, |
| | | ConcurrentModificationException, OperationRejectedException, ErrorResultException; |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.forgerock.opendj.config.client.ClientConstraintHandler; |
| | | import org.forgerock.opendj.config.server.ServerConstraintHandler; |
| | | |
| | | /** |
| | | * An interface for enforcing constraints and dependencies between managed |
| | | * objects and their properties. Constraints express relationships between |
| | | * managed objects and their properties, for example: |
| | | * <ul> |
| | | * <li>referential integrity: where one managed object references another a |
| | | * constraint can enforce referential integrity. The constraint can prevent |
| | | * creation of references to non-existent managed objects, and also prevent |
| | | * deletion of referenced managed objects |
| | | * <li>property dependencies: for example, when a boolean property is |
| | | * <code>true</code>, one or more additional properties must be specified. This |
| | | * is useful for features like SSL, which when enabled, requires that various |
| | | * SSL related configuration options are specified |
| | | * <li>property constraints: for example, when an upper limit property must not |
| | | * have a value which is less than the lower limit property. |
| | | * </ul> |
| | | * On the client-side constraints are enforced immediately before a write |
| | | * operation is performed. That is to say, immediately before a new managed |
| | | * object is created, changes to a managed object are applied, or an existing |
| | | * managed object is deleted. |
| | | */ |
| | | public abstract class Constraint { |
| | | |
| | | /** |
| | | * Creates a new constraint. |
| | | */ |
| | | protected Constraint() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Gets the client-side constraint handlers which will be used to enforce |
| | | * this constraint in client applications. The default implementation is to |
| | | * return an empty set of client constraint handlers. |
| | | * |
| | | * @return Returns the client-side constraint handlers which will be used to |
| | | * enforce this constraint in client applications. The returned |
| | | * collection must not be <code>null</code> but maybe empty |
| | | * (indicating that the constraint can only be enforced on the |
| | | * server-side). |
| | | */ |
| | | public Collection<ClientConstraintHandler> getClientConstraintHandlers() { |
| | | return Collections.emptySet(); |
| | | } |
| | | |
| | | /** |
| | | * Gets the server-side constraint handlers which will be used to enforce |
| | | * this constraint within the server. The default implementation is to |
| | | * return an empty set of server constraint handlers. |
| | | * |
| | | * @return Returns the server-side constraint handlers which will be used to |
| | | * enforce this constraint within the server. The returned |
| | | * collection must not be <code>null</code> and must not be empty, |
| | | * since constraints must always be enforced on the server. |
| | | */ |
| | | public Collection<ServerConstraintHandler> getServerConstraintHandlers() { |
| | | return Collections.emptySet(); |
| | | } |
| | | |
| | | /** |
| | | * Initializes this constraint. The default implementation is to do nothing. |
| | | * |
| | | * @throws Exception |
| | | * If this constraint could not be initialized. |
| | | */ |
| | | protected void initialize() throws Exception { |
| | | // Default implementation is to do nothing. |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | |
| | | import org.forgerock.opendj.ldap.DN; |
| | | |
| | | /** |
| | | * DN property definition. |
| | | */ |
| | | public final class DNPropertyDefinition extends PropertyDefinition<DN> { |
| | | |
| | | // Optional base DN which all valid values must be immediately |
| | | // subordinate to. |
| | | private final DN baseDN; |
| | | |
| | | /** |
| | | * An interface for incrementally constructing DN property definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<DN, DNPropertyDefinition> { |
| | | |
| | | // Optional base DN which all valid values must be immediately |
| | | // subordinate to. |
| | | private DN baseDN = null; |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * Set the base DN which all valid values must be immediately |
| | | * subordinate to. By default there is no based DN. |
| | | * |
| | | * @param baseDN |
| | | * The string representation of the base DN. |
| | | * @throws IllegalArgumentException |
| | | * If the provided string is not a valid DN string |
| | | * representation. |
| | | */ |
| | | public void setBaseDN(String baseDN) { |
| | | if (baseDN == null) { |
| | | setBaseDN((DN) null); |
| | | } else { |
| | | // TODO: is it correct to replace server DN.decode by SDK |
| | | // valueOf ? |
| | | setBaseDN(DN.valueOf(baseDN)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Set the base DN which all valid values must be immediately |
| | | * subordinate to. By default there is no based DN. |
| | | * |
| | | * @param baseDN |
| | | * The base DN. |
| | | */ |
| | | public void setBaseDN(DN baseDN) { |
| | | this.baseDN = baseDN; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected DNPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<DN> defaultBehavior) { |
| | | return new DNPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, baseDN); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Create a DN property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new boolean property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private DNPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<DN> defaultBehavior, DN baseDN) { |
| | | super(d, DN.class, propertyName, options, adminAction, defaultBehavior); |
| | | this.baseDN = baseDN; |
| | | } |
| | | |
| | | /** |
| | | * Get the base DN which all valid values must be immediately subordinate |
| | | * to, or <code>null</code> if there is no based DN. |
| | | * |
| | | * @return Returns the base DN which all valid values must be immediately |
| | | * subordinate to. |
| | | */ |
| | | public DN getBaseDN() { |
| | | return baseDN; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(DN value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | if (baseDN != null) { |
| | | DN parent = value.parent(); |
| | | |
| | | if (parent == null) { |
| | | parent = DN.rootDN(); |
| | | } |
| | | |
| | | if (!parent.equals(baseDN)) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public DN decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | try { |
| | | DN dn = DN.valueOf(value); |
| | | validateValue(dn, options); |
| | | return dn; |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitDN(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, DN value, P p) { |
| | | return v.visitDN(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(DN o1, DN o2) { |
| | | return o1.compareTo(o2); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * The requested managed object was found but it could not be decoded. |
| | | */ |
| | | public abstract class DecodingException extends OperationsException { |
| | | |
| | | /** |
| | | * Fake serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * Create a decoding exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | protected DecodingException(LocalizableMessage message) { |
| | | super(message); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * This exception is thrown when a property's default values cannot be |
| | | * determined. This can occur in the following situations: |
| | | * <ul> |
| | | * <li>the property has a well-defined set of default values but they are |
| | | * invalid according to the property's syntax |
| | | * <li>the property inherits its default values from another managed object but |
| | | * they could not be retrieved, perhaps because of a communication problem. |
| | | * </ul> |
| | | */ |
| | | public class DefaultBehaviorException extends PropertyException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = -2542117466747573053L; |
| | | |
| | | /** |
| | | * Create a new default behavior exception with a cause. |
| | | * |
| | | * @param pd |
| | | * The property definition whose default values could not be |
| | | * determined. |
| | | * @param cause |
| | | * The exception that prevented the default values from being |
| | | * determined. |
| | | */ |
| | | public DefaultBehaviorException(PropertyDefinition<?> pd, Throwable cause) { |
| | | super(pd, ERR_DEFAULT_BEHAVIOR_PROPERTY_EXCEPTION.get(pd.getName()), cause); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * An interface for determining the default behavior of a property. A property |
| | | * exhibits default behavior when it has no values defined. There are four |
| | | * different types of default behavior: |
| | | * <ol> |
| | | * <li>there is no default behavior - e.g. leaving a "description" unset has no |
| | | * side-effects. This default behavior is represented using the |
| | | * {@link UndefinedDefaultBehaviorProvider} implementation |
| | | * <li>the property defaults to one or more real values of the property. This |
| | | * default behavior is represented using the |
| | | * {@link DefinedDefaultBehaviorProvider} implementation |
| | | * <li>the property defaults to some special behavior that cannot be represented |
| | | * using real property values. This default behavior is represented using the |
| | | * {@link AliasDefaultBehaviorProvider} implementation |
| | | * <li>the property inherits its values from property held in another managed |
| | | * object (e.g. the parent managed object). This default behavior is represented |
| | | * using the {@link AbsoluteInheritedDefaultBehaviorProvider} and |
| | | * {@link RelativeInheritedDefaultBehaviorProvider} implementations. |
| | | * </ol> |
| | | * An application can perform actions based on the type of the default behavior |
| | | * by implementing the {@link DefaultBehaviorProviderVisitor} interface. |
| | | * |
| | | * @param <T> |
| | | * The type of values represented by this provider. |
| | | */ |
| | | public abstract class DefaultBehaviorProvider<T> { |
| | | |
| | | /** |
| | | * Creates a new default behavior provider. |
| | | */ |
| | | protected DefaultBehaviorProvider() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Apply a visitor to this default behavior provider. |
| | | * |
| | | * @param <R> |
| | | * The return type of the visitor's methods. |
| | | * @param <P> |
| | | * The type of the additional parameters to the visitor's |
| | | * methods. |
| | | * @param v |
| | | * The default behavior visitor. |
| | | * @param p |
| | | * Optional additional visitor parameter. |
| | | * @return Returns a result as specified by the visitor. |
| | | */ |
| | | public abstract <R, P> R accept(DefaultBehaviorProviderVisitor<T, R, P> v, P p); |
| | | |
| | | /** |
| | | * Performs any run-time initialization required by this default behavior |
| | | * provider. This may include resolving managed object paths and property |
| | | * names. |
| | | * <p> |
| | | * The default implementation is to do nothing. |
| | | * |
| | | * @throws Exception |
| | | * If this default behavior provider could not be initialized. |
| | | */ |
| | | protected void initialize() throws Exception { |
| | | // Default implementation is to do nothing. |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A visitor of default behavior providers, in the style of the visitor design |
| | | * pattern. Classes implementing this interface can query default behavior |
| | | * providers in a type-safe manner when the kind of default behavior provider is |
| | | * unknown at compile time. When a visitor is passed to a default behavior |
| | | * provider's accept method, the corresponding visit method most applicable to |
| | | * that default behavior provider is invoked. |
| | | * |
| | | * @param <T> |
| | | * The type of values represented by the default value provider. |
| | | * @param <R> |
| | | * The return type of this visitor's methods. Use |
| | | * {@link java.lang.Void} for visitors that do not need to return |
| | | * results. |
| | | * @param <P> |
| | | * The type of the additional parameter to this visitor's methods. |
| | | * Use {@link java.lang.Void} for visitors that do not need an |
| | | * additional parameter. |
| | | */ |
| | | public interface DefaultBehaviorProviderVisitor<T, R, P> { |
| | | |
| | | /** |
| | | * Visit an absolute inherited default behavior provider. |
| | | * |
| | | * @param d |
| | | * The absolute inherited default behavior provider to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | R visitAbsoluteInherited(AbsoluteInheritedDefaultBehaviorProvider<T> d, P p); |
| | | |
| | | /** |
| | | * Visit an alias default behavior provider. |
| | | * |
| | | * @param d |
| | | * The alias default behavior provider to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | R visitAlias(AliasDefaultBehaviorProvider<T> d, P p); |
| | | |
| | | /** |
| | | * Visit an defined default behavior provider. |
| | | * |
| | | * @param d |
| | | * The defined default behavior provider to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | R visitDefined(DefinedDefaultBehaviorProvider<T> d, P p); |
| | | |
| | | /** |
| | | * Visit a relative inherited default behavior provider. |
| | | * |
| | | * @param d |
| | | * The relative inherited default behavior provider to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | R visitRelativeInherited(RelativeInheritedDefaultBehaviorProvider<T> d, P p); |
| | | |
| | | /** |
| | | * Visit an undefined default behavior provider. |
| | | * |
| | | * @param d |
| | | * The undefined default behavior provider to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | R visitUndefined(UndefinedDefaultBehaviorProvider<T> d, P p); |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | /** |
| | | * A default managed object which should be created when a parent managed object |
| | | * is created. Default managed objects are associated with a |
| | | * {@link RelationDefinition}. |
| | | * |
| | | * @param <C> |
| | | * The type of client default managed object configuration. |
| | | * @param <S> |
| | | * The type of server default managed object configuration. |
| | | */ |
| | | public final class DefaultManagedObject<C extends ConfigurationClient, S extends Configuration> implements |
| | | PropertyProvider { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing default managed objects. |
| | | * |
| | | * @param <C> |
| | | * The type of client default managed object configuration. |
| | | * @param <S> |
| | | * The type of server default managed object configuration. |
| | | */ |
| | | public static final class Builder<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | // The default managed object's definition. |
| | | private final ManagedObjectDefinition<C, S> definition; |
| | | |
| | | // The string encoded default managed object's properties. |
| | | private final Map<String, List<String>> propertyStringValues = new HashMap<String, List<String>>(); |
| | | |
| | | /** |
| | | * Creates a new default managed object builder. |
| | | * |
| | | * @param definition |
| | | * The default managed object's definition. |
| | | */ |
| | | public Builder(ManagedObjectDefinition<C, S> definition) { |
| | | this.definition = definition; |
| | | } |
| | | |
| | | /** |
| | | * Construct a default managed object based on the properties of this |
| | | * builder. |
| | | * |
| | | * @return Returns the new default managed object. |
| | | */ |
| | | public DefaultManagedObject<C, S> getInstance() { |
| | | return new DefaultManagedObject<C, S>(definition, propertyStringValues); |
| | | } |
| | | |
| | | /** |
| | | * Defines a property's values for the default managed object. |
| | | * |
| | | * @param name |
| | | * The name of the property. |
| | | * @param values |
| | | * One or more property values in the string representation. |
| | | */ |
| | | public void setPropertyValues(String name, String... values) { |
| | | if (values == null || values.length == 0) { |
| | | throw new IllegalArgumentException("null or empty values specified for property " + name); |
| | | } |
| | | |
| | | propertyStringValues.put(name, Arrays.asList(values)); |
| | | } |
| | | } |
| | | |
| | | // The default managed object's definition. |
| | | private final ManagedObjectDefinition<C, S> definition; |
| | | |
| | | // The string encoded default managed object's properties. |
| | | private final Map<String, List<String>> propertyStringValues; |
| | | |
| | | // Private constructor. |
| | | private DefaultManagedObject(ManagedObjectDefinition<C, S> definition, |
| | | Map<String, List<String>> propertyStringValues) { |
| | | this.definition = definition; |
| | | this.propertyStringValues = propertyStringValues; |
| | | } |
| | | |
| | | /** |
| | | * Gets the managed object definition associated with this default managed |
| | | * object. |
| | | * |
| | | * @return Returns the managed object definition associated with this |
| | | * default managed object. |
| | | */ |
| | | public ManagedObjectDefinition<C, S> getManagedObjectDefinition() { |
| | | return definition; |
| | | } |
| | | |
| | | /** |
| | | * Gets a mutable copy of the set of property values for the specified |
| | | * property. |
| | | * |
| | | * @param <T> |
| | | * The type of the property to be retrieved. |
| | | * @param pd |
| | | * The property to be retrieved. |
| | | * @return Returns a newly allocated set containing a copy of the property's |
| | | * values. An empty set indicates that the property has no values |
| | | * defined and any default behavior is applicable. |
| | | * @throws IllegalArgumentException |
| | | * If the property definition is not associated with this |
| | | * managed object's definition. |
| | | */ |
| | | public <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> pd) { |
| | | // Validate the property definition. |
| | | definition.getPropertyDefinition(pd.getName()); |
| | | |
| | | // Do a defensive copy. |
| | | SortedSet<T> values = new TreeSet<T>(pd); |
| | | List<String> stringValues = propertyStringValues.get(pd.getName()); |
| | | if (stringValues != null) { |
| | | for (String stringValue : stringValues) { |
| | | // TODO : is it correct to have no validation ? |
| | | values.add(pd.decodeValue(stringValue, PropertyDefinitionsOptions.NO_VALIDATION_OPTIONS)); |
| | | } |
| | | } |
| | | return values; |
| | | } |
| | | |
| | | /** |
| | | * Performs run-time initialization of properties. |
| | | * |
| | | * @throws Exception |
| | | * If this default managed object could not be initialized. |
| | | */ |
| | | void initialize() throws Exception { |
| | | // FIXME: it would be nice if we could decode all property values |
| | | // at this point. However this is not possible on the server side |
| | | // since some properties will be determined to be invalid since |
| | | // the schema is not loaded. |
| | | |
| | | // Validate provided property names. |
| | | for (String name : propertyStringValues.keySet()) { |
| | | definition.getPropertyDefinition(name); |
| | | } |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Collection; |
| | | |
| | | /** |
| | | * A default behavior provider which represents a well-defined set of default |
| | | * values. It should be used by properties which have default value(s) which are |
| | | * valid value(s) according to the constraints of the property's definition. |
| | | * |
| | | * @param <T> |
| | | * The type of values represented by this provider. |
| | | */ |
| | | public final class DefinedDefaultBehaviorProvider<T> extends DefaultBehaviorProvider<T> { |
| | | |
| | | // The collection of default values. |
| | | private final Collection<String> values; |
| | | |
| | | /** |
| | | * Create a new defined default behavior provider associated with the |
| | | * specified list of values. |
| | | * |
| | | * @param values |
| | | * The list of values (must be non-<code>null</code> and not |
| | | * empty) in their string representation. |
| | | * @throws IllegalArgumentException |
| | | * If the list of values was <code>null</code> or empty. |
| | | */ |
| | | public DefinedDefaultBehaviorProvider(String... values) { |
| | | if (values == null || values.length == 0) { |
| | | throw new IllegalArgumentException("Null or empty list of default values"); |
| | | } |
| | | this.values = Arrays.asList(values); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <R, P> R accept(DefaultBehaviorProviderVisitor<T, R, P> v, P p) { |
| | | return v.visitDefined(this, p); |
| | | } |
| | | |
| | | /** |
| | | * Get a copy of the default values. |
| | | * |
| | | * @return Returns a newly allocated collection containing a copy of the |
| | | * default values. |
| | | */ |
| | | public Collection<String> getDefaultValues() { |
| | | return new ArrayList<String>(values); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * The requested managed object was found but its type could not be determined. |
| | | */ |
| | | public class DefinitionDecodingException extends DecodingException { |
| | | |
| | | /** |
| | | * An enumeration defining the reasons why the definition could not be |
| | | * resolved. |
| | | */ |
| | | public static enum Reason { |
| | | /** |
| | | * The managed object could be found but its type resolved to an |
| | | * abstract managed object definition. |
| | | */ |
| | | ABSTRACT_TYPE_INFORMATION(), |
| | | |
| | | /** |
| | | * The managed object could be found but did not contain any type |
| | | * information (eg missing object classes in LDAP). |
| | | */ |
| | | NO_TYPE_INFORMATION(), |
| | | |
| | | /** |
| | | * The managed object could be found but did not contain the expected |
| | | * type information (eg incorrect object classes in LDAP). |
| | | */ |
| | | WRONG_TYPE_INFORMATION(); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Version ID required by serializable classes. |
| | | */ |
| | | private static final long serialVersionUID = 3459033551415663416L; |
| | | |
| | | // Create the message. |
| | | private static LocalizableMessage createLocalizableMessage(AbstractManagedObjectDefinition<?, ?> d, Reason reason) { |
| | | LocalizableMessage ufn = d.getUserFriendlyName(); |
| | | switch (reason) { |
| | | case NO_TYPE_INFORMATION: |
| | | return ERR_DECODING_EXCEPTION_NO_TYPE_INFO.get(ufn); |
| | | case WRONG_TYPE_INFORMATION: |
| | | return ERR_DECODING_EXCEPTION_WRONG_TYPE_INFO.get(ufn); |
| | | default: |
| | | return ERR_DECODING_EXCEPTION_ABSTRACT_TYPE_INFO.get(ufn); |
| | | } |
| | | } |
| | | |
| | | // The expected type of managed object. |
| | | private final AbstractManagedObjectDefinition<?, ?> d; |
| | | |
| | | // The reason why the definition could not be determined. |
| | | private final Reason reason; |
| | | |
| | | /** |
| | | * Create a new definition decoding exception. |
| | | * |
| | | * @param d |
| | | * The expected type of managed object. |
| | | * @param reason |
| | | * The reason why the definition could not be determined. |
| | | */ |
| | | public DefinitionDecodingException(AbstractManagedObjectDefinition<?, ?> d, Reason reason) { |
| | | super(createLocalizableMessage(d, reason)); |
| | | this.d = d; |
| | | this.reason = reason; |
| | | } |
| | | |
| | | /** |
| | | * Gets the expected managed object definition. |
| | | * |
| | | * @return Returns the expected managed object definition. |
| | | */ |
| | | public AbstractManagedObjectDefinition<?, ?> getManagedObjectDefinition() { |
| | | return d; |
| | | } |
| | | |
| | | /** |
| | | * Gets the reason why the definition could not be determined. |
| | | * |
| | | * @return Returns the reason why the definition could not be determined. |
| | | */ |
| | | public Reason getReason() { |
| | | return reason; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * This interface is used to determine the "best match" managed object |
| | | * definition in a definition hierarchy. |
| | | * <p> |
| | | * Managed object definitions, like Java classes, are arranged in an inheritance |
| | | * hierarchy. When managed objects are decoded (e.g. from LDAP entries), the |
| | | * driver implementation is provided with an |
| | | * "expected managed object definition". However, the actual decoded managed |
| | | * object is often an instance of a sub-type of this definition. For example, |
| | | * when decoding a connection handler managed object, the actual type can never |
| | | * be a connection handler because it is an abstract managed object type. |
| | | * Instead, the decoded managed object must be a "concrete" sub-type: an LDAP |
| | | * connection handler or JMX connection handler. |
| | | * <p> |
| | | * This resolution process is coordinated by the |
| | | * <code>resolveManagedObjectDefinition</code> method in managed object |
| | | * definitions, where it is passed a <code>DefinitionResolver</code> |
| | | * implementation. The <code>resolveManagedObjectDefinition</code> method takes |
| | | * care of recursively descending through the definition hierarchy and invokes |
| | | * the {@link #matches(AbstractManagedObjectDefinition)} method against each |
| | | * potential sub-type. It is the job of the resolver to indicate whether the |
| | | * provided managed object definition is a candidate definition. For example, |
| | | * the LDAP driver provides a definition resolver which uses the decoded LDAP |
| | | * entry's object classes to determine the final appropriate managed object |
| | | * definition. |
| | | */ |
| | | public interface DefinitionResolver { |
| | | |
| | | /** |
| | | * Determines whether or not the provided managed object definition matches |
| | | * this resolver's criteria. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @return Returns <code>true</code> if the the provided managed object |
| | | * definition matches this resolver's criteria. |
| | | */ |
| | | boolean matches(AbstractManagedObjectDefinition<?, ?> d); |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | |
| | | /** |
| | | * Duration property definition. |
| | | * <p> |
| | | * A duration property definition comprises of: |
| | | * <ul> |
| | | * <li>a <i>base unit</i> - specifies the minimum granularity which can be used |
| | | * to specify duration property values. For example, if the base unit is in |
| | | * seconds then values represented in milliseconds will not be permitted. The |
| | | * default base unit is seconds |
| | | * <li>an optional <i>maximum unit</i> - specifies the biggest duration unit |
| | | * which can be used to specify duration property values. Values presented in |
| | | * units greater than this unit will not be permitted. There is no default |
| | | * maximum unit |
| | | * <li><i>lower limit</i> - specifies the smallest duration permitted by the |
| | | * property. The default lower limit is 0 and can never be less than 0 |
| | | * <li>an optional <i>upper limit</i> - specifies the biggest duration permitted |
| | | * by the property. By default, there is no upper limit |
| | | * <li>support for <i>unlimited</i> durations - when permitted users can specify |
| | | * "unlimited" durations. These are represented using the decoded value, -1, or |
| | | * the encoded string value "unlimited". By default, unlimited durations are not |
| | | * permitted. In addition, it is not possible to define an upper limit and |
| | | * support unlimited values. |
| | | * </ul> |
| | | * Decoded values are represented using <code>long</code> values in the base |
| | | * unit defined for the duration property definition. |
| | | */ |
| | | public final class DurationPropertyDefinition extends PropertyDefinition<Long> { |
| | | |
| | | // String used to represent unlimited durations. |
| | | private static final String UNLIMITED = "unlimited"; |
| | | |
| | | // The base unit for this property definition. |
| | | private final DurationUnit baseUnit; |
| | | |
| | | // The optional maximum unit for this property definition. |
| | | private final DurationUnit maximumUnit; |
| | | |
| | | // The lower limit of the property value in milli-seconds. |
| | | private final long lowerLimit; |
| | | |
| | | // The optional upper limit of the property value in milli-seconds. |
| | | private final Long upperLimit; |
| | | |
| | | // Indicates whether this property allows the use of the "unlimited" |
| | | // duration value (represented using a -1L or the string |
| | | // "unlimited"). |
| | | private final boolean allowUnlimited; |
| | | |
| | | /** |
| | | * An interface for incrementally constructing duration property |
| | | * definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<Long, DurationPropertyDefinition> { |
| | | |
| | | // The base unit for this property definition. |
| | | private DurationUnit baseUnit = DurationUnit.SECONDS; |
| | | |
| | | // The optional maximum unit for this property definition. |
| | | private DurationUnit maximumUnit = null; |
| | | |
| | | // The lower limit of the property value in milli-seconds. |
| | | private long lowerLimit = 0L; |
| | | |
| | | // The optional upper limit of the property value in |
| | | // milli-seconds. |
| | | private Long upperLimit = null; |
| | | |
| | | // Indicates whether this property allows the use of the |
| | | // "unlimited" duration value (represented using a -1L or the |
| | | // string "unlimited"). |
| | | private boolean allowUnlimited = false; |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * Set the base unit for this property definition (values including |
| | | * limits are specified in this unit). By default a duration property |
| | | * definition uses seconds. |
| | | * |
| | | * @param unit |
| | | * The string representation of the base unit (must not be |
| | | * <code>null</code>). |
| | | * @throws IllegalArgumentException |
| | | * If the provided unit name did not correspond to a known |
| | | * duration unit, or if the base unit is bigger than the |
| | | * maximum unit. |
| | | */ |
| | | public final void setBaseUnit(String unit) { |
| | | Reject.ifNull(unit); |
| | | |
| | | setBaseUnit(DurationUnit.getUnit(unit)); |
| | | } |
| | | |
| | | /** |
| | | * Set the base unit for this property definition (values including |
| | | * limits are specified in this unit). By default a duration property |
| | | * definition uses seconds. |
| | | * |
| | | * @param unit |
| | | * The base unit (must not be <code>null</code>). |
| | | * @throws IllegalArgumentException |
| | | * If the provided base unit is bigger than the maximum |
| | | * unit. |
| | | */ |
| | | public final void setBaseUnit(DurationUnit unit) { |
| | | Reject.ifNull(unit); |
| | | |
| | | // Make sure that the base unit is not bigger than the maximum |
| | | // unit. |
| | | if (maximumUnit != null) { |
| | | if (unit.getDuration() > maximumUnit.getDuration()) { |
| | | throw new IllegalArgumentException("Base unit greater than maximum unit"); |
| | | } |
| | | } |
| | | |
| | | this.baseUnit = unit; |
| | | } |
| | | |
| | | /** |
| | | * Set the maximum unit for this property definition. By default there |
| | | * is no maximum unit. |
| | | * |
| | | * @param unit |
| | | * The string representation of the maximum unit, or |
| | | * <code>null</code> if there should not be a maximum unit. |
| | | * @throws IllegalArgumentException |
| | | * If the provided unit name did not correspond to a known |
| | | * duration unit, or if the maximum unit is smaller than the |
| | | * base unit. |
| | | */ |
| | | public final void setMaximumUnit(String unit) { |
| | | if (unit == null) { |
| | | setMaximumUnit((DurationUnit) null); |
| | | } else { |
| | | setMaximumUnit(DurationUnit.getUnit(unit)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Set the maximum unit for this property definition. By default there |
| | | * is no maximum unit. |
| | | * |
| | | * @param unit |
| | | * The maximum unit, or <code>null</code> if there should not |
| | | * be a maximum unit. |
| | | * @throws IllegalArgumentException |
| | | * If the provided maximum unit is smaller than the base |
| | | * unit. |
| | | */ |
| | | public final void setMaximumUnit(DurationUnit unit) { |
| | | if (unit != null) { |
| | | // Make sure that the maximum unit is not smaller than the |
| | | // base unit. |
| | | if (unit.getDuration() < baseUnit.getDuration()) { |
| | | throw new IllegalArgumentException("Maximum unit smaller than base unit"); |
| | | } |
| | | } |
| | | |
| | | this.maximumUnit = unit; |
| | | } |
| | | |
| | | /** |
| | | * Set the lower limit in milli-seconds. |
| | | * |
| | | * @param lowerLimit |
| | | * The new lower limit (must be >= 0) in milli-seconds. |
| | | * @throws IllegalArgumentException |
| | | * If a negative lower limit was specified, or the lower |
| | | * limit is greater than the upper limit. |
| | | */ |
| | | public final void setLowerLimit(long lowerLimit) { |
| | | if (lowerLimit < 0) { |
| | | throw new IllegalArgumentException("Negative lower limit"); |
| | | } |
| | | |
| | | if (upperLimit != null && lowerLimit > upperLimit) { |
| | | throw new IllegalArgumentException("Lower limit greater than upper limit"); |
| | | } |
| | | |
| | | this.lowerLimit = lowerLimit; |
| | | } |
| | | |
| | | /** |
| | | * Set the lower limit using a string representation of the limit. If |
| | | * the string does not specify a unit, the current base unit will be |
| | | * used. |
| | | * |
| | | * @param lowerLimit |
| | | * The string representation of the new lower limit. |
| | | * @throws IllegalArgumentException |
| | | * If the lower limit could not be parsed, or if a negative |
| | | * lower limit was specified, or the lower limit is greater |
| | | * than the upper limit. |
| | | */ |
| | | public final void setLowerLimit(String lowerLimit) { |
| | | setLowerLimit(DurationUnit.parseValue(lowerLimit, baseUnit)); |
| | | } |
| | | |
| | | /** |
| | | * Set the upper limit in milli-seconds. |
| | | * |
| | | * @param upperLimit |
| | | * The new upper limit in milli-seconds, or <code>null</code> |
| | | * if there is no upper limit. |
| | | * @throws IllegalArgumentException |
| | | * If a negative upper limit was specified, or the lower |
| | | * limit is greater than the upper limit or unlimited |
| | | * durations are permitted. |
| | | */ |
| | | public final void setUpperLimit(Long upperLimit) { |
| | | if (upperLimit != null) { |
| | | if (upperLimit < 0) { |
| | | throw new IllegalArgumentException("Negative upper limit"); |
| | | } |
| | | |
| | | if (lowerLimit > upperLimit) { |
| | | throw new IllegalArgumentException("Lower limit greater than upper limit"); |
| | | } |
| | | |
| | | if (allowUnlimited) { |
| | | throw new IllegalArgumentException("Upper limit specified when unlimited durations are permitted"); |
| | | } |
| | | } |
| | | |
| | | this.upperLimit = upperLimit; |
| | | } |
| | | |
| | | /** |
| | | * Set the upper limit using a string representation of the limit. If |
| | | * the string does not specify a unit, the current base unit will be |
| | | * used. |
| | | * |
| | | * @param upperLimit |
| | | * The string representation of the new upper limit, or |
| | | * <code>null</code> if there is no upper limit. |
| | | * @throws IllegalArgumentException |
| | | * If the upper limit could not be parsed, or if the lower |
| | | * limit is greater than the upper limit. |
| | | */ |
| | | public final void setUpperLimit(String upperLimit) { |
| | | if (upperLimit == null) { |
| | | setUpperLimit((Long) null); |
| | | } else { |
| | | setUpperLimit(DurationUnit.parseValue(upperLimit, baseUnit)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Specify whether or not this property definition will allow unlimited |
| | | * values (default is false). |
| | | * |
| | | * @param allowUnlimited |
| | | * <code>true</code> if the property will allow unlimited |
| | | * values, or <code>false</code> otherwise. |
| | | * @throws IllegalArgumentException |
| | | * If unlimited values are to be permitted but there is an |
| | | * upper limit specified. |
| | | */ |
| | | public final void setAllowUnlimited(boolean allowUnlimited) { |
| | | if (allowUnlimited && upperLimit != null) { |
| | | throw new IllegalArgumentException("Upper limit specified when unlimited durations are permitted"); |
| | | } |
| | | |
| | | this.allowUnlimited = allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected DurationPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Long> defaultBehavior) { |
| | | return new DurationPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, baseUnit, |
| | | maximumUnit, lowerLimit, upperLimit, allowUnlimited); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Create a duration property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new integer property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private DurationPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Long> defaultBehavior, DurationUnit baseUnit, DurationUnit maximumUnit, |
| | | Long lowerLimit, Long upperLimit, boolean allowUnlimited) { |
| | | super(d, Long.class, propertyName, options, adminAction, defaultBehavior); |
| | | this.baseUnit = baseUnit; |
| | | this.maximumUnit = maximumUnit; |
| | | this.lowerLimit = lowerLimit; |
| | | this.upperLimit = upperLimit; |
| | | this.allowUnlimited = allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * Get the base unit for this property definition (values including limits |
| | | * are specified in this unit). |
| | | * |
| | | * @return Returns the base unit for this property definition (values |
| | | * including limits are specified in this unit). |
| | | */ |
| | | public DurationUnit getBaseUnit() { |
| | | return baseUnit; |
| | | } |
| | | |
| | | /** |
| | | * Get the maximum unit for this property definition if specified. |
| | | * |
| | | * @return Returns the maximum unit for this property definition, or |
| | | * <code>null</code> if there is no maximum unit. |
| | | */ |
| | | public DurationUnit getMaximumUnit() { |
| | | return maximumUnit; |
| | | } |
| | | |
| | | /** |
| | | * Get the lower limit in milli-seconds. |
| | | * |
| | | * @return Returns the lower limit in milli-seconds. |
| | | */ |
| | | public long getLowerLimit() { |
| | | return lowerLimit; |
| | | } |
| | | |
| | | /** |
| | | * Get the upper limit in milli-seconds. |
| | | * |
| | | * @return Returns the upper limit in milli-seconds, or <code>null</code> if |
| | | * there is no upper limit. |
| | | */ |
| | | public Long getUpperLimit() { |
| | | return upperLimit; |
| | | } |
| | | |
| | | /** |
| | | * Determine whether this property allows unlimited durations. |
| | | * |
| | | * @return Returns <code>true</code> if this this property allows unlimited |
| | | * durations. |
| | | */ |
| | | public boolean isAllowUnlimited() { |
| | | return allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(Long value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | long nvalue = baseUnit.toMilliSeconds(value); |
| | | if (!allowUnlimited && nvalue < lowerLimit) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | |
| | | // unlimited allowed |
| | | } else if (nvalue >= 0 && nvalue < lowerLimit) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | |
| | | if ((upperLimit != null) && (nvalue > upperLimit)) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String encodeValue(Long value) { |
| | | Reject.ifNull(value); |
| | | |
| | | // Make sure that we correctly encode negative values as |
| | | // "unlimited". |
| | | if (allowUnlimited) { |
| | | if (value < 0) { |
| | | return UNLIMITED; |
| | | } |
| | | } |
| | | |
| | | // Encode the size value using the base unit. |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append(value); |
| | | builder.append(' '); |
| | | builder.append(baseUnit.toString()); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Long decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // First check for the special "unlimited" value when necessary. |
| | | if (allowUnlimited) { |
| | | if (value.trim().equalsIgnoreCase(UNLIMITED)) { |
| | | return -1L; |
| | | } |
| | | } |
| | | |
| | | // Parse the string representation. |
| | | long ms; |
| | | try { |
| | | ms = DurationUnit.parseValue(value); |
| | | } catch (NumberFormatException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | |
| | | // Check the unit is in range - values must not be more granular |
| | | // than the base unit. |
| | | if ((ms % baseUnit.getDuration()) != 0) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | |
| | | // Convert the value a long in the property's required unit. |
| | | Long i = (long) baseUnit.fromMilliSeconds(ms); |
| | | try { |
| | | validateValue(i, options); |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | return i; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitDuration(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, Long value, P p) { |
| | | return v.visitDuration(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | super.toString(builder); |
| | | |
| | | builder.append(" baseUnit="); |
| | | builder.append(baseUnit); |
| | | |
| | | if (maximumUnit != null) { |
| | | builder.append(" maximumUnit="); |
| | | builder.append(maximumUnit); |
| | | } |
| | | |
| | | builder.append(" lowerLimit="); |
| | | builder.append(lowerLimit); |
| | | builder.append("ms"); |
| | | |
| | | if (upperLimit != null) { |
| | | builder.append(" upperLimit="); |
| | | builder.append(upperLimit); |
| | | builder.append("ms"); |
| | | } |
| | | |
| | | builder.append(" allowUnlimited="); |
| | | builder.append(allowUnlimited); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(Long o1, Long o2) { |
| | | return o1.compareTo(o2); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * This enumeration defines various duration units. |
| | | */ |
| | | public enum DurationUnit { |
| | | |
| | | /** |
| | | * A day unit. |
| | | */ |
| | | DAYS((long) 24 * 60 * 60 * 1000, "d", "days"), |
| | | |
| | | /** |
| | | * An hour unit. |
| | | */ |
| | | HOURS((long) 60 * 60 * 1000, "h", "hours"), |
| | | |
| | | /** |
| | | * A millisecond unit. |
| | | */ |
| | | MILLI_SECONDS(1L, "ms", "milliseconds"), |
| | | |
| | | /** |
| | | * A minute unit. |
| | | */ |
| | | MINUTES((long) 60 * 1000, "m", "minutes"), |
| | | |
| | | /** |
| | | * A second unit. |
| | | */ |
| | | SECONDS(1000L, "s", "seconds"), |
| | | |
| | | /** |
| | | * A week unit. |
| | | */ |
| | | WEEKS((long) 7 * 24 * 60 * 60 * 1000, "w", "weeks"); |
| | | |
| | | // A lookup table for resolving a unit from its name. |
| | | private static final Map<String, DurationUnit> NAME_TO_UNIT; |
| | | static { |
| | | NAME_TO_UNIT = new HashMap<String, DurationUnit>(); |
| | | |
| | | for (DurationUnit unit : DurationUnit.values()) { |
| | | NAME_TO_UNIT.put(unit.shortName, unit); |
| | | NAME_TO_UNIT.put(unit.longName, unit); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the unit corresponding to the provided unit name. |
| | | * |
| | | * @param s |
| | | * The name of the unit. Can be the abbreviated or long name and |
| | | * can contain white space and mixed case characters. |
| | | * @return Returns the unit corresponding to the provided unit name. |
| | | * @throws IllegalArgumentException |
| | | * If the provided name did not correspond to a known duration |
| | | * unit. |
| | | */ |
| | | public static DurationUnit getUnit(String s) { |
| | | DurationUnit unit = NAME_TO_UNIT.get(s.trim().toLowerCase()); |
| | | if (unit == null) { |
| | | throw new IllegalArgumentException("Illegal duration unit \"" + s + "\""); |
| | | } |
| | | return unit; |
| | | } |
| | | |
| | | /** |
| | | * Parse the provided duration string and return its equivalent duration in |
| | | * milliseconds. The duration string must specify the unit e.g. "10s". This |
| | | * method will parse duration string representations produced from the |
| | | * {@link #toString(long)} method. Therefore, a duration can comprise of |
| | | * multiple duration specifiers, for example <code>1d15m25s</code>. |
| | | * |
| | | * @param s |
| | | * The duration string to be parsed. |
| | | * @return Returns the parsed duration in milliseconds. |
| | | * @throws NumberFormatException |
| | | * If the provided duration string could not be parsed. |
| | | * @see #toString(long) |
| | | */ |
| | | public static long parseValue(String s) { |
| | | return parseValue(s, null); |
| | | } |
| | | |
| | | /** |
| | | * Parse the provided duration string and return its equivalent duration in |
| | | * milliseconds. This method will parse duration string representations |
| | | * produced from the {@link #toString(long)} method. Therefore, a duration |
| | | * can comprise of multiple duration specifiers, for example |
| | | * <code>1d15m25s</code>. |
| | | * |
| | | * @param s |
| | | * The duration string to be parsed. |
| | | * @param defaultUnit |
| | | * The default unit to use if there is no unit specified in the |
| | | * duration string, or <code>null</code> if the string must |
| | | * always contain a unit. |
| | | * @return Returns the parsed duration in milliseconds. |
| | | * @throws NumberFormatException |
| | | * If the provided duration string could not be parsed. |
| | | * @see #toString(long) |
| | | */ |
| | | public static long parseValue(String s, DurationUnit defaultUnit) { |
| | | String ns = s.trim(); |
| | | if (ns.length() == 0) { |
| | | throw new NumberFormatException("Empty duration value \"" + s + "\""); |
| | | } |
| | | |
| | | Pattern p1 = |
| | | Pattern.compile("^\\s*((\\d+)\\s*w)?" + "\\s*((\\d+)\\s*d)?" + "\\s*((\\d+)\\s*h)?" |
| | | + "\\s*((\\d+)\\s*m)?" + "\\s*((\\d+)\\s*s)?" + "\\s*((\\d+)\\s*ms)?\\s*$", Pattern.CASE_INSENSITIVE); |
| | | Matcher m1 = p1.matcher(ns); |
| | | if (m1.matches()) { |
| | | // Value must be of the form produced by toString(long). |
| | | String weeks = m1.group(2); |
| | | String days = m1.group(4); |
| | | String hours = m1.group(6); |
| | | String minutes = m1.group(8); |
| | | String seconds = m1.group(10); |
| | | String ms = m1.group(12); |
| | | |
| | | long duration = 0; |
| | | |
| | | try { |
| | | if (weeks != null) { |
| | | duration += Long.valueOf(weeks) * WEEKS.getDuration(); |
| | | } |
| | | |
| | | if (days != null) { |
| | | duration += Long.valueOf(days) * DAYS.getDuration(); |
| | | } |
| | | |
| | | if (hours != null) { |
| | | duration += Long.valueOf(hours) * HOURS.getDuration(); |
| | | } |
| | | |
| | | if (minutes != null) { |
| | | duration += Long.valueOf(minutes) * MINUTES.getDuration(); |
| | | } |
| | | |
| | | if (seconds != null) { |
| | | duration += Long.valueOf(seconds) * SECONDS.getDuration(); |
| | | } |
| | | |
| | | if (ms != null) { |
| | | duration += Long.valueOf(ms) * MILLI_SECONDS.getDuration(); |
| | | } |
| | | } catch (NumberFormatException e) { |
| | | throw new NumberFormatException("Invalid duration value \"" + s + "\""); |
| | | } |
| | | |
| | | return duration; |
| | | } else { |
| | | // Value must be a floating point number followed by a unit. |
| | | Pattern p2 = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)?\\s*$"); |
| | | Matcher m2 = p2.matcher(ns); |
| | | |
| | | if (!m2.matches()) { |
| | | throw new NumberFormatException("Invalid duration value \"" + s + "\""); |
| | | } |
| | | |
| | | // Group 1 is the float. |
| | | double d; |
| | | try { |
| | | d = Double.valueOf(m2.group(1)); |
| | | } catch (NumberFormatException e) { |
| | | throw new NumberFormatException("Invalid duration value \"" + s + "\""); |
| | | } |
| | | |
| | | // Group 3 is the unit. |
| | | String unitString = m2.group(3); |
| | | DurationUnit unit; |
| | | if (unitString == null) { |
| | | if (defaultUnit == null) { |
| | | throw new NumberFormatException("Invalid duration value \"" + s + "\""); |
| | | } else { |
| | | unit = defaultUnit; |
| | | } |
| | | } else { |
| | | try { |
| | | unit = getUnit(unitString); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new NumberFormatException("Invalid duration value \"" + s + "\""); |
| | | } |
| | | } |
| | | |
| | | return unit.toMilliSeconds(d); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Returns a string representation of the provided duration. The string |
| | | * representation can be parsed using the {@link #parseValue(String)} |
| | | * method. The string representation is comprised of one or more of the |
| | | * number of weeks, days, hours, minutes, seconds, and milliseconds. Here |
| | | * are some examples: |
| | | * |
| | | * <pre> |
| | | * toString(0) // 0 ms |
| | | * toString(999) // 999 ms |
| | | * toString(1000) // 1 s |
| | | * toString(1500) // 1 s 500 ms |
| | | * toString(3650000) // 1 h 50 s |
| | | * toString(3700000) // 1 h 1 m 40 s |
| | | * </pre> |
| | | * |
| | | * @param duration |
| | | * The duration in milliseconds. |
| | | * @return Returns a string representation of the provided duration. |
| | | * @throws IllegalArgumentException |
| | | * If the provided duration is negative. |
| | | * @see #parseValue(String) |
| | | * @see #parseValue(String, DurationUnit) |
| | | */ |
| | | public static String toString(long duration) { |
| | | if (duration < 0) { |
| | | throw new IllegalArgumentException("Negative duration " + duration); |
| | | } |
| | | |
| | | if (duration == 0) { |
| | | return "0 ms"; |
| | | } |
| | | |
| | | DurationUnit[] units = new DurationUnit[] { WEEKS, DAYS, HOURS, MINUTES, SECONDS, MILLI_SECONDS }; |
| | | long remainder = duration; |
| | | StringBuilder builder = new StringBuilder(); |
| | | boolean isFirst = true; |
| | | for (DurationUnit unit : units) { |
| | | long count = remainder / unit.getDuration(); |
| | | if (count > 0) { |
| | | if (!isFirst) { |
| | | builder.append(' '); |
| | | } |
| | | builder.append(count); |
| | | builder.append(' '); |
| | | builder.append(unit.getShortName()); |
| | | remainder = remainder - (count * unit.getDuration()); |
| | | isFirst = false; |
| | | } |
| | | } |
| | | return builder.toString(); |
| | | } |
| | | |
| | | // The long name of the unit. |
| | | private final String longName; |
| | | |
| | | // The abbreviation of the unit. |
| | | private final String shortName; |
| | | |
| | | // The size of the unit in milliseconds. |
| | | private final long sz; |
| | | |
| | | // Private constructor. |
| | | private DurationUnit(long sz, String shortName, String longName) { |
| | | this.sz = sz; |
| | | this.shortName = shortName; |
| | | this.longName = longName; |
| | | } |
| | | |
| | | /** |
| | | * Converts the specified duration in milliseconds to this unit. |
| | | * |
| | | * @param duration |
| | | * The duration in milliseconds. |
| | | * @return Returns milliseconds in this unit. |
| | | */ |
| | | public double fromMilliSeconds(long duration) { |
| | | return ((double) duration / sz); |
| | | } |
| | | |
| | | /** |
| | | * Get the number of milliseconds that this unit represents. |
| | | * |
| | | * @return Returns the number of milliseconds that this unit represents. |
| | | */ |
| | | public long getDuration() { |
| | | return sz; |
| | | } |
| | | |
| | | /** |
| | | * Get the long name of this unit. |
| | | * |
| | | * @return Returns the long name of this unit. |
| | | */ |
| | | public String getLongName() { |
| | | return longName; |
| | | } |
| | | |
| | | /** |
| | | * Get the abbreviated name of this unit. |
| | | * |
| | | * @return Returns the abbreviated name of this unit. |
| | | */ |
| | | public String getShortName() { |
| | | return shortName; |
| | | } |
| | | |
| | | /** |
| | | * Converts the specified duration in this unit to milliseconds. |
| | | * |
| | | * @param duration |
| | | * The duration as a quantity of this unit. |
| | | * @return Returns the number of milliseconds that the duration represents. |
| | | */ |
| | | public long toMilliSeconds(double duration) { |
| | | return (long) (sz * duration); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * This implementation returns the abbreviated name of this duration unit. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return shortName; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.HashMap; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.MissingResourceException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Enumeration property definition. |
| | | * |
| | | * @param <E> |
| | | * The enumeration that should be used for values of this property |
| | | * definition. |
| | | */ |
| | | public final class EnumPropertyDefinition<E extends Enum<E>> extends PropertyDefinition<E> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing enumeration property |
| | | * definitions. |
| | | * |
| | | * @param <E> |
| | | * The enumeration that should be used for values of this |
| | | * property definition. |
| | | */ |
| | | public final static class Builder<E extends Enum<E>> extends AbstractBuilder<E, EnumPropertyDefinition<E>> { |
| | | |
| | | // The enumeration class. |
| | | private Class<E> enumClass; |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | this.enumClass = null; |
| | | } |
| | | |
| | | /** |
| | | * Set the enumeration class which should be used for values of this |
| | | * property definition. |
| | | * |
| | | * @param enumClass |
| | | * The enumeration class which should be used for values of |
| | | * this property definition. |
| | | */ |
| | | public final void setEnumClass(Class<E> enumClass) { |
| | | this.enumClass = enumClass; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected EnumPropertyDefinition<E> buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<E> defaultBehavior) { |
| | | // Make sure that the enumeration class has been defined. |
| | | if (enumClass == null) { |
| | | throw new IllegalStateException("Enumeration class undefined"); |
| | | } |
| | | |
| | | return new EnumPropertyDefinition<E>(d, propertyName, options, adminAction, defaultBehavior, enumClass); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Create an enumeration property definition builder. |
| | | * |
| | | * @param <E> |
| | | * The enumeration that should be used for values of this |
| | | * property definition. |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new enumeration property definition builder. |
| | | */ |
| | | public static <E extends Enum<E>> Builder<E> createBuilder(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName) { |
| | | return new Builder<E>(d, propertyName); |
| | | } |
| | | |
| | | // The enumeration class. |
| | | private final Class<E> enumClass; |
| | | |
| | | // Map used for decoding values. |
| | | private final Map<String, E> decodeMap; |
| | | |
| | | // Private constructor. |
| | | private EnumPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, DefaultBehaviorProvider<E> defaultBehavior, |
| | | Class<E> enumClass) { |
| | | super(d, enumClass, propertyName, options, adminAction, defaultBehavior); |
| | | this.enumClass = enumClass; |
| | | |
| | | // Initialize the decoding map. |
| | | this.decodeMap = new HashMap<String, E>(); |
| | | for (E value : EnumSet.<E> allOf(enumClass)) { |
| | | String s = value.toString().trim().toLowerCase(); |
| | | this.decodeMap.put(s, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitEnum(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, E value, P p) { |
| | | return v.visitEnum(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public E decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | String nvalue = value.trim().toLowerCase(); |
| | | E eValue = decodeMap.get(nvalue); |
| | | if (eValue == null) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } else { |
| | | return eValue; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the enumeration class used for values of this property. |
| | | * |
| | | * @return Returns the enumeration class used for values of this property. |
| | | */ |
| | | public Class<E> getEnumClass() { |
| | | return enumClass; |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of the specified enumeration value of this enumeration |
| | | * property definition in the default locale. |
| | | * |
| | | * @param value |
| | | * The enumeration value. |
| | | * @return Returns the synopsis of the specified enumeration value of this |
| | | * enumeration property definition in the default locale. |
| | | */ |
| | | public final LocalizableMessage getValueSynopsis(E value) { |
| | | return getValueSynopsis(Locale.getDefault(), value); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of the specified enumeration value of this enumeration |
| | | * property definition in the specified locale. |
| | | * |
| | | * @param value |
| | | * The enumeration value. |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of the specified enumeration value of this |
| | | * enumeration property definition in the specified locale. |
| | | */ |
| | | public final LocalizableMessage getValueSynopsis(Locale locale, E value) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "property." + getName() + ".syntax.enumeration.value." + value.toString() + ".synopsis"; |
| | | try { |
| | | return resource.getMessage(getManagedObjectDefinition(), property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String normalizeValue(E value) { |
| | | Reject.ifNull(value); |
| | | |
| | | return value.toString().trim().toLowerCase(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(E value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // No additional validation required. |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.Locale; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.config.client.ClientConstraintHandler; |
| | | import org.forgerock.opendj.config.client.ManagedObject; |
| | | import org.forgerock.opendj.config.client.ManagementContext; |
| | | import org.forgerock.opendj.config.conditions.Condition; |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | import org.forgerock.opendj.config.server.ServerConstraintHandler; |
| | | import org.forgerock.opendj.config.server.ServerManagedObject; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | |
| | | /** |
| | | * A generic constraint which comprises of an underlying condition and a |
| | | * description. The condition must evaluate to <code>true</code> in order for a |
| | | * new managed object to be created or modified. |
| | | */ |
| | | public class GenericConstraint extends Constraint { |
| | | |
| | | /** |
| | | * The client-side constraint handler. |
| | | */ |
| | | private final class ClientHandler extends ClientConstraintHandler { |
| | | |
| | | // Private constructor. |
| | | private ClientHandler() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isAddAcceptable(ManagementContext context, ManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | if (!condition.evaluate(context, managedObject)) { |
| | | unacceptableReasons.add(getSynopsis()); |
| | | return false; |
| | | } else { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isModifyAcceptable(ManagementContext context, ManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | if (!condition.evaluate(context, managedObject)) { |
| | | unacceptableReasons.add(getSynopsis()); |
| | | return false; |
| | | } else { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | }; |
| | | |
| | | /** |
| | | * The server-side constraint handler. |
| | | */ |
| | | private final class ServerHandler extends ServerConstraintHandler { |
| | | |
| | | // Private constructor. |
| | | private ServerHandler() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isUsable(ServerManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ConfigException { |
| | | if (!condition.evaluate(managedObject)) { |
| | | unacceptableReasons.add(getSynopsis()); |
| | | return false; |
| | | } else { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | }; |
| | | |
| | | // The client-side constraint handler. |
| | | private final ClientConstraintHandler clientHandler = new ClientHandler(); |
| | | |
| | | // The condition associated with this constraint. |
| | | private final Condition condition; |
| | | |
| | | // The managed object definition associated with this constraint. |
| | | private final AbstractManagedObjectDefinition<?, ?> definition; |
| | | |
| | | // The constraint ID. |
| | | private final int id; |
| | | |
| | | // The server-side constraint handler. |
| | | private final ServerConstraintHandler serverHandler = new ServerHandler(); |
| | | |
| | | /** |
| | | * Creates a new generic constraint. |
| | | * |
| | | * @param definition |
| | | * The managed object definition associated with this constraint. |
| | | * @param id |
| | | * The constraint ID. |
| | | * @param condition |
| | | * The condition associated with this constraint. |
| | | */ |
| | | public GenericConstraint(AbstractManagedObjectDefinition<?, ?> definition, int id, Condition condition) { |
| | | this.definition = definition; |
| | | this.id = id; |
| | | this.condition = condition; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<ClientConstraintHandler> getClientConstraintHandlers() { |
| | | return Collections.singleton(clientHandler); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public Collection<ServerConstraintHandler> getServerConstraintHandlers() { |
| | | return Collections.singleton(serverHandler); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this constraint in the default locale. |
| | | * |
| | | * @return Returns the synopsis of this constraint in the default locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this constraint in the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this constraint in the specified locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "constraint." + id + ".synopsis"; |
| | | return resource.getMessage(definition, property, locale); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | condition.initialize(definition); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | |
| | | import org.opends.server.types.AddressMask; |
| | | |
| | | /** |
| | | * IP address mask property definition. |
| | | */ |
| | | public final class IPAddressMaskPropertyDefinition extends PropertyDefinition<AddressMask> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing IP address mask property |
| | | * definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<AddressMask, IPAddressMaskPropertyDefinition> { |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected IPAddressMaskPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<AddressMask> defaultBehavior) { |
| | | return new IPAddressMaskPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Create a IP address mask property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new IP address mask property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private IPAddressMaskPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<AddressMask> defaultBehavior) { |
| | | super(d, AddressMask.class, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(AddressMask value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // No additional validation required. |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AddressMask decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | try { |
| | | return AddressMask.decode(value); |
| | | } catch (ConfigException e) { |
| | | // TODO: it would be nice to throw the cause. |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitIPAddressMask(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, AddressMask value, P p) { |
| | | return v.visitIPAddressMask(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(AddressMask o1, AddressMask o2) { |
| | | return o1.toString().compareTo(o2.toString()); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.net.InetAddress; |
| | | import java.net.UnknownHostException; |
| | | import java.util.EnumSet; |
| | | |
| | | /** |
| | | * IP address property definition. |
| | | */ |
| | | public final class IPAddressPropertyDefinition extends PropertyDefinition<InetAddress> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing IP address property |
| | | * definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<InetAddress, IPAddressPropertyDefinition> { |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected IPAddressPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<InetAddress> defaultBehavior) { |
| | | return new IPAddressPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Create a IP address property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new IP address property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private IPAddressPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<InetAddress> defaultBehavior) { |
| | | super(d, InetAddress.class, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(InetAddress value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // No additional validation required. |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public InetAddress decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | try { |
| | | return InetAddress.getByName(value); |
| | | } catch (UnknownHostException e) { |
| | | // TODO: it would be nice to throw the cause. |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String encodeValue(InetAddress value) { |
| | | // We should return the host name if it is available, or the IP |
| | | // address if not. |
| | | |
| | | // Unforunately, there is no InetAddress method for doing this, so |
| | | // we have to resort to hacking at the toString() encoding. |
| | | String s = value.toString(); |
| | | int i = s.indexOf('/'); |
| | | if (i > 0) { |
| | | // Host address is before the forward slash. |
| | | return s.substring(0, i); |
| | | } else { |
| | | return value.getHostAddress(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitIPAddress(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, InetAddress value, P p) { |
| | | return v.visitIPAddress(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(InetAddress o1, InetAddress o2) { |
| | | return o1.getHostAddress().compareTo(o2.getHostAddress()); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2013 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Thrown to indicate that a property value was invalid according to its |
| | | * associated property definition. |
| | | */ |
| | | public class IllegalPropertyValueException extends PropertyException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = -3145632074909281823L; |
| | | |
| | | // The illegal property value. |
| | | private final Object value; |
| | | |
| | | /** |
| | | * Create a new illegal property value exception. |
| | | * |
| | | * @param pd |
| | | * The property definition. |
| | | * @param value |
| | | * The illegal property value. |
| | | */ |
| | | public IllegalPropertyValueException(PropertyDefinition<?> pd, Object value) { |
| | | super(pd, createMessage(pd, value)); |
| | | this.value = value; |
| | | } |
| | | |
| | | /** |
| | | * Create a new illegal property value exception. |
| | | * |
| | | * @param pd |
| | | * The property definition. |
| | | * @param value |
| | | * The illegal property value. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public IllegalPropertyValueException(PropertyDefinition<?> pd, Object value, Throwable cause) { |
| | | super(pd, createMessage(pd, value), cause); |
| | | this.value = value; |
| | | } |
| | | |
| | | /** |
| | | * Get the illegal property value that caused the exception. |
| | | * |
| | | * @return Returns the illegal property value. |
| | | */ |
| | | public final Object getIllegalValue() { |
| | | return value; |
| | | } |
| | | |
| | | // Create the message. |
| | | private static LocalizableMessage createMessage(PropertyDefinition<?> pd, Object value) { |
| | | PropertyDefinitionUsageBuilder builder = new PropertyDefinitionUsageBuilder(true); |
| | | return ERR_ILLEGAL_PROPERTY_VALUE_EXCEPTION.get(String.valueOf(value), pd.getName(), builder.getUsage(pd)); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2013 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * Thrown to indicate that a property value string was invalid according to its |
| | | * associated property definition. |
| | | */ |
| | | public class IllegalPropertyValueStringException extends PropertyException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = -3145632074909281823L; |
| | | |
| | | // The illegal property value string. |
| | | private final String value; |
| | | |
| | | /** |
| | | * Create a new illegal property value string exception. |
| | | * |
| | | * @param pd |
| | | * The property definition. |
| | | * @param value |
| | | * The illegal property value string. |
| | | */ |
| | | public IllegalPropertyValueStringException(PropertyDefinition<?> pd, String value) { |
| | | super(pd, createMessage(pd, value)); |
| | | this.value = value; |
| | | } |
| | | |
| | | /** |
| | | * Create a new illegal property value string exception. |
| | | * |
| | | * @param pd |
| | | * The property definition. |
| | | * @param value |
| | | * The illegal property value string. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public IllegalPropertyValueStringException(PropertyDefinition<?> pd, String value, Throwable cause) { |
| | | super(pd, createMessage(pd, value), cause); |
| | | this.value = value; |
| | | } |
| | | |
| | | /** |
| | | * Get the illegal property value string that caused the exception. |
| | | * |
| | | * @return Returns the illegal property value string. |
| | | */ |
| | | public final String getIllegalValueString() { |
| | | return value; |
| | | } |
| | | |
| | | // Create the message. |
| | | private static LocalizableMessage createMessage(PropertyDefinition<?> pd, String value) { |
| | | PropertyDefinitionUsageBuilder builder = new PropertyDefinitionUsageBuilder(true); |
| | | return ERR_ILLEGAL_PROPERTY_VALUE_STRING_EXCEPTION.get(value, pd.getName(), builder.getUsage(pd)); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * A managed object composite relationship definition which represents a |
| | | * composition of zero or more managed objects. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this relation |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this relation |
| | | * definition refers to. |
| | | */ |
| | | public final class InstantiableRelationDefinition<C extends ConfigurationClient, S extends Configuration> extends |
| | | RelationDefinition<C, S> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing instantiable relation |
| | | * definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | */ |
| | | public static final class Builder<C extends ConfigurationClient, S extends Configuration> extends |
| | | AbstractBuilder<C, S, InstantiableRelationDefinition<C, S>> { |
| | | |
| | | // The optional naming property definition. |
| | | private PropertyDefinition<?> namingPropertyDefinition = null; |
| | | |
| | | // The plural name of the relation. |
| | | private final String pluralName; |
| | | |
| | | // The optional default managed objects associated with this |
| | | // instantiable relation definition. |
| | | private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects = |
| | | new HashMap<String, DefaultManagedObject<? extends C, ? extends S>>(); |
| | | |
| | | /** |
| | | * Creates a new builder which can be used to incrementally build an |
| | | * instantiable relation definition. |
| | | * |
| | | * @param pd |
| | | * The parent managed object definition. |
| | | * @param name |
| | | * The name of the relation. |
| | | * @param pluralName |
| | | * The plural name of the relation. |
| | | * @param cd |
| | | * The child managed object definition. |
| | | */ |
| | | public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name, String pluralName, |
| | | AbstractManagedObjectDefinition<C, S> cd) { |
| | | super(pd, name, cd); |
| | | this.pluralName = pluralName; |
| | | } |
| | | |
| | | /** |
| | | * Adds the named default managed object to this instantiable relation |
| | | * definition. |
| | | * |
| | | * @param name |
| | | * The name of the default managed object. |
| | | * @param defaultManagedObject |
| | | * The default managed object. |
| | | */ |
| | | public void setDefaultManagedObject(String name, |
| | | DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) { |
| | | this.defaultManagedObjects.put(name, defaultManagedObject); |
| | | } |
| | | |
| | | /** |
| | | * Sets the naming property for the instantiable relation definition. |
| | | * |
| | | * @param namingPropertyDefinition |
| | | * The property of the child managed object definition which |
| | | * should be used for naming, or <code>null</code> if this |
| | | * relation does not use a property for naming. |
| | | */ |
| | | public void setNamingProperty(PropertyDefinition<?> namingPropertyDefinition) { |
| | | Reject.ifNull(namingPropertyDefinition); |
| | | this.namingPropertyDefinition = namingPropertyDefinition; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected InstantiableRelationDefinition<C, S> buildInstance(Common<C, S> common) { |
| | | return new InstantiableRelationDefinition<C, S>(common, pluralName, namingPropertyDefinition, |
| | | defaultManagedObjects); |
| | | } |
| | | |
| | | } |
| | | |
| | | // The optional naming property definition. |
| | | private final PropertyDefinition<?> namingPropertyDefinition; |
| | | |
| | | // The plural name of the relation. |
| | | private final String pluralName; |
| | | |
| | | // The optional default managed objects associated with this |
| | | // instantiable relation definition. |
| | | private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects; |
| | | |
| | | // Private constructor. |
| | | private InstantiableRelationDefinition(Common<C, S> common, String pluralName, |
| | | PropertyDefinition<?> namingPropertyDefinition, |
| | | Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects) { |
| | | super(common); |
| | | this.pluralName = pluralName; |
| | | this.namingPropertyDefinition = namingPropertyDefinition; |
| | | this.defaultManagedObjects = defaultManagedObjects; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitInstantiable(this, p); |
| | | } |
| | | |
| | | /** |
| | | * Gets the named default managed object associated with this instantiable |
| | | * relation definition. |
| | | * |
| | | * @param name |
| | | * The name of the default managed object. |
| | | * @return Returns the named default managed object. |
| | | * @throws IllegalArgumentException |
| | | * If there is no default managed object associated with the |
| | | * provided name. |
| | | */ |
| | | public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(String name) { |
| | | if (!defaultManagedObjects.containsKey(name)) { |
| | | throw new IllegalArgumentException("unrecognized default managed object \"" + name + "\""); |
| | | } |
| | | return defaultManagedObjects.get(name); |
| | | } |
| | | |
| | | /** |
| | | * Gets the names of the default managed objects associated with this |
| | | * instantiable relation definition. |
| | | * |
| | | * @return Returns an unmodifiable set containing the names of the default |
| | | * managed object. |
| | | */ |
| | | public Set<String> getDefaultManagedObjectNames() { |
| | | return Collections.unmodifiableSet(defaultManagedObjects.keySet()); |
| | | } |
| | | |
| | | /** |
| | | * Get the property of the child managed object definition which should be |
| | | * used for naming children. |
| | | * |
| | | * @return Returns the property of the child managed object definition which |
| | | * should be used for naming, or <code>null</code> if this relation |
| | | * does not use a property for naming. |
| | | */ |
| | | public PropertyDefinition<?> getNamingPropertyDefinition() { |
| | | return namingPropertyDefinition; |
| | | } |
| | | |
| | | /** |
| | | * Get the plural name of the relation. |
| | | * |
| | | * @return Returns the plural name of the relation. |
| | | */ |
| | | public String getPluralName() { |
| | | return pluralName; |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly plural name of this relation definition in the |
| | | * default locale. |
| | | * |
| | | * @return Returns the user friendly plural name of this relation definition |
| | | * in the default locale. |
| | | */ |
| | | public LocalizableMessage getUserFriendlyPluralName() { |
| | | return getUserFriendlyPluralName(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly plural name of this relation definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the user friendly plural name of this relation definition |
| | | * in the specified locale. |
| | | */ |
| | | public LocalizableMessage getUserFriendlyPluralName(Locale locale) { |
| | | String property = "relation." + getName() + ".user-friendly-plural-name"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | builder.append("name="); |
| | | builder.append(getName()); |
| | | builder.append(" type=collection parent="); |
| | | builder.append(getParentDefinition().getName()); |
| | | builder.append(" child="); |
| | | builder.append(getChildDefinition().getName()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) { |
| | | dmo.initialize(); |
| | | } |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.Locale; |
| | | import java.util.MissingResourceException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Integer property definition. |
| | | * <p> |
| | | * All values must be zero or positive and within the lower/upper limit |
| | | * constraints. Support is provided for "unlimited" values. These are |
| | | * represented using a negative value or using the string "unlimited". |
| | | */ |
| | | public final class IntegerPropertyDefinition extends PropertyDefinition<Integer> { |
| | | |
| | | // String used to represent unlimited. |
| | | private static final String UNLIMITED = "unlimited"; |
| | | |
| | | // The lower limit of the property value. |
| | | private final int lowerLimit; |
| | | |
| | | // The optional upper limit of the property value. |
| | | private final Integer upperLimit; |
| | | |
| | | // Indicates whether this property allows the use of the "unlimited" value |
| | | // (represented using a -1 or the string "unlimited"). |
| | | private final boolean allowUnlimited; |
| | | |
| | | /** |
| | | * An interface for incrementally constructing integer property definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<Integer, IntegerPropertyDefinition> { |
| | | |
| | | // The lower limit of the property value. |
| | | private int lowerLimit = 0; |
| | | |
| | | // The optional upper limit of the property value. |
| | | private Integer upperLimit = null; |
| | | |
| | | // Indicates whether this property allows the use of the "unlimited" |
| | | // value |
| | | // (represented using a -1 or the string "unlimited"). |
| | | private boolean allowUnlimited = false; |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * Set the lower limit. |
| | | * |
| | | * @param lowerLimit |
| | | * The new lower limit (must be >= 0). |
| | | * @throws IllegalArgumentException |
| | | * If a negative lower limit was specified or the lower |
| | | * limit is greater than the upper limit. |
| | | */ |
| | | public final void setLowerLimit(int lowerLimit) { |
| | | if (lowerLimit < 0) { |
| | | throw new IllegalArgumentException("Negative lower limit"); |
| | | } |
| | | if (upperLimit != null && lowerLimit > upperLimit) { |
| | | throw new IllegalArgumentException("Lower limit greater than upper limit"); |
| | | } |
| | | this.lowerLimit = lowerLimit; |
| | | } |
| | | |
| | | /** |
| | | * Set the upper limit. |
| | | * |
| | | * @param upperLimit |
| | | * The new upper limit or <code>null</code> if there is no |
| | | * upper limit. |
| | | */ |
| | | public final void setUpperLimit(Integer upperLimit) { |
| | | if (upperLimit != null) { |
| | | if (upperLimit < 0) { |
| | | throw new IllegalArgumentException("Negative lower limit"); |
| | | } |
| | | if (lowerLimit > upperLimit) { |
| | | throw new IllegalArgumentException("Lower limit greater than upper limit"); |
| | | } |
| | | } |
| | | this.upperLimit = upperLimit; |
| | | } |
| | | |
| | | /** |
| | | * Specify whether or not this property definition will allow unlimited |
| | | * values (default is false). |
| | | * |
| | | * @param allowUnlimited |
| | | * <code>true</code> if the property will allow unlimited |
| | | * values, or <code>false</code> otherwise. |
| | | */ |
| | | public final void setAllowUnlimited(boolean allowUnlimited) { |
| | | this.allowUnlimited = allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected IntegerPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Integer> defaultBehavior) { |
| | | return new IntegerPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, lowerLimit, |
| | | upperLimit, allowUnlimited); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Create an integer property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new integer property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private IntegerPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Integer> defaultBehavior, int lowerLimit, Integer upperLimit, boolean allowUnlimited) { |
| | | super(d, Integer.class, propertyName, options, adminAction, defaultBehavior); |
| | | this.lowerLimit = lowerLimit; |
| | | this.upperLimit = upperLimit; |
| | | this.allowUnlimited = allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * Get the lower limit. |
| | | * |
| | | * @return Returns the lower limit. |
| | | */ |
| | | public int getLowerLimit() { |
| | | return lowerLimit; |
| | | } |
| | | |
| | | /** |
| | | * Get the upper limit. |
| | | * |
| | | * @return Returns the upper limit or <code>null</code> if there is no upper |
| | | * limit. |
| | | */ |
| | | public Integer getUpperLimit() { |
| | | return upperLimit; |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional unit synopsis of this integer property definition in |
| | | * the default locale. |
| | | * |
| | | * @return Returns the unit synopsis of this integer property definition in |
| | | * the default locale, or <code>null</code> if there is no unit |
| | | * synopsis. |
| | | */ |
| | | public LocalizableMessage getUnitSynopsis() { |
| | | return getUnitSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional unit synopsis of this integer property definition in |
| | | * the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the unit synopsis of this integer property definition in |
| | | * the specified locale, or <code>null</code> if there is no unit |
| | | * synopsis. |
| | | */ |
| | | public LocalizableMessage getUnitSynopsis(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "property." + getName() + ".syntax.integer.unit-synopsis"; |
| | | try { |
| | | return resource.getMessage(getManagedObjectDefinition(), property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Determine whether this property allows unlimited values. |
| | | * |
| | | * @return Returns <code>true</code> if this this property allows unlimited |
| | | * values. |
| | | */ |
| | | public boolean isAllowUnlimited() { |
| | | return allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(Integer value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | if (!allowUnlimited && value < lowerLimit) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | |
| | | // unlimited allowed |
| | | } else if (value >= 0 && value < lowerLimit) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | |
| | | if ((upperLimit != null) && (value > upperLimit)) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String encodeValue(Integer value) { |
| | | Reject.ifNull(value); |
| | | |
| | | // Make sure that we correctly encode negative values as "unlimited". |
| | | if (allowUnlimited) { |
| | | if (value < 0) { |
| | | return UNLIMITED; |
| | | } |
| | | } |
| | | |
| | | return value.toString(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Integer decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | if (allowUnlimited) { |
| | | if (value.trim().equalsIgnoreCase(UNLIMITED)) { |
| | | return -1; |
| | | } |
| | | } |
| | | |
| | | Integer i; |
| | | try { |
| | | i = Integer.valueOf(value); |
| | | } catch (NumberFormatException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | |
| | | try { |
| | | validateValue(i, options); |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | |
| | | return i; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitInteger(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, Integer value, P p) { |
| | | return v.visitInteger(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | super.toString(builder); |
| | | |
| | | builder.append(" lowerLimit="); |
| | | builder.append(lowerLimit); |
| | | |
| | | if (upperLimit != null) { |
| | | builder.append(" upperLimit="); |
| | | builder.append(upperLimit); |
| | | } |
| | | |
| | | builder.append(" allowUnlimited="); |
| | | builder.append(allowUnlimited); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(Integer o1, Integer o2) { |
| | | return o1.compareTo(o2); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Arrays; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.MissingResourceException; |
| | | import java.util.NoSuchElementException; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * This class is used to map configuration elements to their LDAP schema names. |
| | | * <p> |
| | | * It is possible to augment the core LDAP profile with additional profile |
| | | * mappings at run-time using instances of {@link Wrapper}. This is useful for |
| | | * unit tests which need to add and remove mock components. |
| | | */ |
| | | public final class LDAPProfile { |
| | | |
| | | /** |
| | | * LDAP profile wrappers can be used to provide temporary LDAP profile |
| | | * information for components which do not have LDAP profile property files. |
| | | * These components are typically "mock" components used in unit-tests. |
| | | */ |
| | | public static abstract class Wrapper { |
| | | |
| | | /** |
| | | * Default constructor. |
| | | */ |
| | | protected Wrapper() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Get the name of the LDAP attribute associated with the specified |
| | | * property definition. |
| | | * <p> |
| | | * The default implementation of this method is to return |
| | | * <code>null</code>. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param pd |
| | | * The property definition. |
| | | * @return Returns the name of the LDAP attribute associated with the |
| | | * specified property definition, or <code>null</code> if the |
| | | * property definition is not handled by this LDAP profile |
| | | * wrapper. |
| | | */ |
| | | public String getAttributeName(AbstractManagedObjectDefinition<?, ?> d, PropertyDefinition<?> pd) { |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * Gets the LDAP RDN attribute type for child entries of an instantiable |
| | | * relation. |
| | | * <p> |
| | | * The default implementation of this method is to return |
| | | * <code>null</code>. |
| | | * |
| | | * @param r |
| | | * The instantiable relation. |
| | | * @return Returns the LDAP RDN attribute type for child entries of an |
| | | * instantiable relation, or <code>null</code> if the |
| | | * instantiable relation is not handled by this LDAP profile |
| | | * wrapper. |
| | | */ |
| | | public String getRelationChildRDNType(InstantiableRelationDefinition<?, ?> r) { |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * Gets the LDAP RDN attribute type for child entries of an set |
| | | * relation. |
| | | * <p> |
| | | * The default implementation of this method is to return |
| | | * <code>null</code>. |
| | | * |
| | | * @param r |
| | | * The set relation. |
| | | * @return Returns the LDAP RDN attribute type for child entries of an |
| | | * set relation, or <code>null</code> if the set relation is not |
| | | * handled by this LDAP profile wrapper. |
| | | */ |
| | | public String getRelationChildRDNType(SetRelationDefinition<?, ?> r) { |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * Get the principle object class associated with the specified |
| | | * definition. |
| | | * <p> |
| | | * The default implementation of this method is to return |
| | | * <code>null</code>. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @return Returns the principle object class associated with the |
| | | * specified definition, or <code>null</code> if the managed |
| | | * object definition is not handled by this LDAP profile |
| | | * wrapper. |
| | | */ |
| | | public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) { |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * Get an LDAP RDN sequence associatied with a relation. |
| | | * <p> |
| | | * The default implementation of this method is to return |
| | | * <code>null</code>. |
| | | * |
| | | * @param r |
| | | * The relation. |
| | | * @return Returns the LDAP RDN sequence associatied with a relation, or |
| | | * <code>null</code> if the relation is not handled by this LDAP |
| | | * profile wrapper. |
| | | */ |
| | | public String getRelationRDNSequence(RelationDefinition<?, ?> r) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | // The singleton instance. |
| | | private static final LDAPProfile INSTANCE = new LDAPProfile(); |
| | | |
| | | /** |
| | | * Get the global LDAP profile instance. |
| | | * |
| | | * @return Returns the global LDAP profile instance. |
| | | */ |
| | | public static LDAPProfile getInstance() { |
| | | return INSTANCE; |
| | | } |
| | | |
| | | // The list of profile wrappers. |
| | | private final LinkedList<Wrapper> profiles = new LinkedList<Wrapper>();; |
| | | |
| | | // The LDAP profile property table. |
| | | private final ManagedObjectDefinitionResource resource = ManagedObjectDefinitionResource.createForProfile("ldap"); |
| | | |
| | | // Prevent construction. |
| | | private LDAPProfile() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Get the name of the LDAP attribute associated with the specified property |
| | | * definition. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param pd |
| | | * The property definition. |
| | | * @return Returns the name of the LDAP attribute associated with the |
| | | * specified property definition. |
| | | * @throws MissingResourceException |
| | | * If the LDAP profile properties file associated with the |
| | | * provided managed object definition could not be loaded. |
| | | */ |
| | | public String getAttributeName(AbstractManagedObjectDefinition<?, ?> d, PropertyDefinition<?> pd) { |
| | | for (Wrapper profile : profiles) { |
| | | String attributeName = profile.getAttributeName(d, pd); |
| | | if (attributeName != null) { |
| | | return attributeName; |
| | | } |
| | | } |
| | | return resource.getString(d, "attribute." + pd.getName()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the LDAP RDN attribute type for child entries of an instantiable |
| | | * relation. |
| | | * |
| | | * @param r |
| | | * The instantiable relation. |
| | | * @return Returns the LDAP RDN attribute type for child entries of an |
| | | * instantiable relation. |
| | | * @throws MissingResourceException |
| | | * If the LDAP profile properties file associated with the |
| | | * provided managed object definition could not be loaded. |
| | | */ |
| | | public String getRelationChildRDNType(InstantiableRelationDefinition<?, ?> r) { |
| | | if (r.getNamingPropertyDefinition() != null) { |
| | | // Use the attribute associated with the naming property. |
| | | return getAttributeName(r.getChildDefinition(), r.getNamingPropertyDefinition()); |
| | | } else { |
| | | for (Wrapper profile : profiles) { |
| | | String rdnType = profile.getRelationChildRDNType(r); |
| | | if (rdnType != null) { |
| | | return rdnType; |
| | | } |
| | | } |
| | | return resource.getString(r.getParentDefinition(), "naming-attribute." + r.getName()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the LDAP object classes associated with an instantiable or set |
| | | * relation branch. The branch is the parent entry of child managed objects. |
| | | * |
| | | * @param r |
| | | * The instantiable or set relation. |
| | | * @return Returns the LDAP object classes associated with an instantiable |
| | | * or set relation branch. |
| | | */ |
| | | public List<String> getRelationObjectClasses(RelationDefinition<?, ?> r) { |
| | | return Arrays.asList(new String[] { "top", "ds-cfg-branch" }); |
| | | } |
| | | |
| | | /** |
| | | * Gets the LDAP RDN attribute type for child entries of an set relation. |
| | | * |
| | | * @param r |
| | | * The set relation. |
| | | * @return Returns the LDAP RDN attribute type for child entries of an set |
| | | * relation. |
| | | * @throws MissingResourceException |
| | | * If the LDAP profile properties file associated with the |
| | | * provided managed object definition could not be loaded. |
| | | */ |
| | | public String getRelationChildRDNType(SetRelationDefinition<?, ?> r) { |
| | | for (Wrapper profile : profiles) { |
| | | String rdnType = profile.getRelationChildRDNType(r); |
| | | if (rdnType != null) { |
| | | return rdnType; |
| | | } |
| | | } |
| | | return resource.getString(r.getParentDefinition(), "naming-attribute." + r.getName()); |
| | | } |
| | | |
| | | /** |
| | | * Get the principle object class associated with the specified definition. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @return Returns the principle object class associated with the specified |
| | | * definition. |
| | | * @throws MissingResourceException |
| | | * If the LDAP profile properties file associated with the |
| | | * provided managed object definition could not be loaded. |
| | | */ |
| | | public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) { |
| | | if (d.isTop()) { |
| | | return "top"; |
| | | } |
| | | |
| | | for (Wrapper profile : profiles) { |
| | | String objectClass = profile.getObjectClass(d); |
| | | if (objectClass != null) { |
| | | return objectClass; |
| | | } |
| | | } |
| | | return resource.getString(d, "objectclass"); |
| | | } |
| | | |
| | | /** |
| | | * Get all the object classes associated with the specified definition. |
| | | * <p> |
| | | * The returned list is ordered such that the uppermost object classes |
| | | * appear first (e.g. top). |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @return Returns all the object classes associated with the specified |
| | | * definition. |
| | | * @throws MissingResourceException |
| | | * If the LDAP profile properties file associated with the |
| | | * provided managed object definition could not be loaded. |
| | | */ |
| | | public List<String> getObjectClasses(AbstractManagedObjectDefinition<?, ?> d) { |
| | | LinkedList<String> objectClasses = new LinkedList<String>(); |
| | | Set<String> s = new HashSet<String>(); |
| | | |
| | | // Add the object classes from the parent hierarchy. |
| | | while (d != null) { |
| | | String oc = getObjectClass(d); |
| | | if (!s.contains(oc)) { |
| | | objectClasses.addFirst(oc); |
| | | s.add(oc); |
| | | } |
| | | d = d.getParent(); |
| | | } |
| | | |
| | | if (!s.contains("top")) { |
| | | objectClasses.addFirst("top"); |
| | | } |
| | | |
| | | return objectClasses; |
| | | } |
| | | |
| | | /** |
| | | * Get an LDAP RDN sequence associatied with a relation. |
| | | * |
| | | * @param r |
| | | * The relation. |
| | | * @return Returns the LDAP RDN sequence associatied with a relation. |
| | | * @throws MissingResourceException |
| | | * If the LDAP profile properties file associated with the |
| | | * provided managed object definition could not be loaded. |
| | | */ |
| | | public String getRelationRDNSequence(RelationDefinition<?, ?> r) { |
| | | for (Wrapper profile : profiles) { |
| | | String rdnSequence = profile.getRelationRDNSequence(r); |
| | | if (rdnSequence != null) { |
| | | return rdnSequence; |
| | | } |
| | | } |
| | | return resource.getString(r.getParentDefinition(), "rdn." + r.getName()); |
| | | } |
| | | |
| | | /** |
| | | * Removes the last LDAP profile wrapper added using |
| | | * {@link #pushWrapper(org.forgerock.opendj.config.LDAPProfile.Wrapper)}. |
| | | * |
| | | * @throws NoSuchElementException |
| | | * If there are no LDAP profile wrappers. |
| | | */ |
| | | public void popWrapper() { |
| | | profiles.removeFirst(); |
| | | } |
| | | |
| | | /** |
| | | * Decorates the core LDAP profile with the provided LDAP profile wrapper. |
| | | * All profile requests will be directed to the provided wrapper before |
| | | * being forwarded onto the core profile if the request could not be |
| | | * satisfied. |
| | | * |
| | | * @param wrapper |
| | | * The LDAP profile wrapper. |
| | | */ |
| | | public void pushWrapper(Wrapper wrapper) { |
| | | profiles.addFirst(wrapper); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * A managed object could not be created because there is an existing managed |
| | | * object with the same name. |
| | | */ |
| | | public final class ManagedObjectAlreadyExistsException extends OperationsException { |
| | | |
| | | /** |
| | | * Version ID required by serializable classes. |
| | | */ |
| | | private static final long serialVersionUID = -2344653674171609366L; |
| | | |
| | | /** |
| | | * Create a managed object already exists exception. |
| | | */ |
| | | public ManagedObjectAlreadyExistsException() { |
| | | super(ERR_MANAGED_OBJECT_ALREADY_EXISTS_EXCEPTION.get()); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.opendj.config.client.ManagedObject; |
| | | import org.forgerock.opendj.config.server.ServerManagedObject; |
| | | |
| | | /** |
| | | * Defines the structure of a managed object which can be instantiated. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * definition represents. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * definition represents. |
| | | */ |
| | | public abstract class ManagedObjectDefinition<C extends ConfigurationClient, S extends Configuration> extends |
| | | AbstractManagedObjectDefinition<C, S> { |
| | | |
| | | /** |
| | | * Create a new managed object definition. |
| | | * |
| | | * @param name |
| | | * The name of the definition. |
| | | * @param parent |
| | | * The parent definition, or <code>null</code> if there is no |
| | | * parent. |
| | | */ |
| | | protected ManagedObjectDefinition(String name, AbstractManagedObjectDefinition<? super C, ? super S> parent) { |
| | | super(name, parent); |
| | | } |
| | | |
| | | /** |
| | | * Creates a client configuration view of the provided managed object. |
| | | * Modifications made to the underlying managed object will be reflected in |
| | | * the client configuration view and vice versa. |
| | | * |
| | | * @param managedObject |
| | | * The managed object. |
| | | * @return Returns a client configuration view of the provided managed |
| | | * object. |
| | | */ |
| | | public abstract C createClientConfiguration(ManagedObject<? extends C> managedObject); |
| | | |
| | | /** |
| | | * Creates a server configuration view of the provided server managed |
| | | * object. |
| | | * |
| | | * @param managedObject |
| | | * The server managed object. |
| | | * @return Returns a server configuration view of the provided server |
| | | * managed object. |
| | | */ |
| | | public abstract S createServerConfiguration(ServerManagedObject<? extends S> managedObject); |
| | | |
| | | /** |
| | | * Gets the server configuration class instance associated with this managed |
| | | * object definition. |
| | | * |
| | | * @return Returns the server configuration class instance associated with |
| | | * this managed object definition. |
| | | */ |
| | | public abstract Class<S> getServerConfigurationClass(); |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.MissingResourceException; |
| | | import java.util.ResourceBundle; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * A class for retrieving internationalized resource properties associated with |
| | | * a managed object definition. |
| | | * <p> |
| | | * I18N resource properties are not available for the {@link TopCfgDefn}. |
| | | */ |
| | | public final class ManagedObjectDefinitionI18NResource { |
| | | |
| | | // Application-wide set of instances. |
| | | private static final Map<String, ManagedObjectDefinitionI18NResource> INSTANCES = |
| | | new HashMap<String, ManagedObjectDefinitionI18NResource>(); |
| | | |
| | | /** |
| | | * Gets the internationalized resource instance which can be used to |
| | | * retrieve the localized descriptions for the managed objects and their |
| | | * associated properties and relations. |
| | | * |
| | | * @return Returns the I18N resource instance. |
| | | */ |
| | | public static ManagedObjectDefinitionI18NResource getInstance() { |
| | | return getInstance("config.messages"); |
| | | } |
| | | |
| | | /** |
| | | * Gets the internationalized resource instance for the named profile. |
| | | * |
| | | * @param profile |
| | | * The name of the profile. |
| | | * @return Returns the I18N resource instance for the named profile. |
| | | */ |
| | | public static ManagedObjectDefinitionI18NResource getInstanceForProfile(String profile) { |
| | | return getInstance("config.profiles." + profile); |
| | | } |
| | | |
| | | // Get a resource instance creating it if necessary. |
| | | private synchronized static ManagedObjectDefinitionI18NResource getInstance(String prefix) { |
| | | ManagedObjectDefinitionI18NResource instance = INSTANCES.get(prefix); |
| | | |
| | | if (instance == null) { |
| | | instance = new ManagedObjectDefinitionI18NResource(prefix); |
| | | INSTANCES.put(prefix, instance); |
| | | } |
| | | |
| | | return instance; |
| | | } |
| | | |
| | | // Mapping from definition to locale-based resource bundle. |
| | | private final Map<AbstractManagedObjectDefinition<?, ?>, Map<Locale, ResourceBundle>> resources; |
| | | |
| | | // The resource name prefix. |
| | | private final String prefix; |
| | | |
| | | // Private constructor. |
| | | private ManagedObjectDefinitionI18NResource(String prefix) { |
| | | this.resources = new HashMap<AbstractManagedObjectDefinition<?, ?>, Map<Locale, ResourceBundle>>(); |
| | | this.prefix = prefix; |
| | | } |
| | | |
| | | /** |
| | | * Get the internationalized message associated with the specified key in |
| | | * the default locale. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param key |
| | | * The resource key. |
| | | * @return Returns the internationalized message associated with the |
| | | * specified key in the default locale. |
| | | * @throws MissingResourceException |
| | | * If the key was not found. |
| | | * @throws UnsupportedOperationException |
| | | * If the provided managed object definition was the |
| | | * {@link TopCfgDefn}. |
| | | */ |
| | | public LocalizableMessage getMessage(AbstractManagedObjectDefinition<?, ?> d, String key) { |
| | | return getMessage(d, key, Locale.getDefault(), (String[]) null); |
| | | } |
| | | |
| | | /** |
| | | * Get the internationalized message associated with the specified key and |
| | | * locale. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param key |
| | | * The resource key. |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the internationalized message associated with the |
| | | * specified key and locale. |
| | | * @throws MissingResourceException |
| | | * If the key was not found. |
| | | * @throws UnsupportedOperationException |
| | | * If the provided managed object definition was the |
| | | * {@link TopCfgDefn}. |
| | | */ |
| | | public LocalizableMessage getMessage(AbstractManagedObjectDefinition<?, ?> d, String key, Locale locale) { |
| | | return getMessage(d, key, locale, (String[]) null); |
| | | } |
| | | |
| | | /** |
| | | * Get the parameterized internationalized message associated with the |
| | | * specified key and locale. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param key |
| | | * The resource key. |
| | | * @param locale |
| | | * The locale. |
| | | * @param args |
| | | * Arguments that should be inserted into the retrieved message. |
| | | * @return Returns the internationalized message associated with the |
| | | * specified key and locale. |
| | | * @throws MissingResourceException |
| | | * If the key was not found. |
| | | * @throws UnsupportedOperationException |
| | | * If the provided managed object definition was the |
| | | * {@link TopCfgDefn}. |
| | | */ |
| | | public LocalizableMessage getMessage(AbstractManagedObjectDefinition<?, ?> d, String key, Locale locale, |
| | | String... args) { |
| | | ResourceBundle resource = getResourceBundle(d, locale); |
| | | |
| | | // TODO: use message framework directly |
| | | if (args == null) { |
| | | return LocalizableMessage.raw(resource.getString(key)); |
| | | } else { |
| | | return LocalizableMessage.raw(resource.getString(key), (Object[]) args); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the parameterized internationalized message associated with the |
| | | * specified key in the default locale. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param key |
| | | * The resource key. |
| | | * @param args |
| | | * Arguments that should be inserted into the retrieved message. |
| | | * @return Returns the internationalized message associated with the |
| | | * specified key in the default locale. |
| | | * @throws MissingResourceException |
| | | * If the key was not found. |
| | | * @throws UnsupportedOperationException |
| | | * If the provided managed object definition was the |
| | | * {@link TopCfgDefn}. |
| | | */ |
| | | public LocalizableMessage getMessage(AbstractManagedObjectDefinition<?, ?> d, String key, String... args) { |
| | | return getMessage(d, key, Locale.getDefault(), args); |
| | | } |
| | | |
| | | /** |
| | | * Forcefully removes any resource bundles associated with the provided |
| | | * definition and using the default locale. |
| | | * <p> |
| | | * This method is intended for internal testing only. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | */ |
| | | synchronized void removeResourceBundle(AbstractManagedObjectDefinition<?, ?> d) { |
| | | removeResourceBundle(d, Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Forcefully removes any resource bundles associated with the provided |
| | | * definition and locale. |
| | | * <p> |
| | | * This method is intended for internal testing only. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param locale |
| | | * The locale. |
| | | */ |
| | | synchronized void removeResourceBundle(AbstractManagedObjectDefinition<?, ?> d, Locale locale) { |
| | | // Get the locale resource mapping. |
| | | Map<Locale, ResourceBundle> map = resources.get(d); |
| | | if (map != null) { |
| | | map.remove(locale); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Forcefully adds the provided resource bundle to this I18N resource for |
| | | * the default locale. |
| | | * <p> |
| | | * This method is intended for internal testing only. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param resoureBundle |
| | | * The resource bundle to be used. |
| | | */ |
| | | synchronized void setResourceBundle(AbstractManagedObjectDefinition<?, ?> d, ResourceBundle resoureBundle) { |
| | | setResourceBundle(d, Locale.getDefault(), resoureBundle); |
| | | } |
| | | |
| | | /** |
| | | * Forcefully adds the provided resource bundle to this I18N resource. |
| | | * <p> |
| | | * This method is intended for internal testing only. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param locale |
| | | * The locale. |
| | | * @param resoureBundle |
| | | * The resource bundle to be used. |
| | | */ |
| | | synchronized void setResourceBundle(AbstractManagedObjectDefinition<?, ?> d, Locale locale, |
| | | ResourceBundle resoureBundle) { |
| | | // First get the locale-resource mapping, creating it if |
| | | // necessary. |
| | | Map<Locale, ResourceBundle> map = resources.get(d); |
| | | if (map == null) { |
| | | map = new HashMap<Locale, ResourceBundle>(); |
| | | resources.put(d, map); |
| | | } |
| | | |
| | | // Add the resource bundle. |
| | | map.put(locale, resoureBundle); |
| | | } |
| | | |
| | | // Retrieve the resource bundle associated with a managed object and |
| | | // locale, lazily loading it if necessary. |
| | | private synchronized ResourceBundle getResourceBundle(AbstractManagedObjectDefinition<?, ?> d, Locale locale) { |
| | | if (d.isTop()) { |
| | | throw new UnsupportedOperationException("I18n resources are not available for the " |
| | | + "Top configuration definition"); |
| | | } |
| | | |
| | | // First get the locale-resource mapping, creating it if |
| | | // necessary. |
| | | Map<Locale, ResourceBundle> map = resources.get(d); |
| | | if (map == null) { |
| | | map = new HashMap<Locale, ResourceBundle>(); |
| | | resources.put(d, map); |
| | | } |
| | | |
| | | // Now get the resource based on the locale, loading it if |
| | | // necessary. |
| | | ResourceBundle resourceBundle = map.get(locale); |
| | | if (resourceBundle == null) { |
| | | String baseName = prefix + "." + d.getClass().getName(); |
| | | resourceBundle = |
| | | ResourceBundle.getBundle(baseName, locale, ClassLoaderProvider.getInstance().getClassLoader()); |
| | | map.put(locale, resourceBundle); |
| | | } |
| | | |
| | | return resourceBundle; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.io.BufferedInputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.MissingResourceException; |
| | | import java.util.Properties; |
| | | |
| | | /** |
| | | * A class for retrieving non-internationalized resource properties associated |
| | | * with a managed object definition. |
| | | * <p> |
| | | * Resource properties are not available for the {@link TopCfgDefn}. |
| | | */ |
| | | public final class ManagedObjectDefinitionResource { |
| | | |
| | | // Mapping from definition to property tables. |
| | | private final Map<AbstractManagedObjectDefinition<?, ?>, Properties> properties; |
| | | |
| | | // The resource name prefix. |
| | | private final String prefix; |
| | | |
| | | /** |
| | | * Creates a new resource instance for the named profile. |
| | | * |
| | | * @param profile |
| | | * The name of the profile. |
| | | * @return Returns the resource instance for the named profile. |
| | | */ |
| | | public static ManagedObjectDefinitionResource createForProfile(String profile) { |
| | | return new ManagedObjectDefinitionResource("config.profiles." + profile); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private ManagedObjectDefinitionResource(String prefix) { |
| | | this.properties = new HashMap<AbstractManagedObjectDefinition<?, ?>, Properties>(); |
| | | this.prefix = prefix; |
| | | } |
| | | |
| | | /** |
| | | * Get the resource value associated with the specified key. |
| | | * |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param key |
| | | * The resource key. |
| | | * @return Returns the resource value associated with the specified key. |
| | | * @throws MissingResourceException |
| | | * If the key was not found. |
| | | * @throws UnsupportedOperationException |
| | | * If the provided managed object definition was the |
| | | * {@link TopCfgDefn}. |
| | | */ |
| | | public String getString(AbstractManagedObjectDefinition<?, ?> d, String key) { |
| | | if (d.isTop()) { |
| | | throw new UnsupportedOperationException("Profile resources are not available for the " |
| | | + "Top configuration definition"); |
| | | } |
| | | |
| | | Properties p = getProperties(d); |
| | | String result = p.getProperty(key); |
| | | |
| | | if (result == null) { |
| | | String baseName = prefix + "." + d.getClass().getName(); |
| | | String path = baseName.replace('.', '/') + ".properties"; |
| | | |
| | | throw new MissingResourceException("Can't find resource " + path + ", key " + key, baseName, key); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | // Retrieve the properties table associated with a managed object, |
| | | // lazily loading it if necessary. |
| | | private synchronized Properties getProperties(AbstractManagedObjectDefinition<?, ?> d) { |
| | | Properties p = properties.get(d); |
| | | |
| | | if (p == null) { |
| | | // Load the resource file. |
| | | String baseName = prefix + "." + d.getClass().getName(); |
| | | String path = baseName.replace('.', '/') + ".properties"; |
| | | InputStream stream = ClassLoaderProvider.getInstance().getClassLoader().getResourceAsStream(path); |
| | | |
| | | if (stream == null) { |
| | | throw new MissingResourceException("Can't find resource " + path, baseName, ""); |
| | | } |
| | | |
| | | p = new Properties(); |
| | | try { |
| | | p.load(new BufferedInputStream(stream)); |
| | | } catch (IOException e) { |
| | | throw new MissingResourceException("Can't load resource " + path + " due to IO exception: " |
| | | + e.getMessage(), baseName, ""); |
| | | } |
| | | |
| | | // Cache the resource. |
| | | properties.put(d, p); |
| | | } |
| | | |
| | | return p; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * The requested managed object could not be located. |
| | | */ |
| | | public class ManagedObjectNotFoundException extends OperationsException { |
| | | |
| | | /** |
| | | * Version ID required by serializable classes. |
| | | */ |
| | | private static final long serialVersionUID = -477551786551892978L; |
| | | |
| | | /** |
| | | * Create a managed object not found exception. |
| | | */ |
| | | public ManagedObjectNotFoundException() { |
| | | super(ERR_MANAGED_OBJECT_NOT_FOUND_EXCEPTION.get()); |
| | | } |
| | | |
| | | /** |
| | | * Create a managed object not found exception with the specified cause. |
| | | * |
| | | * @param cause |
| | | * The cause of this exception. |
| | | */ |
| | | public ManagedObjectNotFoundException(Throwable cause) { |
| | | super(ERR_MANAGED_OBJECT_NOT_FOUND_EXCEPTION.get(), cause); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * This enumeration contains various options that can be associated with managed |
| | | * object definitions. |
| | | */ |
| | | public enum ManagedObjectOption { |
| | | /** |
| | | * Use this option to identify managed object types which should be |
| | | * considered as advanced and should not be exposed by default in client |
| | | * applications. |
| | | */ |
| | | ADVANCED, |
| | | |
| | | /** |
| | | * Use this option to identify managed object types which must not be |
| | | * directly exposed in client applications. |
| | | */ |
| | | HIDDEN; |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011 ForgeRock AS |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | import org.forgerock.opendj.server.config.client.RootCfgClient; |
| | | import org.forgerock.opendj.server.config.meta.RootCfgDefn; |
| | | import org.forgerock.opendj.server.config.server.RootCfg; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.RDN; |
| | | import org.forgerock.opendj.ldap.schema.AttributeType; |
| | | import org.opends.server.core.DirectoryServer; |
| | | |
| | | /** |
| | | * A path which can be used to determine the location of a managed object |
| | | * instance. |
| | | * <p> |
| | | * A path is made up of zero or more elements each of which represents a managed |
| | | * object. Managed objects are arranged hierarchically with the root |
| | | * configuration being the top-most managed object. Elements are ordered such |
| | | * that the root configuration managed object is the first element and |
| | | * subsequent elements representing managed objects further down the hierarchy. |
| | | * <p> |
| | | * A path can be encoded into a string representation using the |
| | | * {@link #toString()} and {@link #toString(StringBuilder)} methods. Conversely, |
| | | * this string representation can be parsed using the {@link #valueOf(String)} |
| | | * method. |
| | | * <p> |
| | | * The string representation of a managed object path is similar in principle to |
| | | * a UNIX file-system path and is defined as follows: |
| | | * <ul> |
| | | * <li>the root element is represented by the string <code>/</code> |
| | | * <li>subordinate elements are arranged in big-endian order separated by a |
| | | * forward slash <code>/</code> character |
| | | * <li>an element representing a managed object associated with a one-to-one |
| | | * (singleton) or one-to-zero-or-one (optional) relation has the form |
| | | * <code>relation=</code><i>relation</i> <code>[+type=</code><i>definition</i> |
| | | * <code>]</code>, where <i>relation</i> is the name of the relation and |
| | | * <i>definition</i> is the name of the referenced managed object's definition |
| | | * if required (usually this is implied by the relation itself) |
| | | * <li>an element representing a managed object associated with a one-to-many |
| | | * (instantiable) relation has the form <code>relation=</code><i>relation</i> |
| | | * <code>[+type=</code> <i>definition</i><code>]</code><code>+name=</code> |
| | | * <i>name</i>, where <i>relation</i> is the name of the relation and |
| | | * <i>definition</i> is the name of the referenced managed object's definition |
| | | * if required (usually this is implied by the relation itself), and <i>name</i> |
| | | * is the name of the managed object instance |
| | | * <li>an element representing a managed object associated with a one-to-many |
| | | * (set) relation has the form <code>relation=</code><i>relation</i> |
| | | * <code>[+type=</code> <i>definition</i><code>]</code>, where <i>relation</i> |
| | | * is the name of the relation and <i>definition</i> is the name of the |
| | | * referenced managed object's definition. |
| | | * </ul> |
| | | * The following path string representation identifies a connection handler |
| | | * instance (note that the <code>type</code> is not specified indicating that |
| | | * the path identifies a connection handler called <i>my handler</i> which can |
| | | * be any type of connection handler): |
| | | * |
| | | * <pre> |
| | | * /relation=connection-handler+name=my handler |
| | | * </pre> |
| | | * |
| | | * If the identified connection handler must be an LDAP connection handler then |
| | | * the above path should include the <code>type</code>: |
| | | * |
| | | * <pre> |
| | | * /relation=connection-handler+type=ldap-connection-handler+name=my handler |
| | | * </pre> |
| | | * |
| | | * The final example identifies the global configuration: |
| | | * |
| | | * <pre> |
| | | * /relation=global-configuration |
| | | * </pre> |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this path |
| | | * references. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this path |
| | | * references. |
| | | */ |
| | | public final class ManagedObjectPath<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | /** |
| | | * A serialize which is used to generate the toDN representation. |
| | | */ |
| | | private static final class DNSerializer implements ManagedObjectPathSerializer { |
| | | |
| | | // The current DN. |
| | | private DN dn; |
| | | |
| | | // The LDAP profile. |
| | | private final LDAPProfile profile; |
| | | |
| | | // Create a new DN builder. |
| | | private DNSerializer() { |
| | | this.dn = DN.rootDN(); |
| | | this.profile = LDAPProfile.getInstance(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | InstantiableRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d, |
| | | String name) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement(r); |
| | | |
| | | // Now add the single RDN representing the named instance. |
| | | String type = profile.getRelationChildRDNType(r); |
| | | AttributeType attrType = DirectoryServer.getAttributeType(type.toLowerCase(), true); |
| | | dn = dn.child(new RDN(attrType, name)); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | SetRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement(r); |
| | | |
| | | // Now add the single RDN representing the instance. |
| | | String type = profile.getRelationChildRDNType(r); |
| | | AttributeType attrType = DirectoryServer.getAttributeType(type.toLowerCase(), true); |
| | | dn = dn.child(new RDN(attrType, d.getName())); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | OptionalRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement(r); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | SingletonRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement(r); |
| | | } |
| | | |
| | | // Appends the RDN sequence representing the provided relation. |
| | | private void appendManagedObjectPathElement(RelationDefinition<?, ?> r) { |
| | | DN localName = DN.valueOf(profile.getRelationRDNSequence(r)); |
| | | dn = dn.child(localName); |
| | | } |
| | | |
| | | // Gets the serialized DN value. |
| | | private DN toDN() { |
| | | return dn; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Abstract path element. |
| | | */ |
| | | private static abstract class Element<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | // The type of managed object referenced by this element. |
| | | private final AbstractManagedObjectDefinition<C, S> definition; |
| | | |
| | | /** |
| | | * Protected constructor. |
| | | * |
| | | * @param definition |
| | | * The type of managed object referenced by this element. |
| | | */ |
| | | protected Element(AbstractManagedObjectDefinition<C, S> definition) { |
| | | this.definition = definition; |
| | | } |
| | | |
| | | /** |
| | | * Get the managed object definition associated with this element. |
| | | * |
| | | * @return Returns the managed object definition associated with this |
| | | * element. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<C, S> getManagedObjectDefinition() { |
| | | return definition; |
| | | } |
| | | |
| | | /** |
| | | * 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 element. |
| | | */ |
| | | public abstract RelationDefinition<? super C, ? super S> getRelationDefinition(); |
| | | |
| | | /** |
| | | * Serialize this path element using the provided serialization |
| | | * strategy. |
| | | * |
| | | * @param serializer |
| | | * The managed object path serialization strategy. |
| | | */ |
| | | public abstract void serialize(ManagedObjectPathSerializer serializer); |
| | | } |
| | | |
| | | /** |
| | | * A path element representing an instantiable managed object. |
| | | */ |
| | | private static final class InstantiableElement<C extends ConfigurationClient, S extends Configuration> extends |
| | | Element<C, S> { |
| | | |
| | | // Factory method. |
| | | private static final <C extends ConfigurationClient, S extends Configuration> InstantiableElement<C, S> create( |
| | | InstantiableRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d, |
| | | String name) { |
| | | return new InstantiableElement<C, S>(r, d, name); |
| | | } |
| | | |
| | | // The name of the managed object. |
| | | private final String name; |
| | | |
| | | // The instantiable relation. |
| | | private final InstantiableRelationDefinition<? super C, ? super S> r; |
| | | |
| | | // Private constructor. |
| | | private InstantiableElement(InstantiableRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d, String name) { |
| | | super(d); |
| | | this.r = r; |
| | | this.name = name; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public InstantiableRelationDefinition<? super C, ? super S> getRelationDefinition() { |
| | | return r; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void serialize(ManagedObjectPathSerializer serializer) { |
| | | serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition(), name); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * A path element representing an optional managed object. |
| | | */ |
| | | private static final class OptionalElement<C extends ConfigurationClient, S extends Configuration> extends |
| | | Element<C, S> { |
| | | |
| | | // Factory method. |
| | | private static final <C extends ConfigurationClient, S extends Configuration> OptionalElement<C, S> create( |
| | | OptionalRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | return new OptionalElement<C, S>(r, d); |
| | | } |
| | | |
| | | // The optional relation. |
| | | private final OptionalRelationDefinition<? super C, ? super S> r; |
| | | |
| | | // Private constructor. |
| | | private OptionalElement(OptionalRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | super(d); |
| | | this.r = r; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public OptionalRelationDefinition<? super C, ? super S> getRelationDefinition() { |
| | | return r; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void serialize(ManagedObjectPathSerializer serializer) { |
| | | serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * A path element representing an set managed object. |
| | | */ |
| | | private static final class SetElement<C extends ConfigurationClient, S extends Configuration> extends |
| | | Element<C, S> { |
| | | |
| | | // Factory method. |
| | | private static final <C extends ConfigurationClient, S extends Configuration> SetElement<C, S> create( |
| | | SetRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | return new SetElement<C, S>(r, d); |
| | | } |
| | | |
| | | // The set relation. |
| | | private final SetRelationDefinition<? super C, ? super S> r; |
| | | |
| | | // Private constructor. |
| | | private SetElement(SetRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | super(d); |
| | | this.r = r; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public SetRelationDefinition<? super C, ? super S> getRelationDefinition() { |
| | | return r; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void serialize(ManagedObjectPathSerializer serializer) { |
| | | serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * A path element representing a singleton managed object. |
| | | */ |
| | | private static final class SingletonElement<C extends ConfigurationClient, S extends Configuration> extends |
| | | Element<C, S> { |
| | | |
| | | // Factory method. |
| | | private static final <C extends ConfigurationClient, S extends Configuration> SingletonElement<C, S> create( |
| | | SingletonRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | return new SingletonElement<C, S>(r, d); |
| | | } |
| | | |
| | | // The singleton relation. |
| | | private final SingletonRelationDefinition<? super C, ? super S> r; |
| | | |
| | | // Private constructor. |
| | | private SingletonElement(SingletonRelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | super(d); |
| | | this.r = r; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public SingletonRelationDefinition<? super C, ? super S> getRelationDefinition() { |
| | | return r; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void serialize(ManagedObjectPathSerializer serializer) { |
| | | serializer.appendManagedObjectPathElement(r, getManagedObjectDefinition()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * A serialize which is used to generate the toString representation. |
| | | */ |
| | | private static final class StringSerializer implements ManagedObjectPathSerializer { |
| | | |
| | | // Serialize to this string builder. |
| | | private final StringBuilder builder; |
| | | |
| | | // Private constructor. |
| | | private StringSerializer(StringBuilder builder) { |
| | | this.builder = builder; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> void appendManagedObjectPathElement( |
| | | InstantiableRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d, |
| | | String name) { |
| | | serializeElement(r, d); |
| | | |
| | | // Be careful to escape any forward slashes in the name. |
| | | builder.append("+name="); |
| | | builder.append(name.replace("/", "//")); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> void appendManagedObjectPathElement( |
| | | OptionalRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) { |
| | | serializeElement(r, d); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> void appendManagedObjectPathElement( |
| | | SingletonRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) { |
| | | serializeElement(r, d); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> void appendManagedObjectPathElement( |
| | | SetRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) { |
| | | serializeElement(r, d); |
| | | } |
| | | |
| | | // Common element serialization. |
| | | private <M, N> void serializeElement(RelationDefinition<?, ?> r, AbstractManagedObjectDefinition<?, ?> d) { |
| | | // Always specify the relation name. |
| | | builder.append("/relation="); |
| | | builder.append(r.getName()); |
| | | |
| | | // Only specify the type if it is a sub-type of the relation's |
| | | // type. |
| | | if (r.getChildDefinition() != d) { |
| | | builder.append("+type="); |
| | | builder.append(d.getName()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Single instance of a root path. |
| | | private static final ManagedObjectPath<RootCfgClient, RootCfg> EMPTY_PATH = |
| | | new ManagedObjectPath<RootCfgClient, RootCfg>(new LinkedList<Element<?, ?>>(), null, |
| | | RootCfgDefn.getInstance()); |
| | | |
| | | // A regular expression used to parse path elements. |
| | | private static final Pattern PE_REGEXP = Pattern.compile("^\\s*relation=\\s*([^+]+)\\s*" |
| | | + "(\\+\\s*type=\\s*([^+]+)\\s*)?" + "(\\+\\s*name=\\s*([^+]+)\\s*)?$"); |
| | | |
| | | /** |
| | | * Creates a new managed object path representing the configuration root. |
| | | * |
| | | * @return Returns a new managed object path representing the configuration |
| | | * root. |
| | | */ |
| | | public static ManagedObjectPath<RootCfgClient, RootCfg> emptyPath() { |
| | | return EMPTY_PATH; |
| | | } |
| | | |
| | | /** |
| | | * Returns a managed object path holding the value of the specified string. |
| | | * |
| | | * @param s |
| | | * The string to be parsed. |
| | | * @return Returns a managed object path holding the value of the specified |
| | | * string. |
| | | * @throws IllegalArgumentException |
| | | * If the string could not be parsed. |
| | | */ |
| | | public static ManagedObjectPath<?, ?> valueOf(String s) { |
| | | String ns = s.trim(); |
| | | |
| | | // Check for root special case. |
| | | if (ns.equals("/")) { |
| | | return EMPTY_PATH; |
| | | } |
| | | |
| | | // Parse the elements. |
| | | LinkedList<Element<?, ?>> elements = new LinkedList<Element<?, ?>>(); |
| | | Element<?, ?> lastElement = null; |
| | | AbstractManagedObjectDefinition<?, ?> definition = RootCfgDefn.getInstance(); |
| | | |
| | | if (!ns.startsWith("/")) { |
| | | throw new IllegalArgumentException("Invalid path \"" + ns + "\": must begin with a \"/\""); |
| | | } |
| | | |
| | | int start = 1; |
| | | while (true) { |
| | | // Get the next path element. |
| | | int end; |
| | | for (end = start; end < ns.length(); end++) { |
| | | char c = ns.charAt(end); |
| | | if (c == '/') { |
| | | if (end == (ns.length() - 1)) { |
| | | throw new IllegalArgumentException("Invalid path \"" + ns |
| | | + "\": must not end with a trailing \"/\""); |
| | | } |
| | | |
| | | if (ns.charAt(end + 1) == '/') { |
| | | // Found an escaped forward slash. |
| | | end++; |
| | | } else { |
| | | // Found the end of this path element. |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Get the next element. |
| | | String es = ns.substring(start, end); |
| | | |
| | | Matcher m = PE_REGEXP.matcher(es); |
| | | if (!m.matches()) { |
| | | throw new IllegalArgumentException("Invalid path element \"" + es + "\" in path \"" + ns + "\""); |
| | | } |
| | | |
| | | // Mandatory. |
| | | String relation = m.group(1); |
| | | |
| | | // Optional. |
| | | String type = m.group(3); |
| | | |
| | | // Mandatory if relation is instantiable. |
| | | String name = m.group(5); |
| | | |
| | | // Get the relation definition. |
| | | RelationDefinition<?, ?> r; |
| | | try { |
| | | r = definition.getRelationDefinition(relation); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new IllegalArgumentException("Invalid path element \"" + es + "\" in path \"" + ns |
| | | + "\": unknown relation \"" + relation + "\""); |
| | | } |
| | | |
| | | // Append the next element. |
| | | lastElement = createElement(r, ns, es, type, name); |
| | | elements.add(lastElement); |
| | | definition = lastElement.getManagedObjectDefinition(); |
| | | |
| | | // Update start to point to the beginning of the next element. |
| | | if (end < ns.length()) { |
| | | // Skip to the beginning of the next element |
| | | start = end + 1; |
| | | } else { |
| | | // We reached the end of the string. |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // Construct the new path. |
| | | return create(elements, lastElement); |
| | | } |
| | | |
| | | // Factory method required in order to allow generic wild-card |
| | | // construction of new paths. |
| | | private static <C extends ConfigurationClient, S extends Configuration> ManagedObjectPath<C, S> create( |
| | | LinkedList<Element<?, ?>> elements, Element<C, S> lastElement) { |
| | | return new ManagedObjectPath<C, S>(elements, lastElement.getRelationDefinition(), |
| | | lastElement.getManagedObjectDefinition()); |
| | | } |
| | | |
| | | // Decode an element. |
| | | // @Checkstyle:ignore |
| | | private static <C extends ConfigurationClient, S extends Configuration> Element<? extends C, ? extends S> createElement( |
| | | RelationDefinition<C, S> r, String path, String element, String type, String name) { |
| | | // First determine the managed object definition. |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d = null; |
| | | |
| | | if (type != null) { |
| | | for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : r.getChildDefinition() |
| | | .getAllChildren()) { |
| | | if (child.getName().equals(type)) { |
| | | d = child; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (d == null) { |
| | | throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path |
| | | + "\": unknown sub-type \"" + type + "\""); |
| | | } |
| | | } else { |
| | | d = r.getChildDefinition(); |
| | | } |
| | | |
| | | if (r instanceof InstantiableRelationDefinition) { |
| | | InstantiableRelationDefinition<C, S> ir = (InstantiableRelationDefinition<C, S>) r; |
| | | |
| | | if (name == null) { |
| | | throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path |
| | | + "\": no instance name for instantiable relation"); |
| | | } |
| | | |
| | | return InstantiableElement.create(ir, d, name); |
| | | } else if (r instanceof SetRelationDefinition) { |
| | | SetRelationDefinition<C, S> ir = (SetRelationDefinition<C, S>) r; |
| | | |
| | | if (name != null) { |
| | | throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path |
| | | + "\": instance name specified for set relation"); |
| | | } |
| | | |
| | | return SetElement.create(ir, d); |
| | | } else if (r instanceof OptionalRelationDefinition) { |
| | | OptionalRelationDefinition<C, S> or = (OptionalRelationDefinition<C, S>) r; |
| | | |
| | | if (name != null) { |
| | | throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path |
| | | + "\": instance name specified for optional relation"); |
| | | } |
| | | |
| | | return OptionalElement.create(or, d); |
| | | } else if (r instanceof SingletonRelationDefinition) { |
| | | SingletonRelationDefinition<C, S> sr = (SingletonRelationDefinition<C, S>) r; |
| | | |
| | | if (name != null) { |
| | | throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path |
| | | + "\": instance name specified for singleton relation"); |
| | | } |
| | | |
| | | return SingletonElement.create(sr, d); |
| | | } else { |
| | | throw new IllegalArgumentException("Invalid path element \"" + element + "\" in path \"" + path |
| | | + "\": unsupported relation type"); |
| | | } |
| | | } |
| | | |
| | | // The managed object definition in this path. |
| | | private final AbstractManagedObjectDefinition<C, S> d; |
| | | |
| | | // The list of path elements in this path. |
| | | private final List<Element<?, ?>> elements; |
| | | |
| | | // The last relation definition in this path. |
| | | private final RelationDefinition<? super C, ? super S> r; |
| | | |
| | | // Private constructor. |
| | | private ManagedObjectPath(LinkedList<Element<?, ?>> elements, RelationDefinition<? super C, ? super S> r, |
| | | AbstractManagedObjectDefinition<C, S> d) { |
| | | this.elements = Collections.unmodifiableList(elements); |
| | | this.r = r; |
| | | this.d = d; |
| | | } |
| | | |
| | | /** |
| | | * 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 <C1> |
| | | * The type of client managed object configuration that this path |
| | | * will reference. |
| | | * @param <S1> |
| | | * 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. |
| | | */ |
| | | // @Checkstyle:ignore |
| | | public <C1 extends C, S1 extends S> ManagedObjectPath<C1, S1> asSubType(AbstractManagedObjectDefinition<C1, S1> 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 SetRelationDefinition) { |
| | | SetRelationDefinition<? super C, ? super S> sr = (SetRelationDefinition<? super C, ? super S>) r; |
| | | return parent().child(sr, nd); |
| | | } 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. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the child |
| | | * path references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the child |
| | | * path references. |
| | | * @param r |
| | | * The instantiable relation referencing the child. |
| | | * @param d |
| | | * The managed object definition associated with the child (must |
| | | * be a sub-type of the relation). |
| | | * @param name |
| | | * The relative name of the child managed object. |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | * @throws IllegalArgumentException |
| | | * If the provided name is empty or blank. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child( |
| | | InstantiableRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d, String name) { |
| | | if (name.trim().length() == 0) { |
| | | throw new IllegalArgumentException("Empty or blank managed object names are not allowed"); |
| | | } |
| | | LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements); |
| | | celements.add(new InstantiableElement<M, N>(r, d, name)); |
| | | return new ManagedObjectPath<M, N>(celements, r, d); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new child managed object path beneath the provided parent path |
| | | * using the relation's child managed object definition. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the child |
| | | * path references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the child |
| | | * path references. |
| | | * @param r |
| | | * The instantiable relation referencing the child. |
| | | * @param name |
| | | * The relative name of the child managed object. |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | * @throws IllegalArgumentException |
| | | * If the provided name is empty or blank. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child( |
| | | InstantiableRelationDefinition<M, N> r, String name) { |
| | | return child(r, r.getChildDefinition(), name); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new child managed object path beneath the provided parent path |
| | | * having the specified managed object definition. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the child |
| | | * path references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the child |
| | | * path references. |
| | | * @param r |
| | | * The optional relation referencing the child. |
| | | * @param d |
| | | * The managed object definition associated with the child (must |
| | | * be a sub-type of the relation). |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child( |
| | | OptionalRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) { |
| | | LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements); |
| | | celements.add(new OptionalElement<M, N>(r, d)); |
| | | return new ManagedObjectPath<M, N>(celements, r, d); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new child managed object path beneath the provided parent path |
| | | * using the relation's child managed object definition. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the child |
| | | * path references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the child |
| | | * path references. |
| | | * @param r |
| | | * The optional relation referencing the child. |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child( |
| | | OptionalRelationDefinition<M, N> r) { |
| | | return child(r, r.getChildDefinition()); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new child managed object path beneath the provided parent path |
| | | * having the specified managed object definition. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the child |
| | | * path references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the child |
| | | * path references. |
| | | * @param r |
| | | * The singleton relation referencing the child. |
| | | * @param d |
| | | * The managed object definition associated with the child (must |
| | | * be a sub-type of the relation). |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child( |
| | | SingletonRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) { |
| | | LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements); |
| | | celements.add(new SingletonElement<M, N>(r, d)); |
| | | return new ManagedObjectPath<M, N>(celements, r, d); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new child managed object path beneath the provided parent path |
| | | * using the relation's child managed object definition. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the child |
| | | * path references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the child |
| | | * path references. |
| | | * @param r |
| | | * The singleton relation referencing the child. |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child( |
| | | SingletonRelationDefinition<M, N> r) { |
| | | return child(r, r.getChildDefinition()); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new child managed object path beneath the provided parent path |
| | | * having the specified managed object definition. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the child |
| | | * path references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the child |
| | | * path references. |
| | | * @param r |
| | | * The set relation referencing the child. |
| | | * @param d |
| | | * The managed object definition associated with the child (must |
| | | * be a sub-type of the relation). |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | * @throws IllegalArgumentException |
| | | * If the provided name is empty or blank. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child( |
| | | SetRelationDefinition<? super M, ? super N> r, AbstractManagedObjectDefinition<M, N> d) { |
| | | LinkedList<Element<?, ?>> celements = new LinkedList<Element<?, ?>>(elements); |
| | | celements.add(new SetElement<M, N>(r, d)); |
| | | return new ManagedObjectPath<M, N>(celements, r, d); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new child managed object path beneath the provided parent path |
| | | * having the managed object definition indicated by <code>name</code>. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the path |
| | | * references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the path |
| | | * references. |
| | | * @param r |
| | | * The set relation referencing the child. |
| | | * @param name |
| | | * The name of the managed object definition associated with the |
| | | * child (must be a sub-type of the relation). |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | * @throws IllegalArgumentException |
| | | * If the provided name is empty or blank or specifies a managed |
| | | * object definition which is not a sub-type of the relation's |
| | | * child definition. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<? extends M, ? extends N> child( |
| | | SetRelationDefinition<M, N> r, String name) { |
| | | AbstractManagedObjectDefinition<M, N> d = r.getChildDefinition(); |
| | | return child(r, d.getChild(name)); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new child managed object path beneath the provided parent path |
| | | * using the relation's child managed object definition. |
| | | * |
| | | * @param <M> |
| | | * The type of client managed object configuration that the child |
| | | * path references. |
| | | * @param <N> |
| | | * The type of server managed object configuration that the child |
| | | * path references. |
| | | * @param r |
| | | * The set relation referencing the child. |
| | | * @return Returns a new child managed object path beneath the provided |
| | | * parent path. |
| | | * @throws IllegalArgumentException |
| | | * If the provided name is empty or blank. |
| | | */ |
| | | public <M extends ConfigurationClient, N extends Configuration> ManagedObjectPath<M, N> child( |
| | | SetRelationDefinition<M, N> r) { |
| | | return child(r, r.getChildDefinition()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean equals(Object obj) { |
| | | if (obj == this) { |
| | | return true; |
| | | } else if (obj instanceof ManagedObjectPath) { |
| | | ManagedObjectPath<?, ?> other = (ManagedObjectPath<?, ?>) obj; |
| | | return toString().equals(other.toString()); |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the definition of the managed object referred to by this path. |
| | | * <p> |
| | | * When the path is empty, the {@link RootCfgDefn} is returned. |
| | | * |
| | | * @return Returns the definition of the managed object referred to by this |
| | | * path, or the {@link RootCfgDefn} if the path is empty. |
| | | */ |
| | | public AbstractManagedObjectDefinition<C, S> getManagedObjectDefinition() { |
| | | return d; |
| | | } |
| | | |
| | | /** |
| | | * Get the name of the managed object referred to by this path if |
| | | * applicable. |
| | | * <p> |
| | | * If there path does not refer to an instantiable managed object |
| | | * <code>null</code> is returned. |
| | | * |
| | | * @return Returns the name of the managed object referred to by this path, |
| | | * or <code>null</code> if the managed object does not have a name. |
| | | */ |
| | | public String getName() { |
| | | if (elements.isEmpty()) { |
| | | return null; |
| | | } else { |
| | | return elements.get(elements.size() - 1).getName(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the relation definition of the managed object referred to by this |
| | | * path. |
| | | * <p> |
| | | * When the path is empty, the <code>null</code> is returned. |
| | | * |
| | | * @return Returns the relation definition of the managed object referred to |
| | | * by this path, or the <code>null</code> if the path is empty. |
| | | */ |
| | | public RelationDefinition<? super C, ? super S> getRelationDefinition() { |
| | | return r; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int hashCode() { |
| | | return toString().hashCode(); |
| | | } |
| | | |
| | | /** |
| | | * Determine whether or not this path contains any path elements. |
| | | * |
| | | * @return Returns <code>true</code> if this path does not contain any path |
| | | * elements. |
| | | */ |
| | | public boolean isEmpty() { |
| | | return elements.isEmpty(); |
| | | } |
| | | |
| | | /** |
| | | * Determines whether this managed object path references the same location |
| | | * as the provided managed object path. |
| | | * <p> |
| | | * This method differs from <code>equals</code> in that it ignores sub-type |
| | | * definitions. |
| | | * |
| | | * @param other |
| | | * The managed object path to be compared. |
| | | * @return Returns <code>true</code> if this managed object path references |
| | | * the same location as the provided managed object path. |
| | | */ |
| | | public boolean matches(ManagedObjectPath<?, ?> other) { |
| | | DN thisDN = toDN(); |
| | | DN otherDN = other.toDN(); |
| | | return thisDN.equals(otherDN); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new parent managed object path representing the immediate |
| | | * parent of this path. This method is a short-hand for |
| | | * <code>parent(1)</code>. |
| | | * |
| | | * @return Returns a new parent managed object path representing the |
| | | * immediate parent of this path. |
| | | * @throws IllegalArgumentException |
| | | * If this path does not have a parent (i.e. it is the empty |
| | | * path). |
| | | */ |
| | | public ManagedObjectPath<?, ?> parent() { |
| | | return parent(1); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new parent managed object path the specified number of path |
| | | * elements above this path. |
| | | * |
| | | * @param offset |
| | | * The number of path elements (0 - means no offset, 1 means the |
| | | * parent, and 2 means the grand-parent). |
| | | * @return Returns a new parent managed object path the specified number of |
| | | * path elements above this path. |
| | | * @throws IllegalArgumentException |
| | | * If the offset is less than 0, or greater than the number of |
| | | * path elements in this path. |
| | | */ |
| | | public ManagedObjectPath<?, ?> parent(int offset) { |
| | | if (offset < 0) { |
| | | throw new IllegalArgumentException("Negative offset"); |
| | | } |
| | | |
| | | if (offset > elements.size()) { |
| | | throw new IllegalArgumentException("Offset is greater than the number of path elements"); |
| | | } |
| | | |
| | | // An offset of 0 leaves the path unchanged. |
| | | if (offset == 0) { |
| | | return this; |
| | | } |
| | | |
| | | // Return the empty path if the parent has zero elements. |
| | | if (elements.size() == offset) { |
| | | return emptyPath(); |
| | | } |
| | | |
| | | LinkedList<Element<?, ?>> celements = |
| | | new LinkedList<Element<?, ?>>(elements.subList(0, elements.size() - offset)); |
| | | return create(celements, celements.getLast()); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new managed object path which has the same structure as this |
| | | * path except that the final path element is renamed. The final path |
| | | * element must comprise of an instantiable relation. |
| | | * |
| | | * @param newName |
| | | * The new name of the final path element. |
| | | * @return Returns a new managed object path which has the same structure as |
| | | * this path except that the final path element is renamed. |
| | | * @throws IllegalStateException |
| | | * If this managed object path is empty or if its final path |
| | | * element does not comprise of an instantiable relation. |
| | | */ |
| | | public ManagedObjectPath<C, S> rename(String newName) { |
| | | if (elements.size() == 0) { |
| | | throw new IllegalStateException("Cannot rename an empty path"); |
| | | } |
| | | |
| | | if (r instanceof InstantiableRelationDefinition) { |
| | | InstantiableRelationDefinition<? super C, ? super S> ir = |
| | | (InstantiableRelationDefinition<? super C, ? super S>) r; |
| | | return parent().child(ir, d, newName); |
| | | } else { |
| | | throw new IllegalStateException("Not an instantiable relation"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Serialize this managed object path using the provided serialization |
| | | * strategy. |
| | | * <p> |
| | | * The path elements will be passed to the serializer in big-endian order: |
| | | * starting from the root element and proceeding down to the leaf. |
| | | * |
| | | * @param serializer |
| | | * The managed object path serialization strategy. |
| | | */ |
| | | public void serialize(ManagedObjectPathSerializer serializer) { |
| | | for (Element<?, ?> element : elements) { |
| | | element.serialize(serializer); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the number of path elements in this managed object path. |
| | | * |
| | | * @return Returns the number of path elements (0 - means no offset, 1 means |
| | | * the parent, and 2 means the grand-parent). |
| | | */ |
| | | public int size() { |
| | | return elements.size(); |
| | | } |
| | | |
| | | /** |
| | | * Creates a DN representation of this managed object path. |
| | | * |
| | | * @return Returns a DN representation of this managed object path. |
| | | */ |
| | | public DN toDN() { |
| | | // Use a simple serializer to create the contents. |
| | | DNSerializer serializer = new DNSerializer(); |
| | | serialize(serializer); |
| | | return serializer.toDN(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | toString(builder); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Appends a string representation of this managed object path to the |
| | | * provided string builder. |
| | | * |
| | | * @param builder |
| | | * Append the string representation to this builder. |
| | | * @see #toString() |
| | | */ |
| | | public void toString(final StringBuilder builder) { |
| | | if (isEmpty()) { |
| | | // Special treatment of root configuration paths. |
| | | builder.append('/'); |
| | | } else { |
| | | // Use a simple serializer to create the contents. |
| | | ManagedObjectPathSerializer serializer = new StringSerializer(builder); |
| | | serialize(serializer); |
| | | } |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A strategy for serializing managed object paths. |
| | | * <p> |
| | | * This interface provides a generic means for serializing managed object paths |
| | | * into application specific forms. For example, a JNDI client would use this |
| | | * interface to construct <code>LdapName</code> objects from a path. Similarly, |
| | | * on the server side, a serialization strategy is used to construct |
| | | * <code>DN</code> instances from a path. |
| | | * <p> |
| | | * During serialization the serializer is invoked for each element in the |
| | | * managed object path in big-endian order, starting from the root and |
| | | * proceeding down to the leaf element. |
| | | */ |
| | | public interface ManagedObjectPathSerializer { |
| | | |
| | | /** |
| | | * Append a managed object path element identified by an instantiable |
| | | * relation and an instance name. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this path |
| | | * element references. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this path |
| | | * element references. |
| | | * @param r |
| | | * The instantiable relation. |
| | | * @param d |
| | | * The managed object definition. |
| | | * @param name |
| | | * The instance name. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | InstantiableRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d, String name); |
| | | |
| | | /** |
| | | * Append a managed object path element identified by an optional relation. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this path |
| | | * element references. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this path |
| | | * element references. |
| | | * @param r |
| | | * The optional relation. |
| | | * @param d |
| | | * The managed object definition. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | OptionalRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d); |
| | | |
| | | /** |
| | | * Append a managed object path element identified by a singleton relation. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this path |
| | | * element references. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this path |
| | | * element references. |
| | | * @param r |
| | | * The singleton relation. |
| | | * @param d |
| | | * The managed object definition. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | SingletonRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d); |
| | | |
| | | /** |
| | | * Append a managed object path element identified by a set relation. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this path |
| | | * element references. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this path |
| | | * element references. |
| | | * @param r |
| | | * The set relation. |
| | | * @param d |
| | | * The managed object definition. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | SetRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d); |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Exceptions thrown as a result of errors that occurred when reading, listing, |
| | | * and modifying managed objects. |
| | | */ |
| | | public abstract class OperationsException extends AdminException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 6329910102360262187L; |
| | | |
| | | /** |
| | | * Create an operations exception with a message and cause. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | protected OperationsException(LocalizableMessage message, Throwable cause) { |
| | | super(message, cause); |
| | | } |
| | | |
| | | /** |
| | | * Create an operations exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | protected OperationsException(LocalizableMessage message) { |
| | | super(message); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A managed object composite relationship definition which represents a |
| | | * composition of an optional single managed object (i.e. the referenced managed |
| | | * object may or may not be present). |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this relation |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this relation |
| | | * definition refers to. |
| | | */ |
| | | public final class OptionalRelationDefinition<C extends ConfigurationClient, S extends Configuration> extends |
| | | RelationDefinition<C, S> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing optional relation |
| | | * definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | */ |
| | | public static final class Builder<C extends ConfigurationClient, S extends Configuration> extends |
| | | AbstractBuilder<C, S, OptionalRelationDefinition<C, S>> { |
| | | |
| | | // The optional default managed object associated with this |
| | | // optional relation. |
| | | private DefaultManagedObject<? extends C, ? extends S> defaultManagedObject = null; |
| | | |
| | | /** |
| | | * Creates a new builder which can be used to incrementally build an |
| | | * optional relation definition. |
| | | * |
| | | * @param pd |
| | | * The parent managed object definition. |
| | | * @param name |
| | | * The name of the relation. |
| | | * @param cd |
| | | * The child managed object definition. |
| | | */ |
| | | // @Checkstyle:ignore |
| | | public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name, AbstractManagedObjectDefinition<C, S> cd) { |
| | | super(pd, name, cd); |
| | | } |
| | | |
| | | /** |
| | | * Sets the optional default managed object associated with this |
| | | * optional relation definition. |
| | | * |
| | | * @param defaultManagedObject |
| | | * The default managed object or <code>null</code> if there |
| | | * is no default managed object defined for this relation |
| | | * definition. |
| | | */ |
| | | public void setDefaultManagedObject(DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) { |
| | | this.defaultManagedObject = defaultManagedObject; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected OptionalRelationDefinition<C, S> buildInstance(Common<C, S> common) { |
| | | return new OptionalRelationDefinition<C, S>(common, defaultManagedObject); |
| | | } |
| | | |
| | | } |
| | | |
| | | // The optional default managed object associated with this |
| | | // optional relation. |
| | | private final DefaultManagedObject<? extends C, ? extends S> defaultManagedObject; |
| | | |
| | | // Private constructor. |
| | | private OptionalRelationDefinition(Common<C, S> common, |
| | | DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) { |
| | | super(common); |
| | | this.defaultManagedObject = defaultManagedObject; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitOptional(this, p); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional default managed object associated with this optional |
| | | * relation definition. |
| | | * |
| | | * @return Returns the default managed object or <code>null</code> if there |
| | | * is no default managed object defined for this relation |
| | | * definition. |
| | | */ |
| | | public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject() { |
| | | return defaultManagedObject; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | builder.append("name="); |
| | | builder.append(getName()); |
| | | builder.append(" type=optional parent="); |
| | | builder.append(getParentDefinition().getName()); |
| | | builder.append(" child="); |
| | | builder.append(getChildDefinition().getName()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | if (defaultManagedObject != null) { |
| | | defaultManagedObject.initialize(); |
| | | } |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.Comparator; |
| | | import java.util.EnumSet; |
| | | import java.util.Locale; |
| | | import java.util.MissingResourceException; |
| | | import java.util.Set; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * An interface for querying generic property definition features. |
| | | * <p> |
| | | * Property definitions are analogous to ConfigAttributes in the current model |
| | | * and will play a similar role. Eventually these will replace them. |
| | | * <p> |
| | | * Implementations <b>must</b> take care to implement the various comparison |
| | | * methods. |
| | | * |
| | | * @param <T> |
| | | * The data-type of values of the property. |
| | | */ |
| | | public abstract class PropertyDefinition<T> implements Comparator<T>, Comparable<PropertyDefinition<?>> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing property definitions. |
| | | * |
| | | * @param <T> |
| | | * The data-type of values of the property. |
| | | * @param <D> |
| | | * The type of property definition constructed by this builder. |
| | | */ |
| | | protected abstract static class AbstractBuilder<T, D extends PropertyDefinition<T>> { |
| | | |
| | | // The administrator action. |
| | | private AdministratorAction adminAction; |
| | | |
| | | // The default behavior provider. |
| | | private DefaultBehaviorProvider<T> defaultBehavior; |
| | | |
| | | // The abstract managed object |
| | | private final AbstractManagedObjectDefinition<?, ?> definition; |
| | | |
| | | // The options applicable to this definition. |
| | | private final EnumSet<PropertyOption> options; |
| | | |
| | | // The name of this property definition. |
| | | private final String propertyName; |
| | | |
| | | /** |
| | | * Create a property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this |
| | | * property definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | */ |
| | | protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | this.definition = d; |
| | | this.propertyName = propertyName; |
| | | this.options = EnumSet.noneOf(PropertyOption.class); |
| | | this.adminAction = new AdministratorAction(AdministratorAction.Type.NONE, d, propertyName); |
| | | this.defaultBehavior = new UndefinedDefaultBehaviorProvider<T>(); |
| | | } |
| | | |
| | | /** |
| | | * Construct a property definition based on the properties of this |
| | | * builder. |
| | | * |
| | | * @return The new property definition. |
| | | */ |
| | | public final D getInstance() { |
| | | return buildInstance(definition, propertyName, options, adminAction, defaultBehavior); |
| | | } |
| | | |
| | | /** |
| | | * Set the administrator action. |
| | | * |
| | | * @param adminAction |
| | | * The administrator action. |
| | | */ |
| | | public final void setAdministratorAction(AdministratorAction adminAction) { |
| | | Reject.ifNull(adminAction); |
| | | this.adminAction = adminAction; |
| | | } |
| | | |
| | | /** |
| | | * Set the default behavior provider. |
| | | * |
| | | * @param defaultBehavior |
| | | * The default behavior provider. |
| | | */ |
| | | public final void setDefaultBehaviorProvider(DefaultBehaviorProvider<T> defaultBehavior) { |
| | | Reject.ifNull(defaultBehavior); |
| | | this.defaultBehavior = defaultBehavior; |
| | | } |
| | | |
| | | /** |
| | | * Add a property definition option. |
| | | * |
| | | * @param option |
| | | * The property option. |
| | | */ |
| | | public final void setOption(PropertyOption option) { |
| | | Reject.ifNull(option); |
| | | options.add(option); |
| | | } |
| | | |
| | | /** |
| | | * Build a property definition based on the properties of this builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this |
| | | * property definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @param options |
| | | * Options applicable to this definition. |
| | | * @param adminAction |
| | | * The administrator action. |
| | | * @param defaultBehavior |
| | | * The default behavior provider. |
| | | * @return The new property definition. |
| | | */ |
| | | protected abstract D buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<T> defaultBehavior); |
| | | } |
| | | |
| | | // The administrator action. |
| | | private final AdministratorAction adminAction; |
| | | |
| | | // The default behavior provider. |
| | | private final DefaultBehaviorProvider<T> defaultBehavior; |
| | | |
| | | // The abstract managed object |
| | | private final AbstractManagedObjectDefinition<?, ?> definition; |
| | | |
| | | // Options applicable to this definition. |
| | | private final Set<PropertyOption> options; |
| | | |
| | | // The property name. |
| | | private final String propertyName; |
| | | |
| | | // The property value class. |
| | | private final Class<T> theClass; |
| | | |
| | | /** |
| | | * Create a property definition. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param theClass |
| | | * The property value class. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @param options |
| | | * Options applicable to this definition. |
| | | * @param adminAction |
| | | * The administrator action. |
| | | * @param defaultBehavior |
| | | * The default behavior provider. |
| | | */ |
| | | protected PropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, Class<T> theClass, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, DefaultBehaviorProvider<T> defaultBehavior) { |
| | | Reject.ifNull(d, theClass, propertyName, options, adminAction, defaultBehavior); |
| | | |
| | | this.definition = d; |
| | | this.theClass = theClass; |
| | | this.propertyName = propertyName; |
| | | this.options = EnumSet.copyOf(options); |
| | | this.adminAction = adminAction; |
| | | this.defaultBehavior = defaultBehavior; |
| | | } |
| | | |
| | | /** |
| | | * Apply a visitor to this property definition. |
| | | * |
| | | * @param <R> |
| | | * The return type of the visitor's methods. |
| | | * @param <P> |
| | | * The type of the additional parameters to the visitor's |
| | | * methods. |
| | | * @param v |
| | | * The property definition visitor. |
| | | * @param p |
| | | * Optional additional visitor parameter. |
| | | * @return Returns a result as specified by the visitor. |
| | | */ |
| | | public abstract <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p); |
| | | |
| | | /** |
| | | * Apply a visitor to a property value associated with this property |
| | | * definition. |
| | | * |
| | | * @param <R> |
| | | * The return type of the visitor's methods. |
| | | * @param <P> |
| | | * The type of the additional parameters to the visitor's |
| | | * methods. |
| | | * @param v |
| | | * The property value visitor. |
| | | * @param value |
| | | * The property value. |
| | | * @param p |
| | | * Optional additional visitor parameter. |
| | | * @return Returns a result as specified by the visitor. |
| | | */ |
| | | public abstract <R, P> R accept(PropertyValueVisitor<R, P> v, T value, P p); |
| | | |
| | | /** |
| | | * Cast the provided value to the type associated with this property |
| | | * definition. |
| | | * <p> |
| | | * This method only casts the object to the required type; it does not |
| | | * validate the value once it has been cast. Subsequent validation should be |
| | | * performed using the method {@link #validateValue(Object, PropertyDefinitionsOptions)}. |
| | | * <p> |
| | | * This method guarantees the following expression is always |
| | | * <code>true</code>: |
| | | * |
| | | * <pre> |
| | | * PropertyDefinition d; |
| | | * x == d.cast(x); |
| | | * </pre> |
| | | * |
| | | * @param object |
| | | * The property value to be cast (can be <code>null</code>). |
| | | * @return Returns the property value cast to the correct type. |
| | | * @throws ClassCastException |
| | | * If the provided property value did not have the correct type. |
| | | */ |
| | | public final T castValue(Object object) { |
| | | return theClass.cast(object); |
| | | } |
| | | |
| | | /** |
| | | * Compares two property values for order. Returns a negative integer, zero, |
| | | * or a positive integer as the first argument is less than, equal to, or |
| | | * greater than the second. |
| | | * <p> |
| | | * This default implementation normalizes both values using |
| | | * {@link #normalizeValue(Object)} and then performs a case-sensitive string |
| | | * comparison. |
| | | * |
| | | * @param o1 |
| | | * the first object to be compared. |
| | | * @param o2 |
| | | * the second object to be compared. |
| | | * @return a negative integer, zero, or a positive integer as the first |
| | | * argument is less than, equal to, or greater than the second. |
| | | */ |
| | | public int compare(T o1, T o2) { |
| | | Reject.ifNull(o1); |
| | | Reject.ifNull(o2); |
| | | |
| | | String s1 = normalizeValue(o1); |
| | | String s2 = normalizeValue(o2); |
| | | |
| | | return s1.compareTo(s2); |
| | | } |
| | | |
| | | /** |
| | | * Compares this property definition with the specified property definition |
| | | * for order. Returns a negative integer, zero, or a positive integer if |
| | | * this property definition is less than, equal to, or greater than the |
| | | * specified property definition. |
| | | * <p> |
| | | * The ordering must be determined first from the property name and then |
| | | * base on the underlying value type. |
| | | * |
| | | * @param o |
| | | * The reference property definition with which to compare. |
| | | * @return Returns a negative integer, zero, or a positive integer if this |
| | | * property definition is less than, equal to, or greater than the |
| | | * specified property definition. |
| | | */ |
| | | public final int compareTo(PropertyDefinition<?> o) { |
| | | int rc = propertyName.compareTo(o.propertyName); |
| | | if (rc == 0) { |
| | | rc = theClass.getName().compareTo(o.theClass.getName()); |
| | | } |
| | | return rc; |
| | | } |
| | | |
| | | /** |
| | | * Parse and validate a string representation of a property value. |
| | | * |
| | | * @param value |
| | | * The property string value (must not be <code>null</code>). |
| | | * @param options |
| | | * Options to use when decoding value. |
| | | * @return Returns the decoded property value. |
| | | * @throws IllegalPropertyValueStringException |
| | | * If the property value string is invalid. |
| | | */ |
| | | public abstract T decodeValue(String value, PropertyDefinitionsOptions options); |
| | | |
| | | /** |
| | | * Encode the provided property value into its string representation. |
| | | * <p> |
| | | * This default implementation simply returns invokes the |
| | | * {@link Object#toString()} method on the provided value. |
| | | * |
| | | * @param value |
| | | * The property value (must not be <code>null</code>). |
| | | * @return Returns the encoded property string value. |
| | | * @throws IllegalPropertyValueException |
| | | * If the property value is invalid. |
| | | */ |
| | | public String encodeValue(T value) { |
| | | Reject.ifNull(value); |
| | | |
| | | return value.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether some other object is "equal to" this property |
| | | * definition. This method must obey the general contract of |
| | | * <tt>Object.equals(Object)</tt>. Additionally, this method can return |
| | | * <tt>true</tt> <i>only</i> if the specified Object is also a property |
| | | * definition and it has the same name, as returned by {@link #getName()}, |
| | | * and also is deemed to be "compatible" with this property |
| | | * definition. Compatibility means that the two property definitions share |
| | | * the same underlying value type and provide similar comparator |
| | | * implementations. |
| | | * |
| | | * @param o |
| | | * The reference object with which to compare. |
| | | * @return Returns <code>true</code> only if the specified object is also a |
| | | * property definition and it has the same name and is compatible |
| | | * with this property definition. |
| | | * @see java.lang.Object#equals(java.lang.Object) |
| | | * @see java.lang.Object#hashCode() |
| | | */ |
| | | @Override |
| | | public final boolean equals(Object o) { |
| | | if (this == o) { |
| | | return true; |
| | | } else if (o instanceof PropertyDefinition) { |
| | | PropertyDefinition<?> other = (PropertyDefinition<?>) o; |
| | | if (propertyName.equals(other.propertyName)) { |
| | | if (theClass.equals(other.theClass)) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the administrator action associated with this property definition. |
| | | * The administrator action describes any action which the administrator |
| | | * must perform in order for changes to this property to take effect. |
| | | * |
| | | * @return Returns the administrator action associated with this property |
| | | * definition. |
| | | */ |
| | | public final AdministratorAction getAdministratorAction() { |
| | | return adminAction; |
| | | } |
| | | |
| | | /** |
| | | * Get the default behavior provider associated with this property |
| | | * definition. |
| | | * |
| | | * @return Returns the default behavior provider associated with this |
| | | * property definition. |
| | | */ |
| | | public final DefaultBehaviorProvider<T> getDefaultBehaviorProvider() { |
| | | return defaultBehavior; |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional description of this property definition in the default |
| | | * locale. |
| | | * |
| | | * @return Returns the description of this property definition in the |
| | | * default locale, or <code>null</code> if there is no description. |
| | | */ |
| | | public final LocalizableMessage getDescription() { |
| | | return getDescription(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional description of this property definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the description of this property definition in the |
| | | * specified locale, or <code>null</code> if there is no |
| | | * description. |
| | | */ |
| | | public final LocalizableMessage getDescription(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "property." + propertyName + ".description"; |
| | | try { |
| | | return resource.getMessage(definition, property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the managed object definition associated with this property |
| | | * definition. |
| | | * |
| | | * @return Returns the managed object definition associated with this |
| | | * property definition. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<?, ?> getManagedObjectDefinition() { |
| | | return definition; |
| | | } |
| | | |
| | | /** |
| | | * Get the name of the property. |
| | | * |
| | | * @return Returns the name of the property. |
| | | */ |
| | | public final String getName() { |
| | | return propertyName; |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this property definition in the default locale. |
| | | * |
| | | * @return Returns the synopsis of this property definition in the default |
| | | * locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this property definition in the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this property definition in the specified |
| | | * locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "property." + propertyName + ".synopsis"; |
| | | return resource.getMessage(definition, property, locale); |
| | | } |
| | | |
| | | /** |
| | | * Returns a hash code value for this property definition. The hash code |
| | | * should be derived from the property name and the type of values handled |
| | | * by this property definition. |
| | | * |
| | | * @return Returns the hash code value for this property definition. |
| | | */ |
| | | @Override |
| | | public final int hashCode() { |
| | | int rc = 17 + propertyName.hashCode(); |
| | | return 37 * rc + theClass.hashCode(); |
| | | } |
| | | |
| | | /** |
| | | * Check if the specified option is set for this property definition. |
| | | * |
| | | * @param option |
| | | * The option to test. |
| | | * @return Returns <code>true</code> if the option is set, or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public final boolean hasOption(PropertyOption option) { |
| | | return options.contains(option); |
| | | } |
| | | |
| | | /** |
| | | * Get a normalized string representation of a property value. This can then |
| | | * be used for comparisons and for generating hash-codes. |
| | | * <p> |
| | | * This method may throw an exception if the provided value is invalid. |
| | | * However, applications should not assume that implementations of this |
| | | * method will always validate a value. This task is the responsibility of |
| | | * {@link #validateValue(Object, PropertyDefinitionsOptions)}. |
| | | * <p> |
| | | * This default implementation simply returns the string representation of |
| | | * the provided value. Sub-classes might want to override this method if |
| | | * this behavior is insufficient (for example, a string property definition |
| | | * might strip white-space and convert characters to lower-case). |
| | | * |
| | | * @param value |
| | | * The property value to be normalized. |
| | | * @return Returns the normalized property value. |
| | | * @throws IllegalPropertyValueException |
| | | * If the property value is invalid. |
| | | */ |
| | | public String normalizeValue(T value) { |
| | | Reject.ifNull(value); |
| | | |
| | | return encodeValue(value); |
| | | } |
| | | |
| | | /** |
| | | * Returns a string representation of this property definition. |
| | | * |
| | | * @return Returns a string representation of this property definition. |
| | | * @see Object#toString() |
| | | */ |
| | | @Override |
| | | public final String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | toString(builder); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Append a string representation of the property definition to the provided |
| | | * string builder. |
| | | * <p> |
| | | * This simple implementation just outputs the propertyName of the property |
| | | * definition. Sub-classes should override this method to provide more |
| | | * complete string representations. |
| | | * |
| | | * @param builder |
| | | * The string builder where the string representation should be |
| | | * appended. |
| | | */ |
| | | public void toString(StringBuilder builder) { |
| | | builder.append(propertyName); |
| | | } |
| | | |
| | | /** |
| | | * Determine if the provided property value is valid according to this |
| | | * property definition. |
| | | * |
| | | * @param value |
| | | * The property value (must not be <code>null</code>). |
| | | * @param options |
| | | * Options to use when decoding value. |
| | | * @throws IllegalPropertyValueException |
| | | * If the property value is invalid. |
| | | */ |
| | | public abstract void validateValue(T value, PropertyDefinitionsOptions options); |
| | | |
| | | /** |
| | | * Performs any run-time initialization required by this property |
| | | * definition. This may include resolving managed object paths and property |
| | | * names. |
| | | * |
| | | * @throws Exception |
| | | * If this property definition could not be initialized. |
| | | */ |
| | | protected void initialize() throws Exception { |
| | | // No implementation required. |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.text.NumberFormat; |
| | | import java.util.EnumSet; |
| | | import java.util.Set; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizableMessageBuilder; |
| | | |
| | | /** |
| | | * A property definition visitor which can be used to generate syntax usage |
| | | * information. |
| | | */ |
| | | public final class PropertyDefinitionUsageBuilder { |
| | | |
| | | /** |
| | | * Underlying implementation. |
| | | */ |
| | | private final class MyPropertyDefinitionVisitor extends PropertyDefinitionVisitor<LocalizableMessage, Void> { |
| | | |
| | | // Flag indicating whether detailed syntax information will be |
| | | // generated. |
| | | private final boolean isDetailed; |
| | | |
| | | // The formatter to use for numeric values. |
| | | private final NumberFormat numberFormat; |
| | | |
| | | // Private constructor. |
| | | private MyPropertyDefinitionVisitor(boolean isDetailed) { |
| | | this.isDetailed = isDetailed; |
| | | |
| | | this.numberFormat = NumberFormat.getNumberInstance(); |
| | | this.numberFormat.setGroupingUsed(true); |
| | | this.numberFormat.setMaximumFractionDigits(2); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> LocalizableMessage visitAggregation( |
| | | AggregationPropertyDefinition<C, S> d, Void p) { |
| | | return LocalizableMessage.raw("NAME"); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitAttributeType(AttributeTypePropertyDefinition d, Void p) { |
| | | return LocalizableMessage.raw("OID"); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitACI(ACIPropertyDefinition d, Void p) { |
| | | return LocalizableMessage.raw("ACI"); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitBoolean(BooleanPropertyDefinition d, Void p) { |
| | | if (isDetailed) { |
| | | return LocalizableMessage.raw("false | true"); |
| | | } else { |
| | | return LocalizableMessage.raw("BOOLEAN"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitClass(ClassPropertyDefinition d, Void p) { |
| | | if (isDetailed && !d.getInstanceOfInterface().isEmpty()) { |
| | | return LocalizableMessage.raw("CLASS <= " + d.getInstanceOfInterface().get(0)); |
| | | } else { |
| | | return LocalizableMessage.raw("CLASS"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitDN(DNPropertyDefinition d, Void p) { |
| | | if (isDetailed && d.getBaseDN() != null) { |
| | | return LocalizableMessage.raw("DN <= " + d.getBaseDN()); |
| | | } else { |
| | | return LocalizableMessage.raw("DN"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitDuration(DurationPropertyDefinition d, Void p) { |
| | | LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | DurationUnit unit = d.getBaseUnit(); |
| | | |
| | | if (isDetailed && d.getLowerLimit() > 0) { |
| | | builder.append(DurationUnit.toString(d.getLowerLimit())); |
| | | builder.append(" <= "); |
| | | } |
| | | |
| | | builder.append("DURATION ("); |
| | | builder.append(unit.getShortName()); |
| | | builder.append(")"); |
| | | |
| | | if (isDetailed) { |
| | | if (d.getUpperLimit() != null) { |
| | | builder.append(" <= "); |
| | | builder.append(DurationUnit.toString(d.getUpperLimit())); |
| | | } |
| | | |
| | | if (d.isAllowUnlimited()) { |
| | | builder.append(" | unlimited"); |
| | | } |
| | | } |
| | | |
| | | return builder.toMessage(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <E extends Enum<E>> LocalizableMessage visitEnum(EnumPropertyDefinition<E> d, Void p) { |
| | | if (!isDetailed) { |
| | | // Use the last word in the property name. |
| | | String name = d.getName(); |
| | | int i = name.lastIndexOf('-'); |
| | | if (i == -1 || i == (name.length() - 1)) { |
| | | return LocalizableMessage.raw(name.toUpperCase()); |
| | | } else { |
| | | return LocalizableMessage.raw(name.substring(i + 1).toUpperCase()); |
| | | } |
| | | } else { |
| | | Set<String> values = new TreeSet<String>(); |
| | | |
| | | for (Object value : EnumSet.allOf(d.getEnumClass())) { |
| | | values.add(value.toString().trim().toLowerCase()); |
| | | } |
| | | |
| | | boolean isFirst = true; |
| | | LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | for (String s : values) { |
| | | if (!isFirst) { |
| | | builder.append(" | "); |
| | | } |
| | | builder.append(s); |
| | | isFirst = false; |
| | | } |
| | | |
| | | return builder.toMessage(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitInteger(IntegerPropertyDefinition d, Void p) { |
| | | LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | |
| | | if (isDetailed) { |
| | | builder.append(String.valueOf(d.getLowerLimit())); |
| | | builder.append(" <= "); |
| | | } |
| | | |
| | | builder.append("INTEGER"); |
| | | |
| | | if (isDetailed) { |
| | | if (d.getUpperLimit() != null) { |
| | | builder.append(" <= "); |
| | | builder.append(String.valueOf(d.getUpperLimit())); |
| | | } else if (d.isAllowUnlimited()) { |
| | | builder.append(" | unlimited"); |
| | | } |
| | | } |
| | | |
| | | return builder.toMessage(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitIPAddress(IPAddressPropertyDefinition d, Void p) { |
| | | return LocalizableMessage.raw("HOST_NAME"); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitIPAddressMask(IPAddressMaskPropertyDefinition d, Void p) { |
| | | return LocalizableMessage.raw("IP_ADDRESS_MASK"); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitSize(SizePropertyDefinition d, Void p) { |
| | | LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | |
| | | if (isDetailed && d.getLowerLimit() > 0) { |
| | | SizeUnit unit = SizeUnit.getBestFitUnitExact(d.getLowerLimit()); |
| | | builder.append(numberFormat.format(unit.fromBytes(d.getLowerLimit()))); |
| | | builder.append(' '); |
| | | builder.append(unit.getShortName()); |
| | | builder.append(" <= "); |
| | | } |
| | | |
| | | builder.append("SIZE"); |
| | | |
| | | if (isDetailed) { |
| | | if (d.getUpperLimit() != null) { |
| | | long upperLimit = d.getUpperLimit(); |
| | | SizeUnit unit = SizeUnit.getBestFitUnitExact(upperLimit); |
| | | |
| | | // Quite often an upper limit is some power of 2 minus 1. In |
| | | // those |
| | | // cases lets use a "less than" relation rather than a "less |
| | | // than |
| | | // or equal to" relation. This will result in a much more |
| | | // readable |
| | | // quantity. |
| | | if (unit == SizeUnit.BYTES && upperLimit < Long.MAX_VALUE) { |
| | | unit = SizeUnit.getBestFitUnitExact(upperLimit + 1); |
| | | if (unit != SizeUnit.BYTES) { |
| | | upperLimit += 1; |
| | | builder.append(" < "); |
| | | } else { |
| | | builder.append(" <= "); |
| | | } |
| | | } else { |
| | | builder.append(" <= "); |
| | | } |
| | | |
| | | builder.append(numberFormat.format(unit.fromBytes(upperLimit))); |
| | | builder.append(' '); |
| | | builder.append(unit.getShortName()); |
| | | } |
| | | |
| | | if (d.isAllowUnlimited()) { |
| | | builder.append(" | unlimited"); |
| | | } |
| | | } |
| | | |
| | | return builder.toMessage(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public LocalizableMessage visitString(StringPropertyDefinition d, Void p) { |
| | | if (d.getPattern() != null) { |
| | | if (isDetailed) { |
| | | LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | builder.append(d.getPatternUsage()); |
| | | builder.append(" - "); |
| | | builder.append(d.getPatternSynopsis()); |
| | | return builder.toMessage(); |
| | | } else { |
| | | return LocalizableMessage.raw(d.getPatternUsage()); |
| | | } |
| | | } else { |
| | | return LocalizableMessage.raw("STRING"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> LocalizableMessage visitUnknown(PropertyDefinition<T> d, Void p) { |
| | | return LocalizableMessage.raw("?"); |
| | | } |
| | | } |
| | | |
| | | // Underlying implementation. |
| | | private final MyPropertyDefinitionVisitor pimpl; |
| | | |
| | | /** |
| | | * Creates a new property usage builder. |
| | | * |
| | | * @param isDetailed |
| | | * Indicates whether or not the generated usage should contain |
| | | * detailed information such as constraints. |
| | | */ |
| | | public PropertyDefinitionUsageBuilder(boolean isDetailed) { |
| | | this.pimpl = new MyPropertyDefinitionVisitor(isDetailed); |
| | | } |
| | | |
| | | /** |
| | | * Generates the usage information for the provided property definition. |
| | | * |
| | | * @param pd |
| | | * The property definitions. |
| | | * @return Returns the usage information for the provided property |
| | | * definition. |
| | | */ |
| | | public LocalizableMessage getUsage(PropertyDefinition<?> pd) { |
| | | return pd.accept(pimpl, null); |
| | | }; |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A visitor of property definitions, in the style of the visitor design |
| | | * pattern. Classes implementing this interface can query property definitions |
| | | * in a type-safe manner when the kind of property definition is unknown at |
| | | * compile time. When a visitor is passed to a property definition's accept |
| | | * method, the corresponding visit method most applicable to that property |
| | | * definition is invoked. |
| | | * <p> |
| | | * Each <code>visitXXX</code> method is provided with a default implementation |
| | | * which calls {@link #visitUnknown(PropertyDefinition, Object)}. Sub-classes |
| | | * can override any or all of the methods to provide their own type-specific |
| | | * behavior. |
| | | * |
| | | * @param <R> |
| | | * The return type of this visitor's methods. Use |
| | | * {@link java.lang.Void} for visitors that do not need to return |
| | | * results. |
| | | * @param <P> |
| | | * The type of the additional parameter to this visitor's methods. |
| | | * Use {@link java.lang.Void} for visitors that do not need an |
| | | * additional parameter. |
| | | */ |
| | | public abstract class PropertyDefinitionVisitor<R, P> { |
| | | |
| | | /** |
| | | * Default constructor. |
| | | */ |
| | | protected PropertyDefinitionVisitor() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Visit a dseecompat Global ACI property definition. |
| | | * |
| | | * @param pd |
| | | * The Global ACI property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitACI(ACIPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an aggregation property definition. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param pd |
| | | * The aggregation property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> R visitAggregation( |
| | | AggregationPropertyDefinition<C, S> pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an attribute type property definition. |
| | | * |
| | | * @param pd |
| | | * The attribute type property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitAttributeType(AttributeTypePropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a boolean property definition. |
| | | * |
| | | * @param pd |
| | | * The boolean property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitBoolean(BooleanPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a class property definition. |
| | | * |
| | | * @param pd |
| | | * The class property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitClass(ClassPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a DN property definition. |
| | | * |
| | | * @param pd |
| | | * The DN property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitDN(DNPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a duration property definition. |
| | | * |
| | | * @param pd |
| | | * The duration property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitDuration(DurationPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an enumeration property definition. |
| | | * |
| | | * @param <E> |
| | | * The enumeration that should be used for values of the property |
| | | * definition. |
| | | * @param pd |
| | | * The enumeration property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public <E extends Enum<E>> R visitEnum(EnumPropertyDefinition<E> pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an integer property definition. |
| | | * |
| | | * @param pd |
| | | * The integer property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitInteger(IntegerPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a IP address property definition. |
| | | * |
| | | * @param pd |
| | | * The IP address property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitIPAddress(IPAddressPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a IP address mask property definition. |
| | | * |
| | | * @param pd |
| | | * The IP address mask property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitIPAddressMask(IPAddressMaskPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a size property definition. |
| | | * |
| | | * @param pd |
| | | * The size property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitSize(SizePropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a string property definition. |
| | | * |
| | | * @param pd |
| | | * The string property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitString(StringPropertyDefinition pd, P p) { |
| | | return visitUnknown(pd, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an unknown type of property definition. Implementations of this |
| | | * method can provide default behavior for unknown property definition |
| | | * types. |
| | | * <p> |
| | | * The default implementation of this method throws an |
| | | * {@link UnknownPropertyDefinitionException}. Sub-classes can override this |
| | | * method with their own default behavior. |
| | | * |
| | | * @param <T> |
| | | * The type of the underlying property. |
| | | * @param pd |
| | | * The property definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | * @throws UnknownPropertyDefinitionException |
| | | * Visitor implementations may optionally throw this exception. |
| | | */ |
| | | public <T> R visitUnknown(PropertyDefinition<T> pd, P p) { |
| | | throw new UnknownPropertyDefinitionException(pd, p); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * Provides options for {@code PropertyDefinition property definitions}. |
| | | * <p> |
| | | * These options are used by some {@code PropertyDefinition} methods to define |
| | | * strategy used when processing value(s) of a property definition. |
| | | */ |
| | | public final class PropertyDefinitionsOptions { |
| | | |
| | | /** Immutable options with no validation of java classes or LDAP attributes. */ |
| | | public static final PropertyDefinitionsOptions NO_VALIDATION_OPTIONS = new PropertyDefinitionsOptions(). |
| | | setAllowClassValidation(false). |
| | | setCheckSchemaForAttributes(false). |
| | | freeze(); |
| | | |
| | | /** By default, class validation is enabled. */ |
| | | private boolean allowClassValidation = true; |
| | | |
| | | /** By default, attributes validation against the schema is enabled. */ |
| | | private boolean checkSchemaForAttributes = true; |
| | | |
| | | /** |
| | | * If true, then the instance is frozen so state can't be changed (object is |
| | | * immutable). |
| | | */ |
| | | private boolean isFrozen = false; |
| | | |
| | | /** |
| | | * Creates a new set of properties options with default settings. By |
| | | * default, class validation and attributes checking are enabled. |
| | | */ |
| | | public PropertyDefinitionsOptions() { |
| | | // empty implementation |
| | | } |
| | | |
| | | /** |
| | | * Determine whether or not class property definitions should validate class |
| | | * name property values. Validation involves checking that the class exists |
| | | * and that it implements the required interfaces. |
| | | * |
| | | * @return Returns <code>true</code> if class property definitions should |
| | | * validate class name property values. |
| | | */ |
| | | public boolean allowClassValidation() { |
| | | return allowClassValidation; |
| | | } |
| | | |
| | | /** |
| | | * Specify whether or not class property definitions should validate class |
| | | * name property values. Validation involves checking that the class exists |
| | | * and that it implements the required interfaces. |
| | | * <p> |
| | | * By default validation is switched on. |
| | | * |
| | | * @param value |
| | | * <code>true</code> if class property definitions should |
| | | * validate class name property values. |
| | | * @return A reference to this definitions options. |
| | | */ |
| | | public PropertyDefinitionsOptions setAllowClassValidation(boolean value) { |
| | | if (isFrozen) { |
| | | throw new IllegalStateException("This object is frozen, it can't be changed"); |
| | | } |
| | | allowClassValidation = value; |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not attribute type names should be validated |
| | | * against the schema. |
| | | * |
| | | * @return Returns <code>true</code> if attribute type names should be |
| | | * validated against the schema. |
| | | */ |
| | | public boolean checkSchemaForAttributes() { |
| | | return checkSchemaForAttributes; |
| | | } |
| | | |
| | | /** |
| | | * Specify whether or not attribute type names should be validated against |
| | | * the schema. |
| | | * <p> |
| | | * By default validation is switched on. |
| | | * |
| | | * @param value |
| | | * <code>true</code> if attribute type names should be validated |
| | | * against the schema. |
| | | * @return A reference to this definitions options. |
| | | */ |
| | | public PropertyDefinitionsOptions setCheckSchemaForAttributes(boolean value) { |
| | | if (isFrozen) { |
| | | throw new IllegalStateException("This object is frozen, it can't be changed"); |
| | | } |
| | | checkSchemaForAttributes = value; |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Freeze this object, making it effectively immutable. |
| | | * <p> |
| | | * Once this method is called, all {@code set} methods will throw |
| | | * an IllegalStateException if called. |
| | | * |
| | | * @return A reference to this definitions options. |
| | | */ |
| | | public PropertyDefinitionsOptions freeze() { |
| | | isFrozen = true; |
| | | return this; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Exceptions thrown as a result of errors that occurred when decoding and |
| | | * modifying property values. |
| | | */ |
| | | public abstract class PropertyException extends AdminRuntimeException { |
| | | |
| | | /** |
| | | * Version ID required by serializable classes. |
| | | */ |
| | | private static final long serialVersionUID = -8465109598081914482L; |
| | | |
| | | // The property definition associated with the property that caused |
| | | // the exception. |
| | | private final PropertyDefinition<?> pd; |
| | | |
| | | /** |
| | | * Creates property exception without a cause. |
| | | * |
| | | * @param pd |
| | | * The property definition associated with the property that |
| | | * caused the exception. |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | protected PropertyException(PropertyDefinition<?> pd, LocalizableMessage message) { |
| | | super(message); |
| | | this.pd = pd; |
| | | } |
| | | |
| | | /** |
| | | * Creates property exception with a cause. |
| | | * |
| | | * @param pd |
| | | * The property definition associated with the property that |
| | | * caused the exception. |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | protected PropertyException(PropertyDefinition<?> pd, LocalizableMessage message, Throwable cause) { |
| | | super(message, cause); |
| | | this.pd = pd; |
| | | } |
| | | |
| | | /** |
| | | * Get the property definition associated with the property that caused the |
| | | * exception. |
| | | * |
| | | * @return Returns the property definition associated with the property that |
| | | * caused the exception. |
| | | */ |
| | | public final PropertyDefinition<?> getPropertyDefinition() { |
| | | return pd; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * Thrown when an attempt is made to remove a mandatory property. |
| | | */ |
| | | public class PropertyIsMandatoryException extends PropertyException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 5328211711156565625L; |
| | | |
| | | /** |
| | | * Create a new property is mandatory exception. |
| | | * |
| | | * @param pd |
| | | * The property definition. |
| | | */ |
| | | public PropertyIsMandatoryException(PropertyDefinition<?> pd) { |
| | | super(pd, ERR_PROPERTY_IS_MANDATORY_EXCEPTION.get(pd.getName())); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * Thrown when an attempt is made to modify a read-only property. |
| | | */ |
| | | public class PropertyIsReadOnlyException extends PropertyException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 5315348044141024459L; |
| | | |
| | | /** |
| | | * Create a new property is read-only exception. |
| | | * |
| | | * @param pd |
| | | * The property definition. |
| | | */ |
| | | public PropertyIsReadOnlyException(PropertyDefinition<?> pd) { |
| | | super(pd, ERR_PROPERTY_IS_READ_ONLY_EXCEPTION.get(pd.getName())); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * Thrown when an attempt is made to add more than value to a single-valued |
| | | * property. |
| | | */ |
| | | public class PropertyIsSingleValuedException extends PropertyException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = -8056602690887917027L; |
| | | |
| | | /** |
| | | * Create a new property is single valued exception. |
| | | * |
| | | * @param pd |
| | | * The property definition. |
| | | */ |
| | | public PropertyIsSingleValuedException(PropertyDefinition<?> pd) { |
| | | super(pd, ERR_PROPERTY_IS_SINGLE_VALUED_EXCEPTION.get(pd.getName())); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * Thrown when an attempt is made to retrieve a property using its name but the |
| | | * name was not recognized. |
| | | * <p> |
| | | * This exception can occur when attempt is made to retrieve inherited default |
| | | * values from a managed object. |
| | | */ |
| | | public class PropertyNotFoundException extends OperationsException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = -895548482881819610L; |
| | | |
| | | // The name of the property that could not be found. |
| | | private final String propertyName; |
| | | |
| | | /** |
| | | * Create a new property not found exception. |
| | | * |
| | | * @param propertyName |
| | | * The name of the property that could not be found. |
| | | */ |
| | | public PropertyNotFoundException(String propertyName) { |
| | | super(ERR_PROPERTY_NOT_FOUND_EXCEPTION.get(propertyName)); |
| | | |
| | | this.propertyName = propertyName; |
| | | } |
| | | |
| | | /** |
| | | * Get the name of the property that could not be found. |
| | | * |
| | | * @return Returns the name of the property that could not be found. |
| | | */ |
| | | public String getPropertyName() { |
| | | return propertyName; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * This enumeration contains various options that can be associated with |
| | | * property definitions. |
| | | */ |
| | | public enum PropertyOption { |
| | | /** |
| | | * Use this option to identify properties which should be considered as |
| | | * advanced and should not be exposed by default in client applications. |
| | | */ |
| | | ADVANCED, |
| | | |
| | | /** |
| | | * Use this option to identify properties which must not be directly exposed |
| | | * in client applications. |
| | | */ |
| | | HIDDEN, |
| | | |
| | | /** |
| | | * Use this option to identify properties which must have a value. |
| | | */ |
| | | MANDATORY, |
| | | |
| | | /** |
| | | * Use this option to identify properties which are multi-valued. |
| | | */ |
| | | MULTI_VALUED, |
| | | |
| | | /** |
| | | * Use this option to identify properties which can be initialized once only |
| | | * and are read-only thereafter. |
| | | */ |
| | | READ_ONLY, |
| | | |
| | | /** |
| | | * Use this option to identify properties which are for monitoring purposes |
| | | * only and are generated automatically by the server.. |
| | | */ |
| | | MONITORING; |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | /** |
| | | * An interface which can be used to initialize the contents of a managed |
| | | * object. |
| | | */ |
| | | public interface PropertyProvider { |
| | | |
| | | /** |
| | | * A property provider which always returns empty property values, |
| | | * indicating default behavior. |
| | | */ |
| | | public static final PropertyProvider DEFAULT_PROVIDER = new PropertyProvider() { |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <T> Collection<T> getPropertyValues(PropertyDefinition<T> d) { |
| | | return Collections.<T> emptySet(); |
| | | } |
| | | |
| | | }; |
| | | |
| | | /** |
| | | * Get the property values associated with the specified property |
| | | * definition. |
| | | * <p> |
| | | * Implementations are not required to validate the values that they |
| | | * provide. Specifically: |
| | | * <ul> |
| | | * <li>they do not need to guarantee that the provided values are valid |
| | | * according to the property's syntax |
| | | * <li>they do not need to provide values for mandatory properties |
| | | * <li>they do not need to ensure that single-valued properties do contain |
| | | * at most one value. |
| | | * </ul> |
| | | * The returned set of values is allowed to contain duplicates. |
| | | * |
| | | * @param <T> |
| | | * The underlying type of the property. |
| | | * @param d |
| | | * The Property definition. |
| | | * @return Returns a newly allocated set containing a copy of the property's |
| | | * values. An empty set indicates that the property has no values |
| | | * defined and any default behavior is applicable. |
| | | * @throws IllegalArgumentException |
| | | * If this property provider does not recognise the requested |
| | | * property definition. |
| | | */ |
| | | <T> Collection<T> getPropertyValues(PropertyDefinition<T> d); |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.net.InetAddress; |
| | | |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.schema.AttributeType; |
| | | import org.opends.server.authorization.dseecompat.Aci; |
| | | import org.opends.server.types.AddressMask; |
| | | |
| | | /** |
| | | * A visitor of property values, in the style of the visitor design pattern. |
| | | * Classes implementing this interface can query a property a value and its |
| | | * associated property definition in a type-safe manner when the kind of |
| | | * property value is unknown at compile time. When a visitor is passed to a |
| | | * property definition's accept method, the corresponding visit method most |
| | | * applicable to that property definition is invoked. |
| | | * <p> |
| | | * Each <code>visitXXX</code> method is provided with a default implementation |
| | | * which calls {@link #visitUnknown(PropertyDefinition, Object, Object)}. |
| | | * Sub-classes can override any or all of the methods to provide their own |
| | | * type-specific behavior. |
| | | * |
| | | * @param <R> |
| | | * The return type of this visitor's methods. Use |
| | | * {@link java.lang.Void} for visitors that do not need to return |
| | | * results. |
| | | * @param <P> |
| | | * The type of the additional parameter to this visitor's methods. |
| | | * Use {@link java.lang.Void} for visitors that do not need an |
| | | * additional parameter. |
| | | */ |
| | | public abstract class PropertyValueVisitor<R, P> { |
| | | |
| | | /** |
| | | * Default constructor. |
| | | */ |
| | | protected PropertyValueVisitor() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Visit a dseecompat ACI. |
| | | * |
| | | * @param pd |
| | | * The dseecompat ACI property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitACI(ACIPropertyDefinition pd, Aci v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an aggregation property value. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * aggregation property definition refers to. |
| | | * @param pd |
| | | * The aggregation property definition to visit. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> R visitAggregation( |
| | | AggregationPropertyDefinition<C, S> pd, String v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an attribute type. |
| | | * |
| | | * @param pd |
| | | * The attribute type property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitAttributeType(AttributeTypePropertyDefinition pd, AttributeType v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a boolean. |
| | | * |
| | | * @param pd |
| | | * The boolean property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitBoolean(BooleanPropertyDefinition pd, Boolean v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a class. |
| | | * |
| | | * @param pd |
| | | * The class property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitClass(ClassPropertyDefinition pd, String v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a DN. |
| | | * |
| | | * @param pd |
| | | * The DN property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitDN(DNPropertyDefinition pd, DN v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a duration. |
| | | * |
| | | * @param pd |
| | | * The duration property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitDuration(DurationPropertyDefinition pd, Long v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an enumeration. |
| | | * |
| | | * @param <E> |
| | | * The enumeration that should be used for values of the property |
| | | * definition. |
| | | * @param pd |
| | | * The enumeration property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public <E extends Enum<E>> R visitEnum(EnumPropertyDefinition<E> pd, E v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an integer. |
| | | * |
| | | * @param pd |
| | | * The integer property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitInteger(IntegerPropertyDefinition pd, Integer v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a IP address. |
| | | * |
| | | * @param pd |
| | | * The IP address property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitIPAddress(IPAddressPropertyDefinition pd, InetAddress v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a IP address mask. |
| | | * |
| | | * @param pd |
| | | * The IP address mask property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitIPAddressMask(IPAddressMaskPropertyDefinition pd, AddressMask v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a size. |
| | | * |
| | | * @param pd |
| | | * The size property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitSize(SizePropertyDefinition pd, Long v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit a string. |
| | | * |
| | | * @param pd |
| | | * The string property definition. |
| | | * @param v |
| | | * The property value to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | public R visitString(StringPropertyDefinition pd, String v, P p) { |
| | | return visitUnknown(pd, v, p); |
| | | } |
| | | |
| | | /** |
| | | * Visit an unknown type of property value. Implementations of this method |
| | | * can provide default behavior for unknown types of property. |
| | | * <p> |
| | | * The default implementation of this method throws an |
| | | * {@link UnknownPropertyDefinitionException}. Sub-classes can override this |
| | | * method with their own default behavior. |
| | | * |
| | | * @param <T> |
| | | * The type of property value to visit. |
| | | * @param pd |
| | | * The property definition. |
| | | * @param v |
| | | * The property value. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | * @throws UnknownPropertyDefinitionException |
| | | * Visitor implementations may optionally throw this exception. |
| | | */ |
| | | public <T> R visitUnknown(PropertyDefinition<T> pd, T v, P p) { |
| | | throw new UnknownPropertyDefinitionException(pd, p); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.util.StaticUtils.*; |
| | | |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.RDN; |
| | | |
| | | /** |
| | | * A reference to another managed object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * reference refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * reference refers to. |
| | | */ |
| | | public final class Reference<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | /** |
| | | * Parses a DN string value as a reference using the provided managed object |
| | | * path and relation definition. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * reference refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * reference refers to. |
| | | * @param path |
| | | * The path of the referenced managed object's parent. |
| | | * @param relationDef |
| | | * The instantiable relation in the parent which contains the |
| | | * referenced managed object. |
| | | * @param dnAsString |
| | | * The DN string value. |
| | | * @return Returns the new reference based on the provided DN string value. |
| | | * @throws IllegalArgumentException |
| | | * If the DN string value could not be decoded as a DN or if the |
| | | * provided DN did not correspond to the provided path and |
| | | * relation. |
| | | */ |
| | | public static <C extends ConfigurationClient, S extends Configuration> Reference<C, S> parseDN( |
| | | ManagedObjectPath<?, ?> path, InstantiableRelationDefinition<C, S> relationDef, String dnAsString) { |
| | | AbstractManagedObjectDefinition<?, ?> definition = path.getManagedObjectDefinition(); |
| | | RelationDefinition<?, ?> tmp = definition.getRelationDefinition(relationDef.getName()); |
| | | if (tmp != relationDef) { |
| | | // TODO : i18n ? |
| | | throw new IllegalArgumentException("The relation \"" + relationDef.getName() |
| | | + "\" is not associated with the definition \"" + definition.getName() + "\""); |
| | | } |
| | | |
| | | DN dn = DN.valueOf(dnAsString); |
| | | RDN rdn = dn.rdn(); |
| | | if (rdn == null) { |
| | | // TODO : i18n ? |
| | | throw new IllegalArgumentException("Unabled to decode the DN string: \"" + dnAsString + "\""); |
| | | } |
| | | |
| | | // Check that the DN was valid. |
| | | String name = rdn.getFirstAVA().getAttributeValue().toString(); |
| | | DN expected = path.child(relationDef, name).toDN(); |
| | | if (!dn.equals(expected)) { |
| | | // TODO : i18n ? |
| | | throw new IllegalArgumentException("Unabled to decode the DN string: \"" + dnAsString + "\""); |
| | | } |
| | | |
| | | return new Reference<C, S>(path, relationDef, name); |
| | | } |
| | | |
| | | /** |
| | | * Parses a name as a reference using the provided managed object path and |
| | | * relation definition. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * reference refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * reference refers to. |
| | | * @param p |
| | | * The path of the referenced managed object's parent. |
| | | * @param rd |
| | | * The instantiable relation in the parent which contains the |
| | | * referenced managed object. |
| | | * @param s |
| | | * The name of the referenced managed object. |
| | | * @return Returns the new reference based on the provided name. |
| | | * @throws IllegalArgumentException |
| | | * If the relation is not associated with the provided parent's |
| | | * definition, or if the provided name is empty. |
| | | */ |
| | | public static <C extends ConfigurationClient, S extends Configuration> Reference<C, S> parseName( |
| | | ManagedObjectPath<?, ?> p, InstantiableRelationDefinition<C, S> rd, String s) { |
| | | // Sanity checks. |
| | | AbstractManagedObjectDefinition<?, ?> d = p.getManagedObjectDefinition(); |
| | | RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName()); |
| | | if (tmp != rd) { |
| | | throw new IllegalArgumentException("The relation \"" + rd.getName() |
| | | + "\" is not associated with the definition \"" + d.getName() + "\""); |
| | | } |
| | | |
| | | if (s.trim().length() == 0) { |
| | | throw new IllegalArgumentException("Empty names are not allowed"); |
| | | } |
| | | |
| | | return new Reference<C, S>(p, rd, s); |
| | | } |
| | | |
| | | // The name of the referenced managed object. |
| | | private final String name; |
| | | |
| | | // The path of the referenced managed object. |
| | | private final ManagedObjectPath<C, S> path; |
| | | |
| | | // The instantiable relation in the parent which contains the |
| | | // referenced managed object. |
| | | private final InstantiableRelationDefinition<C, S> relation; |
| | | |
| | | // Private constructor. |
| | | private Reference(ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> relation, String name) { |
| | | this.relation = relation; |
| | | this.name = name; |
| | | this.path = parent.child(relation, name); |
| | | } |
| | | |
| | | /** |
| | | * Gets the name of the referenced managed object. |
| | | * |
| | | * @return Returns the name of the referenced managed object. |
| | | */ |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | /** |
| | | * Gets the normalized name of the referenced managed object. |
| | | * |
| | | * @return Returns the normalized name of the referenced managed object. |
| | | */ |
| | | public String getNormalizedName() { |
| | | PropertyDefinition<?> pd = relation.getNamingPropertyDefinition(); |
| | | return normalizeName(pd); |
| | | } |
| | | |
| | | /** |
| | | * Gets the DN of the referenced managed object. |
| | | * |
| | | * @return Returns the DN of the referenced managed object. |
| | | */ |
| | | public DN toDN() { |
| | | return path.toDN(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public String toString() { |
| | | return name; |
| | | } |
| | | |
| | | // Normalize a value using the specified naming property definition |
| | | // if defined. |
| | | private <T> String normalizeName(PropertyDefinition<T> pd) { |
| | | if (pd != null) { |
| | | try { |
| | | // TODO : is it correct to have no validation ? |
| | | T tvalue = pd.decodeValue(name, PropertyDefinitionsOptions.NO_VALIDATION_OPTIONS); |
| | | return pd.normalizeValue(tvalue); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | // Fall through to default normalization. |
| | | } |
| | | } |
| | | |
| | | // FIXME: should really use directory string normalizer. |
| | | String s = name.trim().replaceAll(" +", " "); |
| | | return toLowerCase(s); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.Locale; |
| | | import java.util.MissingResourceException; |
| | | import java.util.Set; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * Relation definitions define relationships between types of managed objects. |
| | | * In addition they define the ownership model: |
| | | * <ul> |
| | | * <li>composition - referenced managed objects are owned by the parent managed |
| | | * object and are deleted when the parent is deleted |
| | | * <li>aggregation - referenced managed objects are not owned by the parent |
| | | * managed object. Instead they are shared by other managed objects. |
| | | * </ul> |
| | | * Relations define how clients interact with the configuration. For example, |
| | | * clients manage aggregated managed objects in a shared location and attach |
| | | * them to parent managed objects. Composed managed objects, on the other hand, |
| | | * would be created directly beneath the parent managed object and destroyed |
| | | * with it too. |
| | | * <p> |
| | | * Within the server, listeners can choose to request notification of managed |
| | | * objects being added or removed from relations. |
| | | * <p> |
| | | * In LDAP, compositions are represented as follows: |
| | | * <ul> |
| | | * <li>singleton relations (one to one): a referenced managed object is |
| | | * represented using a child entry directly beneath the parent |
| | | * <li>optional relations (one to zero or one): a referenced managed object is |
| | | * represented using a child entry directly beneath the parent |
| | | * <li>instantiable relations (one to many): the relation is represented using a |
| | | * child entry directly beneath the parent. Referenced managed objects are |
| | | * represented using child entries of this "relation entry" and are named by the |
| | | * user |
| | | * <li>set relations (one to many): the relation is represented using a child |
| | | * entry directly beneath the parent. Referenced managed objects are represented |
| | | * using child entries of this "relation entry" whose name is the type of the |
| | | * managed object. |
| | | * </ul> |
| | | * Whereas, aggregations are represented by storing the DNs of the referenced |
| | | * managed objects in an attribute of the aggregating managed object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this relation |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this relation |
| | | * definition refers to. |
| | | */ |
| | | public abstract class RelationDefinition<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing relation definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <D> |
| | | * The type of relation definition constructed by this builder. |
| | | */ |
| | | protected abstract static class AbstractBuilder<C extends ConfigurationClient, S extends Configuration, |
| | | D extends RelationDefinition<C, S>> { |
| | | |
| | | // Common fields. |
| | | private final Common<C, S> common; |
| | | |
| | | /** |
| | | * Create a property definition builder. |
| | | * |
| | | * @param pd |
| | | * The parent managed object definition. |
| | | * @param name |
| | | * The name of the relation. |
| | | * @param cd |
| | | * The child managed object definition. |
| | | */ |
| | | protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> pd, String name, |
| | | AbstractManagedObjectDefinition<C, S> cd) { |
| | | this.common = new Common<C, S>(pd, name, cd); |
| | | } |
| | | |
| | | /** |
| | | * Construct a relation definition based on the properties of this |
| | | * builder. |
| | | * |
| | | * @return The new relation definition. |
| | | */ |
| | | public final D getInstance() { |
| | | return buildInstance(common); |
| | | } |
| | | |
| | | /** |
| | | * Add a relation definition option. |
| | | * |
| | | * @param option |
| | | * The relation option. |
| | | */ |
| | | public final void setOption(RelationOption option) { |
| | | Reject.ifNull(option); |
| | | common.options.add(option); |
| | | } |
| | | |
| | | /** |
| | | * Build a relation definition based on the properties of this builder. |
| | | * |
| | | * @param common |
| | | * The common fields of the new relation definition. |
| | | * @return The new relation definition. |
| | | */ |
| | | protected abstract D buildInstance(Common<C, S> common); |
| | | } |
| | | |
| | | /** |
| | | * Opaque structure containing fields common to all relation definition |
| | | * types. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | */ |
| | | protected static final class Common<C extends ConfigurationClient, S extends Configuration> { |
| | | |
| | | // The definition of the child managed object. |
| | | private final AbstractManagedObjectDefinition<C, S> cd; |
| | | |
| | | // The name of the relation. |
| | | private final String name; |
| | | |
| | | // Options applicable to this definition. |
| | | private final Set<RelationOption> options; |
| | | |
| | | // The definition of the parent managed object. |
| | | private final AbstractManagedObjectDefinition<?, ?> pd; |
| | | |
| | | // Private constructor. |
| | | private Common(AbstractManagedObjectDefinition<?, ?> pd, String name, |
| | | AbstractManagedObjectDefinition<C, S> cd) { |
| | | this.name = name; |
| | | this.pd = pd; |
| | | this.cd = cd; |
| | | this.options = EnumSet.noneOf(RelationOption.class); |
| | | } |
| | | } |
| | | |
| | | // Common fields. |
| | | private final Common<C, S> common; |
| | | |
| | | /** |
| | | * Create a new managed object relation definition with the specified common |
| | | * fields. |
| | | * |
| | | * @param common |
| | | * The common fields of the new relation definition. |
| | | */ |
| | | protected RelationDefinition(Common<C, S> common) { |
| | | this.common = common; |
| | | } |
| | | |
| | | /** |
| | | * Apply a visitor to this relation definition. |
| | | * |
| | | * @param <R> |
| | | * The return type of the visitor's methods. |
| | | * @param <P> |
| | | * The type of the additional parameters to the visitor's |
| | | * methods. |
| | | * @param v |
| | | * The relation definition visitor. |
| | | * @param p |
| | | * Optional additional visitor parameter. |
| | | * @return Returns a result as specified by the visitor. |
| | | */ |
| | | public abstract <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p); |
| | | |
| | | /** |
| | | * Get the definition of the child managed object. |
| | | * |
| | | * @return Returns the definition of the child managed object. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<C, S> getChildDefinition() { |
| | | return common.cd; |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional description of this relation definition in the default |
| | | * locale. |
| | | * |
| | | * @return Returns the description of this relation definition in the |
| | | * default locale, or <code>null</code> if there is no description. |
| | | */ |
| | | public final LocalizableMessage getDescription() { |
| | | return getDescription(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional description of this relation definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the description of this relation definition in the |
| | | * specified locale, or <code>null</code> if there is no |
| | | * description. |
| | | */ |
| | | public final LocalizableMessage getDescription(Locale locale) { |
| | | try { |
| | | String property = "relation." + common.name + ".description"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, |
| | | locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the name of the relation. |
| | | * |
| | | * @return Returns the name of the relation. |
| | | */ |
| | | public final String getName() { |
| | | return common.name; |
| | | } |
| | | |
| | | /** |
| | | * Get the definition of the parent managed object. |
| | | * |
| | | * @return Returns the definition of the parent managed object. |
| | | */ |
| | | public final AbstractManagedObjectDefinition<?, ?> getParentDefinition() { |
| | | return common.pd; |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this relation definition in the default locale. |
| | | * |
| | | * @return Returns the synopsis of this relation definition in the default |
| | | * locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this relation definition in the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this relation definition in the specified |
| | | * locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis(Locale locale) { |
| | | String property = "relation." + common.name + ".synopsis"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly name of this relation definition in the default |
| | | * locale. |
| | | * |
| | | * @return Returns the user friendly name of this relation definition in the |
| | | * default locale. |
| | | */ |
| | | public final LocalizableMessage getUserFriendlyName() { |
| | | return getUserFriendlyName(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly name of this relation definition in the specified |
| | | * locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the user friendly name of this relation definition in the |
| | | * specified locale. |
| | | */ |
| | | public final LocalizableMessage getUserFriendlyName(Locale locale) { |
| | | String property = "relation." + common.name + ".user-friendly-name"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | /** |
| | | * Check if the specified option is set for this relation definition. |
| | | * |
| | | * @param option |
| | | * The option to test. |
| | | * @return Returns <code>true</code> if the option is set, or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public final boolean hasOption(RelationOption option) { |
| | | return common.options.contains(option); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | toString(builder); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Append a string representation of the managed object relation to the |
| | | * provided string builder. |
| | | * |
| | | * @param builder |
| | | * The string builder where the string representation should be |
| | | * appended. |
| | | */ |
| | | public abstract void toString(StringBuilder builder); |
| | | |
| | | /** |
| | | * Performs any run-time initialization required by this relation |
| | | * definition. This may include resolving managed object paths and property |
| | | * names. |
| | | * |
| | | * @throws Exception |
| | | * If this relation definition could not be initialized. |
| | | */ |
| | | protected void initialize() throws Exception { |
| | | // No implementation required. |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A visitor of relation definitions, in the style of the visitor design |
| | | * pattern. Classes implementing this interface can query relation definitions |
| | | * in a type-safe manner when the kind of relation definition is unknown at |
| | | * compile time. When a visitor is passed to a relation definition's accept |
| | | * method, the corresponding visit method most applicable to that relation |
| | | * definition is invoked. |
| | | * |
| | | * @param <R> |
| | | * The return type of this visitor's methods. Use |
| | | * {@link java.lang.Void} for visitors that do not need to return |
| | | * results. |
| | | * @param <P> |
| | | * The type of the additional parameter to this visitor's methods. |
| | | * Use {@link java.lang.Void} for visitors that do not need an |
| | | * additional parameter. |
| | | */ |
| | | public interface RelationDefinitionVisitor<R, P> { |
| | | |
| | | /** |
| | | * Visit an instantiable relation 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 rd |
| | | * The instantiable relation definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> R visitInstantiable( |
| | | InstantiableRelationDefinition<C, S> rd, P p); |
| | | |
| | | /** |
| | | * Visit a set relation 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 rd |
| | | * The set relation definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> R visitSet(SetRelationDefinition<C, S> rd, P p); |
| | | |
| | | /** |
| | | * Visit an optional relation 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 rd |
| | | * The optional relation definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> R visitOptional(OptionalRelationDefinition<C, S> rd, P p); |
| | | |
| | | /** |
| | | * Visit a singleton relation 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 rd |
| | | * The singleton relation definition to visit. |
| | | * @param p |
| | | * A visitor specified parameter. |
| | | * @return Returns a visitor specified result. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> R visitSingleton(SingletonRelationDefinition<C, S> rd, |
| | | P p); |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * This enumeration contains various options that can be associated with |
| | | * relation definitions. |
| | | */ |
| | | public enum RelationOption { |
| | | /** |
| | | * Use this option to identify relations which should be considered as |
| | | * advanced and should not be exposed by default in client applications. |
| | | */ |
| | | ADVANCED, |
| | | |
| | | /** |
| | | * Use this option to identify relations which must not be directly exposed |
| | | * in client applications. |
| | | */ |
| | | HIDDEN; |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A default behavior provider which retrieves default values from a parent |
| | | * managed object. It should be used by properties which inherit their default |
| | | * value(s) from properties held in an other managed object. |
| | | * |
| | | * @param <T> |
| | | * The type of values represented by this provider. |
| | | */ |
| | | public final class RelativeInheritedDefaultBehaviorProvider<T> extends DefaultBehaviorProvider<T> { |
| | | |
| | | // The type of managed object expected at the relative offset. |
| | | private final AbstractManagedObjectDefinition<?, ?> d; |
| | | |
| | | // The relative offset (where 1 = parent, 2 = grandparent) of the |
| | | // managed object containing the property. |
| | | private final int offset; |
| | | |
| | | // The name of the property containing the inherited default values. |
| | | private final String propertyName; |
| | | |
| | | /** |
| | | * Create a relative inherited default behavior provider associated with a |
| | | * parent managed object. |
| | | * |
| | | * @param d |
| | | * The type of parent managed object expected at the relative |
| | | * location. |
| | | * @param propertyName |
| | | * The name of the property containing the inherited default |
| | | * values. |
| | | * @param offset |
| | | * The relative location of the parent managed object (where 0 is |
| | | * the managed object itself, 1 is the parent, and 2 is the |
| | | * grand-parent). |
| | | * @throws IllegalArgumentException |
| | | * If the offset is less than 0. |
| | | */ |
| | | public RelativeInheritedDefaultBehaviorProvider(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | int offset) { |
| | | // We do not decode the property name now because the property |
| | | // might not have been constructed at this point (e.g. when the |
| | | // offset is 0). |
| | | if (offset < 0) { |
| | | throw new IllegalArgumentException("Negative offset"); |
| | | } |
| | | this.d = d; |
| | | this.propertyName = propertyName; |
| | | this.offset = offset; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <R, P> R accept(DefaultBehaviorProviderVisitor<T, R, P> v, P p) { |
| | | return v.visitRelativeInherited(this, p); |
| | | } |
| | | |
| | | /** |
| | | * Get the definition of the parent managed object containing the inherited |
| | | * default values. |
| | | * |
| | | * @return Returns the definition of the parent managed object containing |
| | | * the inherited default values. |
| | | */ |
| | | public AbstractManagedObjectDefinition<?, ?> getManagedObjectDefinition() { |
| | | return d; |
| | | } |
| | | |
| | | /** |
| | | * Get the absolute path of the managed object containing the property which |
| | | * has the default values. |
| | | * |
| | | * @param path |
| | | * The path of the current managed object from which the relative |
| | | * path should be determined. |
| | | * @return Returns the absolute path of the managed object containing the |
| | | * property which has the default values. |
| | | */ |
| | | public ManagedObjectPath<?, ?> getManagedObjectPath(ManagedObjectPath<?, ?> path) { |
| | | return path.parent(offset); |
| | | } |
| | | |
| | | /** |
| | | * Gets the name of the property containing the inherited default values. |
| | | * |
| | | * @return Returns the name of the property containing the inherited default |
| | | * values. |
| | | */ |
| | | public String getPropertyName() { |
| | | return propertyName; |
| | | } |
| | | |
| | | /** |
| | | * Get the relative location of the parent managed object. |
| | | * |
| | | * @return Returns the relative location of the parent managed object (where |
| | | * 0 is the managed object itself, 1 is the parent, and 2 is the |
| | | * grand-parent). |
| | | */ |
| | | public int getRelativeOffset() { |
| | | return offset; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * A managed object composite relationship definition which represents a |
| | | * composition of zero or more managed objects each of which must have a |
| | | * different type. The manage objects are named using their type name. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this relation |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this relation |
| | | * definition refers to. |
| | | */ |
| | | public final class SetRelationDefinition<C extends ConfigurationClient, S extends Configuration> extends |
| | | RelationDefinition<C, S> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing set relation definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | */ |
| | | public static final class Builder<C extends ConfigurationClient, S extends Configuration> extends |
| | | AbstractBuilder<C, S, SetRelationDefinition<C, S>> { |
| | | |
| | | // The plural name of the relation. |
| | | private final String pluralName; |
| | | |
| | | // The optional default managed objects associated with this |
| | | // set relation definition. |
| | | private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects = |
| | | new HashMap<String, DefaultManagedObject<? extends C, ? extends S>>(); |
| | | |
| | | /** |
| | | * Creates a new builder which can be used to incrementally build a set |
| | | * relation definition. |
| | | * |
| | | * @param pd |
| | | * The parent managed object definition. |
| | | * @param name |
| | | * The name of the relation. |
| | | * @param pluralName |
| | | * The plural name of the relation. |
| | | * @param cd |
| | | * The child managed object definition. |
| | | */ |
| | | public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name, String pluralName, |
| | | AbstractManagedObjectDefinition<C, S> cd) { |
| | | super(pd, name, cd); |
| | | this.pluralName = pluralName; |
| | | } |
| | | |
| | | /** |
| | | * Adds the default managed object to this set relation definition. |
| | | * |
| | | * @param defaultManagedObject |
| | | * The default managed object. |
| | | */ |
| | | public void setDefaultManagedObject(DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) { |
| | | this.defaultManagedObjects.put(defaultManagedObject.getManagedObjectDefinition().getName(), |
| | | defaultManagedObject); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected SetRelationDefinition<C, S> buildInstance(Common<C, S> common) { |
| | | return new SetRelationDefinition<C, S>(common, pluralName, defaultManagedObjects); |
| | | } |
| | | |
| | | } |
| | | |
| | | // The plural name of the relation. |
| | | private final String pluralName; |
| | | |
| | | // The optional default managed objects associated with this |
| | | // set relation definition. |
| | | private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects; |
| | | |
| | | // Private constructor. |
| | | private SetRelationDefinition(Common<C, S> common, String pluralName, |
| | | Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects) { |
| | | super(common); |
| | | this.pluralName = pluralName; |
| | | this.defaultManagedObjects = defaultManagedObjects; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitSet(this, p); |
| | | } |
| | | |
| | | /** |
| | | * Gets the named default managed object associated with this set relation |
| | | * definition. |
| | | * |
| | | * @param name |
| | | * The name of the default managed object (for set relations this |
| | | * is the type of the default managed object). |
| | | * @return The named default managed object. |
| | | * @throws IllegalArgumentException |
| | | * If there is no default managed object associated with the |
| | | * provided name. |
| | | */ |
| | | public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(String name) { |
| | | if (!defaultManagedObjects.containsKey(name)) { |
| | | throw new IllegalArgumentException("unrecognized default managed object \"" + name + "\""); |
| | | } |
| | | return defaultManagedObjects.get(name); |
| | | } |
| | | |
| | | /** |
| | | * Gets the names of the default managed objects associated with this set |
| | | * relation definition. |
| | | * |
| | | * @return An unmodifiable set containing the names of the default managed |
| | | * object. |
| | | */ |
| | | public Set<String> getDefaultManagedObjectNames() { |
| | | return Collections.unmodifiableSet(defaultManagedObjects.keySet()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the plural name of the relation. |
| | | * |
| | | * @return The plural name of the relation. |
| | | */ |
| | | public String getPluralName() { |
| | | return pluralName; |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly plural name of this relation definition in the |
| | | * default locale. |
| | | * |
| | | * @return Returns the user friendly plural name of this relation definition |
| | | * in the default locale. |
| | | */ |
| | | public LocalizableMessage getUserFriendlyPluralName() { |
| | | return getUserFriendlyPluralName(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly plural name of this relation definition in the |
| | | * specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the user friendly plural name of this relation definition |
| | | * in the specified locale. |
| | | */ |
| | | public LocalizableMessage getUserFriendlyPluralName(Locale locale) { |
| | | String property = "relation." + getName() + ".user-friendly-plural-name"; |
| | | return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | builder.append("name="); |
| | | builder.append(getName()); |
| | | builder.append(" type=set parent="); |
| | | builder.append(getParentDefinition().getName()); |
| | | builder.append(" child="); |
| | | builder.append(getChildDefinition().getName()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) { |
| | | dmo.initialize(); |
| | | } |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A managed object composite relationship definition which represents a |
| | | * composition of a single managed object (i.e. the managed object must be |
| | | * present). |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this relation |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this relation |
| | | * definition refers to. |
| | | */ |
| | | public final class SingletonRelationDefinition<C extends ConfigurationClient, S extends Configuration> extends |
| | | RelationDefinition<C, S> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing singleton relation |
| | | * definitions. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that this |
| | | * relation definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that this |
| | | * relation definition refers to. |
| | | */ |
| | | public static final class Builder<C extends ConfigurationClient, S extends Configuration> extends |
| | | AbstractBuilder<C, S, SingletonRelationDefinition<C, S>> { |
| | | |
| | | // The optional default managed object associated with this |
| | | // singleton relation. |
| | | private DefaultManagedObject<? extends C, ? extends S> defaultManagedObject = null; |
| | | |
| | | /** |
| | | * Creates a new builder which can be used to incrementally build an |
| | | * singleton relation definition. |
| | | * |
| | | * @param pd |
| | | * The parent managed object definition. |
| | | * @param name |
| | | * The name of the relation. |
| | | * @param cd |
| | | * The child managed object definition. |
| | | */ |
| | | // @Checkstyle:ignore |
| | | public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name, AbstractManagedObjectDefinition<C, S> cd) { |
| | | super(pd, name, cd); |
| | | } |
| | | |
| | | /** |
| | | * Sets the optional default managed object associated with this |
| | | * singleton relation definition. |
| | | * |
| | | * @param defaultManagedObject |
| | | * The default managed object or <code>null</code> if there |
| | | * is no default managed object defined for this relation |
| | | * definition. |
| | | */ |
| | | public void setDefaultManagedObject(DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) { |
| | | this.defaultManagedObject = defaultManagedObject; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected SingletonRelationDefinition<C, S> buildInstance(Common<C, S> common) { |
| | | return new SingletonRelationDefinition<C, S>(common, defaultManagedObject); |
| | | } |
| | | |
| | | } |
| | | |
| | | // The optional default managed object associated with this |
| | | // singleton relation. |
| | | private final DefaultManagedObject<? extends C, ? extends S> defaultManagedObject; |
| | | |
| | | // Private constructor. |
| | | private SingletonRelationDefinition(Common<C, S> common, |
| | | DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) { |
| | | super(common); |
| | | this.defaultManagedObject = defaultManagedObject; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitSingleton(this, p); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional default managed object associated with this singleton |
| | | * relation definition. |
| | | * |
| | | * @return Returns the default managed object or <code>null</code> if there |
| | | * is no default managed object defined for this relation |
| | | * definition. |
| | | */ |
| | | public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject() { |
| | | return defaultManagedObject; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | builder.append("name="); |
| | | builder.append(getName()); |
| | | builder.append(" type=singleton parent="); |
| | | builder.append(getParentDefinition().getName()); |
| | | builder.append(" child="); |
| | | builder.append(getChildDefinition().getName()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void initialize() throws Exception { |
| | | if (defaultManagedObject != null) { |
| | | defaultManagedObject.initialize(); |
| | | } |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | |
| | | /** |
| | | * Memory size property definition. |
| | | * <p> |
| | | * All memory size property values are represented in bytes using longs. |
| | | * <p> |
| | | * All values must be zero or positive and within the lower/upper limit |
| | | * constraints. Support is provided for "unlimited" memory sizes. These are |
| | | * represented using a negative memory size value or using the string |
| | | * "unlimited". |
| | | */ |
| | | public final class SizePropertyDefinition extends PropertyDefinition<Long> { |
| | | |
| | | // String used to represent unlimited memory sizes. |
| | | private static final String UNLIMITED = "unlimited"; |
| | | |
| | | // The lower limit of the property value in bytes. |
| | | private final long lowerLimit; |
| | | |
| | | // The optional upper limit of the property value in bytes. |
| | | private final Long upperLimit; |
| | | |
| | | // Indicates whether this property allows the use of the "unlimited" memory |
| | | // size value (represented using a -1L or the string "unlimited"). |
| | | private final boolean allowUnlimited; |
| | | |
| | | /** |
| | | * An interface for incrementally constructing memory size property |
| | | * definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<Long, SizePropertyDefinition> { |
| | | |
| | | // The lower limit of the property value in bytes. |
| | | private long lowerLimit = 0L; |
| | | |
| | | // The optional upper limit of the property value in bytes. |
| | | private Long upperLimit = null; |
| | | |
| | | // Indicates whether this property allows the use of the "unlimited" |
| | | // memory |
| | | // size value (represented using a -1L or the string "unlimited"). |
| | | private boolean allowUnlimited = false; |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * Set the lower limit in bytes. |
| | | * |
| | | * @param lowerLimit |
| | | * The new lower limit (must be >= 0) in bytes. |
| | | * @throws IllegalArgumentException |
| | | * If a negative lower limit was specified, or if the lower |
| | | * limit is greater than the upper limit. |
| | | */ |
| | | public final void setLowerLimit(long lowerLimit) { |
| | | if (lowerLimit < 0) { |
| | | throw new IllegalArgumentException("Negative lower limit"); |
| | | } |
| | | if (upperLimit != null && lowerLimit > upperLimit) { |
| | | throw new IllegalArgumentException("Lower limit greater than upper limit"); |
| | | } |
| | | this.lowerLimit = lowerLimit; |
| | | } |
| | | |
| | | /** |
| | | * Set the lower limit using a string representation of the limit. |
| | | * |
| | | * @param lowerLimit |
| | | * The string representation of the new lower limit. |
| | | * @throws IllegalArgumentException |
| | | * If the lower limit could not be parsed, or if a negative |
| | | * lower limit was specified, or the lower limit is greater |
| | | * than the upper limit. |
| | | */ |
| | | public final void setLowerLimit(String lowerLimit) { |
| | | setLowerLimit(SizeUnit.parseValue(lowerLimit, SizeUnit.BYTES)); |
| | | } |
| | | |
| | | /** |
| | | * Set the upper limit in bytes. |
| | | * |
| | | * @param upperLimit |
| | | * The new upper limit in bytes or <code>null</code> if there |
| | | * is no upper limit. |
| | | * @throws IllegalArgumentException |
| | | * If the lower limit is greater than the upper limit. |
| | | */ |
| | | public final void setUpperLimit(Long upperLimit) { |
| | | if (upperLimit != null) { |
| | | if (upperLimit < 0) { |
| | | throw new IllegalArgumentException("Negative upper limit"); |
| | | } |
| | | if (lowerLimit > upperLimit) { |
| | | throw new IllegalArgumentException("Lower limit greater than upper limit"); |
| | | } |
| | | } |
| | | this.upperLimit = upperLimit; |
| | | } |
| | | |
| | | /** |
| | | * Set the upper limit using a string representation of the limit. |
| | | * |
| | | * @param upperLimit |
| | | * The string representation of the new upper limit, or |
| | | * <code>null</code> if there is no upper limit. |
| | | * @throws IllegalArgumentException |
| | | * If the upper limit could not be parsed, or if the lower |
| | | * limit is greater than the upper limit. |
| | | */ |
| | | public final void setUpperLimit(String upperLimit) { |
| | | if (upperLimit == null) { |
| | | setUpperLimit((Long) null); |
| | | } else { |
| | | setUpperLimit(SizeUnit.parseValue(upperLimit, SizeUnit.BYTES)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Specify whether or not this property definition will allow unlimited |
| | | * values (default is false). |
| | | * |
| | | * @param allowUnlimited |
| | | * <code>true</code> if the property will allow unlimited |
| | | * values, or <code>false</code> otherwise. |
| | | */ |
| | | public final void setAllowUnlimited(boolean allowUnlimited) { |
| | | this.allowUnlimited = allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected SizePropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Long> defaultBehavior) { |
| | | return new SizePropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, lowerLimit, |
| | | upperLimit, allowUnlimited); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Create an memory size property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new integer property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Private constructor. |
| | | private SizePropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<Long> defaultBehavior, Long lowerLimit, Long upperLimit, boolean allowUnlimited) { |
| | | super(d, Long.class, propertyName, options, adminAction, defaultBehavior); |
| | | this.lowerLimit = lowerLimit; |
| | | this.upperLimit = upperLimit; |
| | | this.allowUnlimited = allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * Get the lower limit in bytes. |
| | | * |
| | | * @return Returns the lower limit in bytes. |
| | | */ |
| | | public long getLowerLimit() { |
| | | return lowerLimit; |
| | | } |
| | | |
| | | /** |
| | | * Get the upper limit in bytes. |
| | | * |
| | | * @return Returns the upper limit in bytes or <code>null</code> if there is |
| | | * no upper limit. |
| | | */ |
| | | public Long getUpperLimit() { |
| | | return upperLimit; |
| | | } |
| | | |
| | | /** |
| | | * Determine whether this property allows unlimited memory sizes. |
| | | * |
| | | * @return Returns <code>true</code> if this this property allows unlimited |
| | | * memory sizes. |
| | | */ |
| | | public boolean isAllowUnlimited() { |
| | | return allowUnlimited; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(Long value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | if (!allowUnlimited && value < lowerLimit) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | |
| | | // unlimited allowed |
| | | } else if (value >= 0 && value < lowerLimit) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | |
| | | if ((upperLimit != null) && (value > upperLimit)) { |
| | | throw new IllegalPropertyValueException(this, value); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String encodeValue(Long value) { |
| | | Reject.ifNull(value); |
| | | |
| | | // Make sure that we correctly encode negative values as "unlimited". |
| | | if (allowUnlimited) { |
| | | if (value < 0) { |
| | | return UNLIMITED; |
| | | } |
| | | } |
| | | |
| | | // Encode the size value using the best-fit unit. |
| | | StringBuilder builder = new StringBuilder(); |
| | | SizeUnit unit = SizeUnit.getBestFitUnitExact(value); |
| | | |
| | | // Cast to a long to remove fractional part (which should not be there |
| | | // anyway as the best-fit unit should result in an exact conversion). |
| | | builder.append((long) unit.fromBytes(value)); |
| | | builder.append(' '); |
| | | builder.append(unit.toString()); |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Long decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | // First check for the special "unlimited" value when necessary. |
| | | if (allowUnlimited) { |
| | | if (value.trim().equalsIgnoreCase(UNLIMITED)) { |
| | | return -1L; |
| | | } |
| | | } |
| | | |
| | | // Decode the value. |
| | | Long i; |
| | | try { |
| | | i = SizeUnit.parseValue(value, SizeUnit.BYTES); |
| | | } catch (NumberFormatException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | |
| | | try { |
| | | validateValue(i, options); |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | return i; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitSize(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, Long value, P p) { |
| | | return v.visitSize(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void toString(StringBuilder builder) { |
| | | super.toString(builder); |
| | | |
| | | builder.append(" lowerLimit="); |
| | | builder.append(lowerLimit); |
| | | |
| | | if (upperLimit != null) { |
| | | builder.append(" upperLimit="); |
| | | builder.append(upperLimit); |
| | | } |
| | | |
| | | builder.append(" allowUnlimited="); |
| | | builder.append(allowUnlimited); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public int compare(Long o1, Long o2) { |
| | | return o1.compareTo(o2); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * This enumeration defines various memory size units. |
| | | */ |
| | | public enum SizeUnit { |
| | | |
| | | /** |
| | | * A byte unit. |
| | | */ |
| | | BYTES(1L, "b", "bytes"), |
| | | |
| | | /** |
| | | * A gibi-byte unit. |
| | | */ |
| | | GIBI_BYTES((long) 1024 * 1024 * 1024, "gib", "gibibytes"), |
| | | |
| | | /** |
| | | * A giga-byte unit. |
| | | */ |
| | | GIGA_BYTES((long) 1000 * 1000 * 1000, "gb", "gigabytes"), |
| | | |
| | | /** |
| | | * A kibi-byte unit. |
| | | */ |
| | | KIBI_BYTES(1024L, "kib", "kibibytes"), |
| | | |
| | | /** |
| | | * A kilo-byte unit. |
| | | */ |
| | | KILO_BYTES(1000L, "kb", "kilobytes"), |
| | | |
| | | /** |
| | | * A mebi-byte unit. |
| | | */ |
| | | MEBI_BYTES((long) 1024 * 1024, "mib", "mebibytes"), |
| | | |
| | | /** |
| | | * A mega-byte unit. |
| | | */ |
| | | MEGA_BYTES((long) 1000 * 1000, "mb", "megabytes"), |
| | | |
| | | /** |
| | | * A tebi-byte unit. |
| | | */ |
| | | TEBI_BYTES((long) 1024 * 1024 * 1024 * 1024, "tib", "tebibytes"), |
| | | |
| | | /** |
| | | * A tera-byte unit. |
| | | */ |
| | | TERA_BYTES((long) 1000 * 1000 * 1000 * 1000, "tb", "terabytes"); |
| | | |
| | | // A lookup table for resolving a unit from its name. |
| | | private static final Map<String, SizeUnit> NAME_TO_UNIT; |
| | | static { |
| | | NAME_TO_UNIT = new HashMap<String, SizeUnit>(); |
| | | |
| | | for (SizeUnit unit : SizeUnit.values()) { |
| | | NAME_TO_UNIT.put(unit.shortName, unit); |
| | | NAME_TO_UNIT.put(unit.longName, unit); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the best-fit unit for the specified number of bytes. The returned |
| | | * unit will be able to represent the number of bytes using a decimal number |
| | | * comprising of an integer part which is greater than zero. Bigger units |
| | | * are chosen in preference to smaller units and binary units are only |
| | | * returned if they are an exact fit. If the number of bytes is zero then |
| | | * the {@link #BYTES} unit is always returned. For example: |
| | | * |
| | | * <pre> |
| | | * getBestFitUnit(0) // BYTES |
| | | * getBestFitUnit(999) // BYTES |
| | | * getBestFitUnit(1000) // KILO_BYTES |
| | | * getBestFitUnit(1024) // KIBI_BYTES |
| | | * getBestFitUnit(1025) // KILO_BYTES |
| | | * getBestFitUnit(999999) // KILO_BYTES |
| | | * getBestFitUnit(1000000) // MEGA_BYTES |
| | | * </pre> |
| | | * |
| | | * @param bytes |
| | | * The number of bytes. |
| | | * @return Returns the best fit unit. |
| | | * @throws IllegalArgumentException |
| | | * If <code>bytes</code> is negative. |
| | | * @see #getBestFitUnitExact(long) |
| | | */ |
| | | public static SizeUnit getBestFitUnit(long bytes) { |
| | | if (bytes < 0) { |
| | | throw new IllegalArgumentException("negative number of bytes: " + bytes); |
| | | } else if (bytes == 0) { |
| | | // Always use bytes for zero values. |
| | | return BYTES; |
| | | } else { |
| | | // Determine best fit: prefer non-binary units unless binary |
| | | // fits exactly. |
| | | SizeUnit[] nonBinary = new SizeUnit[] { TERA_BYTES, GIGA_BYTES, MEGA_BYTES, KILO_BYTES }; |
| | | SizeUnit[] binary = new SizeUnit[] { TEBI_BYTES, GIBI_BYTES, MEBI_BYTES, KIBI_BYTES }; |
| | | |
| | | for (int i = 0; i < nonBinary.length; i++) { |
| | | if ((bytes % binary[i].getSize()) == 0) { |
| | | return binary[i]; |
| | | } else if ((bytes / nonBinary[i].getSize()) > 0) { |
| | | return nonBinary[i]; |
| | | } |
| | | } |
| | | |
| | | return BYTES; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the best-fit unit for the specified number of bytes which can |
| | | * represent the provided value using an integral value. Bigger units are |
| | | * chosen in preference to smaller units. If the number of bytes is zero |
| | | * then the {@link #BYTES} unit is always returned. For example: |
| | | * |
| | | * <pre> |
| | | * getBestFitUnitExact(0) // BYTES |
| | | * getBestFitUnitExact(999) // BYTES |
| | | * getBestFitUnitExact(1000) // KILO_BYTES |
| | | * getBestFitUnitExact(1024) // KIBI_BYTES |
| | | * getBestFitUnitExact(1025) // BYTES |
| | | * getBestFitUnitExact(999999) // BYTES |
| | | * getBestFitUnitExact(1000000) // MEGA_BYTES |
| | | * </pre> |
| | | * |
| | | * @param bytes |
| | | * The number of bytes. |
| | | * @return Returns the best fit unit can represent the provided value using |
| | | * an integral value. |
| | | * @throws IllegalArgumentException |
| | | * If <code>bytes</code> is negative. |
| | | * @see #getBestFitUnit(long) |
| | | */ |
| | | public static SizeUnit getBestFitUnitExact(long bytes) { |
| | | if (bytes < 0) { |
| | | throw new IllegalArgumentException("negative number of bytes: " + bytes); |
| | | } else if (bytes == 0) { |
| | | // Always use bytes for zero values. |
| | | return BYTES; |
| | | } else { |
| | | // Determine best fit. |
| | | SizeUnit[] units = |
| | | new SizeUnit[] { TEBI_BYTES, TERA_BYTES, GIBI_BYTES, GIGA_BYTES, MEBI_BYTES, MEGA_BYTES, KIBI_BYTES, |
| | | KILO_BYTES }; |
| | | |
| | | for (SizeUnit unit : units) { |
| | | if ((bytes % unit.getSize()) == 0) { |
| | | return unit; |
| | | } |
| | | } |
| | | |
| | | return BYTES; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the unit corresponding to the provided unit name. |
| | | * |
| | | * @param s |
| | | * The name of the unit. Can be the abbreviated or long name and |
| | | * can contain white space and mixed case characters. |
| | | * @return Returns the unit corresponding to the provided unit name. |
| | | * @throws IllegalArgumentException |
| | | * If the provided name did not correspond to a known memory |
| | | * size unit. |
| | | */ |
| | | public static SizeUnit getUnit(String s) { |
| | | SizeUnit unit = NAME_TO_UNIT.get(s.trim().toLowerCase()); |
| | | if (unit == null) { |
| | | throw new IllegalArgumentException("Illegal memory size unit \"" + s + "\""); |
| | | } |
| | | return unit; |
| | | } |
| | | |
| | | /** |
| | | * Parse the provided size string and return its equivalent size in bytes. |
| | | * The size string must specify the unit e.g. "10kb". |
| | | * |
| | | * @param s |
| | | * The size string to be parsed. |
| | | * @return Returns the parsed duration in bytes. |
| | | * @throws NumberFormatException |
| | | * If the provided size string could not be parsed. |
| | | */ |
| | | public static long parseValue(String s) { |
| | | return parseValue(s, null); |
| | | } |
| | | |
| | | /** |
| | | * Parse the provided size string and return its equivalent size in bytes. |
| | | * |
| | | * @param s |
| | | * The size string to be parsed. |
| | | * @param defaultUnit |
| | | * The default unit to use if there is no unit specified in the |
| | | * size string, or <code>null</code> if the string must always |
| | | * contain a unit. |
| | | * @return Returns the parsed size in bytes. |
| | | * @throws NumberFormatException |
| | | * If the provided size string could not be parsed. |
| | | */ |
| | | public static long parseValue(String s, SizeUnit defaultUnit) { |
| | | // Value must be a floating point number followed by a unit. |
| | | Pattern p = Pattern.compile("^\\s*(\\d+(\\.\\d+)?)\\s*(\\w+)?\\s*$"); |
| | | Matcher m = p.matcher(s); |
| | | |
| | | if (!m.matches()) { |
| | | throw new NumberFormatException("Invalid size value \"" + s + "\""); |
| | | } |
| | | |
| | | // Group 1 is the float. |
| | | double d; |
| | | try { |
| | | d = Double.valueOf(m.group(1)); |
| | | } catch (NumberFormatException e) { |
| | | throw new NumberFormatException("Invalid size value \"" + s + "\""); |
| | | } |
| | | |
| | | // Group 3 is the unit. |
| | | String unitString = m.group(3); |
| | | SizeUnit unit; |
| | | if (unitString == null) { |
| | | if (defaultUnit == null) { |
| | | throw new NumberFormatException("Invalid size value \"" + s + "\""); |
| | | } else { |
| | | unit = defaultUnit; |
| | | } |
| | | } else { |
| | | try { |
| | | unit = getUnit(unitString); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new NumberFormatException("Invalid size value \"" + s + "\""); |
| | | } |
| | | } |
| | | |
| | | return unit.toBytes(d); |
| | | } |
| | | |
| | | // The long name of the unit. |
| | | private final String longName; |
| | | |
| | | // The abbreviation of the unit. |
| | | private final String shortName; |
| | | |
| | | // The size of the unit in bytes. |
| | | private final long sz; |
| | | |
| | | // Private constructor. |
| | | private SizeUnit(long sz, String shortName, String longName) { |
| | | this.sz = sz; |
| | | this.shortName = shortName; |
| | | this.longName = longName; |
| | | } |
| | | |
| | | /** |
| | | * Converts the specified size in bytes to this unit. |
| | | * |
| | | * @param amount |
| | | * The size in bytes. |
| | | * @return Returns size in this unit. |
| | | */ |
| | | public double fromBytes(long amount) { |
| | | return ((double) amount / sz); |
| | | } |
| | | |
| | | /** |
| | | * Get the long name of this unit. |
| | | * |
| | | * @return Returns the long name of this unit. |
| | | */ |
| | | public String getLongName() { |
| | | return longName; |
| | | } |
| | | |
| | | /** |
| | | * Get the abbreviated name of this unit. |
| | | * |
| | | * @return Returns the abbreviated name of this unit. |
| | | */ |
| | | public String getShortName() { |
| | | return shortName; |
| | | } |
| | | |
| | | /** |
| | | * Get the number of bytes that this unit represents. |
| | | * |
| | | * @return Returns the number of bytes that this unit represents. |
| | | */ |
| | | public long getSize() { |
| | | return sz; |
| | | } |
| | | |
| | | /** |
| | | * Converts the specified size in this unit to bytes. |
| | | * |
| | | * @param amount |
| | | * The size as a quantity of this unit. |
| | | * @return Returns the number of bytes that the size represents. |
| | | * @throws NumberFormatException |
| | | * If the provided size exceeded long.MAX_VALUE. |
| | | */ |
| | | public long toBytes(double amount) { |
| | | double value = sz * amount; |
| | | if (value > Long.MAX_VALUE) { |
| | | throw new NumberFormatException("number too big (exceeded long.MAX_VALUE"); |
| | | } |
| | | return (long) (value); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | * <p> |
| | | * This implementation returns the abbreviated name of this size unit. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return shortName; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.EnumSet; |
| | | import java.util.Locale; |
| | | import java.util.MissingResourceException; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | import java.util.regex.PatternSyntaxException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * String property definition. |
| | | */ |
| | | public final class StringPropertyDefinition extends PropertyDefinition<String> { |
| | | |
| | | /** |
| | | * An interface for incrementally constructing string property definitions. |
| | | */ |
| | | public static final class Builder extends AbstractBuilder<String, StringPropertyDefinition> { |
| | | |
| | | // Flag indicating whether values of this property are |
| | | // case-insensitive. |
| | | private boolean isCaseInsensitive = true; |
| | | |
| | | // Optional pattern which values of this property must match. |
| | | private Pattern pattern = null; |
| | | |
| | | // Pattern usage which provides a user-friendly summary of the |
| | | // pattern if present. |
| | | private String patternUsage = null; |
| | | |
| | | // Private constructor |
| | | private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | super(d, propertyName); |
| | | } |
| | | |
| | | /** |
| | | * Set a flag indicating whether values of this property are |
| | | * case-insensitive. |
| | | * |
| | | * @param value |
| | | * <code>true</code> if values are case-insensitive, or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public final void setCaseInsensitive(boolean value) { |
| | | isCaseInsensitive = value; |
| | | } |
| | | |
| | | /** |
| | | * Set the regular expression pattern which values of this property must |
| | | * match. By default there is no pattern defined. |
| | | * |
| | | * @param pattern |
| | | * The regular expression pattern string, or |
| | | * <code>null</code> if there is no pattern. |
| | | * @param patternUsage |
| | | * A user-friendly usage string representing the pattern |
| | | * which can be used in error messages and help (e.g. for |
| | | * patterns which match a host/port combination, the usage |
| | | * string "HOST:PORT" would be appropriate). |
| | | * @throws PatternSyntaxException |
| | | * If the provided regular expression pattern has an invalid |
| | | * syntax. |
| | | */ |
| | | public final void setPattern(String pattern, String patternUsage) { |
| | | if (pattern == null) { |
| | | this.pattern = null; |
| | | this.patternUsage = null; |
| | | } else { |
| | | this.pattern = Pattern.compile(pattern); |
| | | this.patternUsage = patternUsage; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected StringPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, |
| | | String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<String> defaultBehavior) { |
| | | return new StringPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, |
| | | isCaseInsensitive, pattern, patternUsage); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Create a string property definition builder. |
| | | * |
| | | * @param d |
| | | * The managed object definition associated with this property |
| | | * definition. |
| | | * @param propertyName |
| | | * The property name. |
| | | * @return Returns the new string property definition builder. |
| | | */ |
| | | public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | return new Builder(d, propertyName); |
| | | } |
| | | |
| | | // Flag indicating whether values of this property are |
| | | // case-insensitive. |
| | | private final boolean isCaseInsensitive; |
| | | |
| | | // Optional pattern which values of this property must match. |
| | | private final Pattern pattern; |
| | | |
| | | // Pattern usage which provides a user-friendly summary of the |
| | | // pattern if present. |
| | | private final String patternUsage; |
| | | |
| | | // Private constructor. |
| | | private StringPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName, |
| | | EnumSet<PropertyOption> options, AdministratorAction adminAction, |
| | | DefaultBehaviorProvider<String> defaultBehavior, boolean isCaseInsensitive, Pattern pattern, |
| | | String patternUsage) { |
| | | super(d, String.class, propertyName, options, adminAction, defaultBehavior); |
| | | this.isCaseInsensitive = isCaseInsensitive; |
| | | this.pattern = pattern; |
| | | this.patternUsage = patternUsage; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) { |
| | | return v.visitString(this, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) { |
| | | return v.visitString(this, value, p); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String decodeValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | try { |
| | | validateValue(value, options); |
| | | } catch (IllegalPropertyValueException e) { |
| | | throw new IllegalPropertyValueStringException(this, value); |
| | | } |
| | | |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional regular expression pattern which values of this |
| | | * property must match. |
| | | * |
| | | * @return Returns the optional regular expression pattern which values of |
| | | * this property must match, or <code>null</code> if there is no |
| | | * pattern. |
| | | */ |
| | | public Pattern getPattern() { |
| | | return pattern; |
| | | } |
| | | |
| | | /** |
| | | * Gets the pattern synopsis of this string property definition in the |
| | | * default locale. |
| | | * |
| | | * @return Returns the pattern synopsis of this string property definition |
| | | * in the default locale, or <code>null</code> if there is no |
| | | * pattern synopsis (which is the case when there is no pattern |
| | | * matching defined for this string property definition). |
| | | */ |
| | | public LocalizableMessage getPatternSynopsis() { |
| | | return getPatternSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the optional pattern synopsis of this string property definition in |
| | | * the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the pattern synopsis of this string property definition |
| | | * in the specified locale, or <code>null</code> if there is no |
| | | * pattern synopsis (which is the case when there is no pattern |
| | | * matching defined for this string property definition). |
| | | */ |
| | | public LocalizableMessage getPatternSynopsis(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "property." + getName() + ".syntax.string.pattern.synopsis"; |
| | | try { |
| | | return resource.getMessage(getManagedObjectDefinition(), property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets a user-friendly usage string representing the pattern which can be |
| | | * used in error messages and help (e.g. for patterns which match a |
| | | * host/port combination, the usage string "HOST:PORT" would be |
| | | * appropriate). |
| | | * |
| | | * @return Returns the user-friendly pattern usage string, or |
| | | * <code>null</code> if there is no pattern. |
| | | */ |
| | | public String getPatternUsage() { |
| | | return patternUsage; |
| | | } |
| | | |
| | | /** |
| | | * Query whether values of this property are case-insensitive. |
| | | * |
| | | * @return Returns <code>true</code> if values are case-insensitive, or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public boolean isCaseInsensitive() { |
| | | return isCaseInsensitive; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String normalizeValue(String value) { |
| | | Reject.ifNull(value); |
| | | |
| | | if (isCaseInsensitive()) { |
| | | return value.trim().toLowerCase(); |
| | | } else { |
| | | return value.trim(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void validateValue(String value, PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(value); |
| | | |
| | | if (pattern != null) { |
| | | Matcher matcher = pattern.matcher(value); |
| | | if (!matcher.matches()) { |
| | | throw new IllegalPropertyValueException(this, 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import org.forgerock.util.Reject; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.Locale; |
| | | import java.util.Map; |
| | | import java.util.MissingResourceException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.server.config.meta.RootCfgDefn; |
| | | |
| | | /** |
| | | * An interface for querying the properties of a tag. |
| | | * <p> |
| | | * Tags are used to group related managed objects together into categories. |
| | | */ |
| | | public final class Tag implements Comparable<Tag> { |
| | | |
| | | /** All the tags. */ |
| | | private static final Map<String, Tag> TAGS = new HashMap<String, Tag>(); |
| | | |
| | | /** |
| | | * Defines a new tag with the specified name. |
| | | * |
| | | * @param name |
| | | * The name of the new tag. |
| | | */ |
| | | public static void define(String name) { |
| | | Tag tag = new Tag(name); |
| | | |
| | | // Register the tag. |
| | | TAGS.put(name, tag); |
| | | } |
| | | |
| | | /** |
| | | * Returns the tag associated with the specified name. |
| | | * |
| | | * @param name |
| | | * The name of the tag. |
| | | * @return Returns the tag associated with the specified name. |
| | | * @throws IllegalArgumentException |
| | | * If the tag name was not recognized. |
| | | */ |
| | | public static Tag valueOf(String name) { |
| | | Reject.ifNull(name); |
| | | |
| | | // Hack to force initialization of the tag definitions. |
| | | RootCfgDefn.getInstance(); |
| | | |
| | | Tag tag = TAGS.get(name.toLowerCase()); |
| | | |
| | | if (tag == null) { |
| | | throw new IllegalArgumentException("Unknown tag \"" + name + "\""); |
| | | } |
| | | |
| | | return tag; |
| | | } |
| | | |
| | | /** |
| | | * Returns an unmodifiable collection view of the set of registered tags. |
| | | * |
| | | * @return Returns an unmodifiable collection view of the set of registered |
| | | * tags. |
| | | */ |
| | | public static Collection<Tag> values() { |
| | | // Hack to force initialization of the tag definitions. |
| | | RootCfgDefn.getInstance(); |
| | | |
| | | return Collections.unmodifiableCollection(TAGS.values()); |
| | | } |
| | | |
| | | /** The name of the tag. */ |
| | | private final String name; |
| | | |
| | | /** Private constructor. */ |
| | | private Tag(String name) { |
| | | this.name = name; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | public final int compareTo(Tag o) { |
| | | return name.compareTo(o.name); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final boolean equals(Object obj) { |
| | | if (this == obj) { |
| | | return true; |
| | | } |
| | | |
| | | if (obj instanceof Tag) { |
| | | Tag other = (Tag) obj; |
| | | return other.name.equals(this.name); |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * Gets the name of this tag. |
| | | * |
| | | * @return Returns the name of this tag. |
| | | */ |
| | | public final String getName() { |
| | | return name; |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this tag in the default locale. |
| | | * |
| | | * @return Returns the synopsis of this tag in the default locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis() { |
| | | return getSynopsis(Locale.getDefault()); |
| | | } |
| | | |
| | | /** |
| | | * Gets the synopsis of this tag in the specified locale. |
| | | * |
| | | * @param locale |
| | | * The locale. |
| | | * @return Returns the synopsis of this tag in the specified locale. |
| | | */ |
| | | public final LocalizableMessage getSynopsis(Locale locale) { |
| | | ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance(); |
| | | String property = "tag." + name + ".synopsis"; |
| | | try { |
| | | return resource.getMessage(RootCfgDefn.getInstance(), property, locale); |
| | | } catch (MissingResourceException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final int hashCode() { |
| | | return name.hashCode(); |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public final String toString() { |
| | | return name; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * Configuration definition <code>TopCfgDefn</code> is the root of the |
| | | * configuration definition hierarchy. Every configuration has |
| | | * <code>TopCfgDefn</code> as a superclass. |
| | | * <p> |
| | | * The <code>TopCfgDefn</code> has no properties or relations. However, it can |
| | | * be used to determine all the configuration definitions currently available to |
| | | * the administration framework using the {@link #getAllChildren()}. |
| | | * <p> |
| | | * <b>NOTE:</b> it is not possible to retrieve I18N related information or |
| | | * profile information for this managed object definition. In particular, calls |
| | | * to the methods {@link #getSynopsis()}, {@link #getDescription()}, |
| | | * {@link #getUserFriendlyName()}, and {@link #getUserFriendlyPluralName()} will |
| | | * not work. |
| | | */ |
| | | public final class TopCfgDefn extends AbstractManagedObjectDefinition<ConfigurationClient, Configuration> { |
| | | |
| | | // The singleton configuration definition instance. |
| | | private static final TopCfgDefn INSTANCE = new TopCfgDefn(); |
| | | |
| | | /** |
| | | * Get the Top configuration definition singleton. |
| | | * |
| | | * @return Returns the Top configuration definition singleton. |
| | | */ |
| | | public static TopCfgDefn getInstance() { |
| | | return INSTANCE; |
| | | } |
| | | |
| | | /** |
| | | * Private constructor. |
| | | */ |
| | | private TopCfgDefn() { |
| | | super("top", null); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | /** |
| | | * A default behavior provider which indicates undefined behavior. It should be |
| | | * used by properties which have no default values or behavior as such. For |
| | | * example, a description property, when left unset, has no default value and no |
| | | * side-effects. |
| | | * |
| | | * @param <T> |
| | | * The type of values represented by this provider. |
| | | */ |
| | | public final class UndefinedDefaultBehaviorProvider<T> extends DefaultBehaviorProvider<T> { |
| | | |
| | | /** |
| | | * Create an undefined default behavior provider. |
| | | */ |
| | | public UndefinedDefaultBehaviorProvider() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <R, P> R accept(DefaultBehaviorProviderVisitor<T, R, P> v, P p) { |
| | | return v.visitUndefined(this, p); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * Indicates that an unknown type of property definition was encountered. This |
| | | * can occur as the management prototype develops and new kinds of property |
| | | * definitions are added. |
| | | */ |
| | | public final class UnknownPropertyDefinitionException extends PropertyException { |
| | | |
| | | // Generated serialization ID. |
| | | private static final long serialVersionUID = 7042646409131322385L; |
| | | |
| | | // The visitor parameter if there was one. |
| | | private Object parameter; |
| | | |
| | | /** |
| | | * Creates a new unknown property definition exception. |
| | | * |
| | | * @param pd |
| | | * The unknown property definition. |
| | | * @param p |
| | | * The visitor parameter if there was one. |
| | | */ |
| | | public UnknownPropertyDefinitionException(PropertyDefinition<?> pd, Object p) { |
| | | super(pd, ERR_UNKNOWN_PROPERTY_DEFINITION_EXCEPTION.get(pd.getName(), pd.getClass().getName())); |
| | | this.parameter = p; |
| | | } |
| | | |
| | | /** |
| | | * Get the visitor parameter if there was one. |
| | | * |
| | | * @return Returns the visitor parameter if there was one. |
| | | */ |
| | | public Object getParameter() { |
| | | return parameter; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.config.AdminException; |
| | | |
| | | /** |
| | | * Administration client exceptions represent non-operational problems which |
| | | * occur whilst interacting with the administration framework. They provide |
| | | * clients with a transport independent interface for handling transport related |
| | | * exceptions. |
| | | * <p> |
| | | * Client exceptions represent communications problems, security problems, and |
| | | * service related problems. |
| | | */ |
| | | public abstract class AdminClientException extends AdminException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 4044747533980824456L; |
| | | |
| | | /** |
| | | * Create an administration client exception with a message and cause. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | protected AdminClientException(LocalizableMessage message, Throwable cause) { |
| | | super(message, cause); |
| | | } |
| | | |
| | | /** |
| | | * Create an administration client exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | protected AdminClientException(LocalizableMessage message) { |
| | | super(message); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | /** |
| | | * This exception is thrown when a security related problem occurs whilst |
| | | * interacting with the Directory Server. These fall broadly into two |
| | | * categories: authentication problems and authorization problems. |
| | | */ |
| | | public abstract class AdminSecurityException extends AdminClientException { |
| | | |
| | | /** |
| | | * Fake serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * Create a security exception with a message and cause. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | protected AdminSecurityException(LocalizableMessage message, Throwable cause) { |
| | | super(message, cause); |
| | | } |
| | | |
| | | /** |
| | | * Create a security exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | protected AdminSecurityException(LocalizableMessage message) { |
| | | super(message); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * This exception is thrown when an authentication error occurs while connecting |
| | | * to the Directory Server. An authentication error can happen, for example, |
| | | * when the client credentials are invalid. |
| | | */ |
| | | public class AuthenticationException extends AdminSecurityException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 3544797197747686958L; |
| | | |
| | | /** |
| | | * Creates an authentication exception with a default message. |
| | | */ |
| | | public AuthenticationException() { |
| | | super(ERR_AUTHENTICATION_EXCEPTION_DEFAULT.get()); |
| | | } |
| | | |
| | | /** |
| | | * Create an authentication exception with a cause and a default message. |
| | | * |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public AuthenticationException(Throwable cause) { |
| | | super(ERR_AUTHENTICATION_EXCEPTION_DEFAULT.get(), cause); |
| | | } |
| | | |
| | | /** |
| | | * Create an authentication exception with a message and cause. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public AuthenticationException(LocalizableMessage message, Throwable cause) { |
| | | super(message, cause); |
| | | } |
| | | |
| | | /** |
| | | * Create an authentication exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | public AuthenticationException(LocalizableMessage message) { |
| | | super(message); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | /** |
| | | * This exception is thrown when the particular flavor of authentication |
| | | * requested is not supported by the Directory Server. |
| | | */ |
| | | public class AuthenticationNotSupportedException extends AdminSecurityException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 7387834052676291793L; |
| | | |
| | | /** |
| | | * Creates an authentication not supported exception with a default message. |
| | | */ |
| | | public AuthenticationNotSupportedException() { |
| | | super(ERR_AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_DEFAULT.get()); |
| | | } |
| | | |
| | | /** |
| | | * Creates an authentication not supported exception with a cause and a |
| | | * default message. |
| | | * |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public AuthenticationNotSupportedException(Throwable cause) { |
| | | super(ERR_AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_DEFAULT.get(), cause); |
| | | } |
| | | |
| | | /** |
| | | * Create an authentication not supported exception with a message and |
| | | * cause. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public AuthenticationNotSupportedException(LocalizableMessage message, Throwable cause) { |
| | | super(message, cause); |
| | | } |
| | | |
| | | /** |
| | | * Create an authentication not supported exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | public AuthenticationNotSupportedException(LocalizableMessage message) { |
| | | super(message); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.config.ManagedObjectPath; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | |
| | | /** |
| | | * An interface for performing client-side constraint validation. |
| | | * <p> |
| | | * Constraints are evaluated immediately before the client performs a write |
| | | * operation. If one or more constraints fails, the write operation is refused |
| | | * and fails with an {@link OperationRejectedException}. |
| | | * <p> |
| | | * A client constraint handler must override at least one of the provided |
| | | * methods. |
| | | * |
| | | * @see org.forgerock.opendj.config.Constraint |
| | | */ |
| | | public abstract class ClientConstraintHandler { |
| | | |
| | | /** |
| | | * Creates a new client constraint handler. |
| | | */ |
| | | protected ClientConstraintHandler() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not the newly created managed object which is about |
| | | * to be added to the server configuration satisfies this constraint. |
| | | * <p> |
| | | * If the constraint is not satisfied, the implementation must return |
| | | * <code>false</code> and add a message describing why the constraint was |
| | | * not satisfied. |
| | | * <p> |
| | | * The default implementation is to return <code>true</code>. |
| | | * |
| | | * @param context |
| | | * The management context. |
| | | * @param managedObject |
| | | * The new managed object. |
| | | * @param unacceptableReasons |
| | | * A list of messages to which error messages should be added. |
| | | * @return Returns <code>true</code> if this constraint is satisfied, or |
| | | * <code>false</code> if it is not. |
| | | * @throws ErrorResultException |
| | | * If an error occurs. |
| | | */ |
| | | public boolean isAddAcceptable(ManagementContext context, ManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not the changes to an existing managed object which |
| | | * are about to be committed to the server configuration satisfies this |
| | | * constraint. |
| | | * <p> |
| | | * If the constraint is not satisfied, the implementation must return |
| | | * <code>false</code> and add a message describing why the constraint was |
| | | * not satisfied. |
| | | * <p> |
| | | * The default implementation is to return <code>true</code>. |
| | | * |
| | | * @param context |
| | | * The management context. |
| | | * @param managedObject |
| | | * The modified managed object. |
| | | * @param unacceptableReasons |
| | | * A list of messages to which error messages should be added. |
| | | * @return Returns <code>true</code> if this modify is satisfied, or |
| | | * <code>false</code> if it is not. |
| | | * @throws ErrorResultException |
| | | * If an error occurs. |
| | | */ |
| | | public boolean isModifyAcceptable(ManagementContext context, ManagedObject<?> managedObject, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not the existing managed object which is about to |
| | | * be deleted from the server configuration satisfies this constraint. |
| | | * <p> |
| | | * If the constraint is not satisfied, the implementation must return |
| | | * <code>false</code> and add a message describing why the constraint was |
| | | * not satisfied. |
| | | * <p> |
| | | * The default implementation is to return <code>true</code>. |
| | | * |
| | | * @param context |
| | | * The management context. |
| | | * @param path |
| | | * The path of the managed object which is about to be deleted. |
| | | * @param unacceptableReasons |
| | | * A list of messages to which error messages should be added. |
| | | * @return Returns <code>true</code> if this constraint is satisfied, or |
| | | * <code>false</code> if it is not. |
| | | * @throws ErrorResultException |
| | | * If an error occurs. |
| | | */ |
| | | public boolean isDeleteAcceptable(ManagementContext context, ManagedObjectPath<?, ?> path, |
| | | Collection<LocalizableMessage> unacceptableReasons) throws ErrorResultException { |
| | | return true; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.config.OperationsException; |
| | | |
| | | /** |
| | | * This exception is thrown when a critical concurrent modification is detected |
| | | * by the client. This may be caused by another client application removing a |
| | | * managed object whilst it is being managed. |
| | | */ |
| | | public class ConcurrentModificationException extends OperationsException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = -1467024486347612820L; |
| | | |
| | | /** |
| | | * Create a concurrent modification exception with a default message. |
| | | */ |
| | | public ConcurrentModificationException() { |
| | | super(ERR_CONCURRENT_MODIFICATION_EXCEPTION_DEFAULT.get()); |
| | | } |
| | | |
| | | /** |
| | | * Create a concurrent modification exception with a cause and a default |
| | | * message. |
| | | * |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public ConcurrentModificationException(Throwable cause) { |
| | | super(ERR_CONCURRENT_MODIFICATION_EXCEPTION_DEFAULT.get(), cause); |
| | | } |
| | | |
| | | /** |
| | | * Create a concurrent modification exception with a message and cause. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | * @param cause |
| | | * The cause. |
| | | */ |
| | | public ConcurrentModificationException(LocalizableMessage message, Throwable cause) { |
| | | super(message, cause); |
| | | } |
| | | |
| | | /** |
| | | * Create a concurrent modification exception with a message. |
| | | * |
| | | * @param message |
| | | * The message. |
| | | */ |
| | | public ConcurrentModificationException(LocalizableMessage message) { |
| | | super(message); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.config.IllegalPropertyValueStringException; |
| | | import org.forgerock.opendj.config.OperationsException; |
| | | import org.forgerock.opendj.config.PropertyDefinition; |
| | | import org.forgerock.opendj.config.PropertyDefinitionUsageBuilder; |
| | | import org.forgerock.opendj.config.PropertyDefinitionsOptions; |
| | | |
| | | /** |
| | | * Thrown when an attempt is made to create a new managed object with an illegal |
| | | * name. |
| | | * <p> |
| | | * This exception can occur when a new managed object is given a name which is |
| | | * either an empty string, a string containing just white-spaces, or a string |
| | | * which is invalid according to the managed object's naming property (if it has |
| | | * one). |
| | | */ |
| | | public class IllegalManagedObjectNameException extends OperationsException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 7491748228684293291L; |
| | | |
| | | /** Create the message. */ |
| | | private static LocalizableMessage createMessage(String illegalName, PropertyDefinition<?> namingPropertyDefinition, |
| | | PropertyDefinitionsOptions options) { |
| | | if (illegalName.length() == 0) { |
| | | return ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_EMPTY.get(); |
| | | } else if (illegalName.trim().length() == 0) { |
| | | return ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_BLANK.get(); |
| | | } else if (namingPropertyDefinition != null) { |
| | | try { |
| | | namingPropertyDefinition.decodeValue(illegalName, options); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | PropertyDefinitionUsageBuilder builder = new PropertyDefinitionUsageBuilder(true); |
| | | return ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_SYNTAX.get(illegalName, |
| | | namingPropertyDefinition.getName(), builder.getUsage(namingPropertyDefinition)); |
| | | } |
| | | } |
| | | |
| | | return ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_OTHER.get(illegalName); |
| | | } |
| | | |
| | | /** The illegal name. */ |
| | | private final String illegalName; |
| | | |
| | | /** The naming property definition if applicable. */ |
| | | private final PropertyDefinition<?> namingPropertyDefinition; |
| | | |
| | | /** |
| | | * Create a new illegal name exception and no naming property definition. |
| | | * |
| | | * @param illegalName |
| | | * The illegal managed object name. |
| | | */ |
| | | public IllegalManagedObjectNameException(String illegalName) { |
| | | this(illegalName, null, null); |
| | | } |
| | | |
| | | /** |
| | | * Create a new illegal name exception and a naming property definition. |
| | | * |
| | | * @param illegalName |
| | | * The illegal managed object name. |
| | | * @param namingPropertyDefinition |
| | | * The naming property definition. |
| | | * @param options |
| | | * Options to decode property definition values. |
| | | */ |
| | | public IllegalManagedObjectNameException(String illegalName, PropertyDefinition<?> namingPropertyDefinition, |
| | | PropertyDefinitionsOptions options) { |
| | | super(createMessage(illegalName, namingPropertyDefinition, options)); |
| | | |
| | | this.illegalName = illegalName; |
| | | this.namingPropertyDefinition = namingPropertyDefinition; |
| | | } |
| | | |
| | | /** |
| | | * Get the illegal managed object name. |
| | | * |
| | | * @return Returns the illegal managed object name. |
| | | */ |
| | | public String getIllegalName() { |
| | | return illegalName; |
| | | } |
| | | |
| | | /** |
| | | * Get the naming property definition if applicable. |
| | | * |
| | | * @return Returns naming property definition, or <code>null</code> if none |
| | | * was specified. |
| | | */ |
| | | public PropertyDefinition<?> getNamingPropertyDefinition() { |
| | | return namingPropertyDefinition; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2007-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.SortedSet; |
| | | |
| | | import org.forgerock.opendj.config.AbstractManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.Configuration; |
| | | import org.forgerock.opendj.config.ConfigurationClient; |
| | | import org.forgerock.opendj.config.DefaultBehaviorException; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException; |
| | | import org.forgerock.opendj.config.InstantiableRelationDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectAlreadyExistsException; |
| | | import org.forgerock.opendj.config.ManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectNotFoundException; |
| | | import org.forgerock.opendj.config.ManagedObjectPath; |
| | | import org.forgerock.opendj.config.OptionalRelationDefinition; |
| | | import org.forgerock.opendj.config.PropertyDefinition; |
| | | import org.forgerock.opendj.config.PropertyIsMandatoryException; |
| | | import org.forgerock.opendj.config.PropertyIsReadOnlyException; |
| | | import org.forgerock.opendj.config.PropertyIsSingleValuedException; |
| | | import org.forgerock.opendj.config.PropertyProvider; |
| | | import org.forgerock.opendj.config.SetRelationDefinition; |
| | | import org.forgerock.opendj.config.SingletonRelationDefinition; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | |
| | | /** |
| | | * A generic interface for accessing client-side managed objects. |
| | | * <p> |
| | | * A managed object comprises of zero or more properties. A property has |
| | | * associated with it three sets of property value(s). These are: |
| | | * <ul> |
| | | * <li><i>default value(s)</i> - these value(s) represent the default behavior |
| | | * for the property when it has no active values. When a property inherits its |
| | | * default value(s) from elsewhere (i.e. a property in another managed object), |
| | | * the default value(s) represent the active value(s) of the inherited property |
| | | * at the time the managed object was retrieved |
| | | * <li><i>active value(s)</i> - these value(s) represent the state of the |
| | | * property at the time the managed object was retrieved |
| | | * <li><i>pending value(s)</i> - these value(s) represent any modifications made |
| | | * to the property's value(s) since the managed object object was retrieved and |
| | | * before the changes have been committed using the {@link #commit()} method, |
| | | * the pending values can be empty indicating that the property should be |
| | | * modified back to its default values. |
| | | * </ul> |
| | | * In addition, a property has an <i>effective state</i> defined by its |
| | | * <i>effective values</i> which are derived by evaluating the following rules |
| | | * in the order presented: |
| | | * <ul> |
| | | * <li>the <i>pending values</i> if defined and non-empty |
| | | * <li>or, the <i>default values</i> if the pending values are defined but are |
| | | * empty |
| | | * <li>or, the <i>active values</i> if defined and non-empty |
| | | * <li>or, the <i>default values</i> if there are no active values |
| | | * <li>or, an empty set of values, if there are no default values. |
| | | * </ul> |
| | | * |
| | | * @param <T> |
| | | * The type of client configuration represented by the client managed |
| | | * object. |
| | | */ |
| | | public interface ManagedObject<T extends ConfigurationClient> extends PropertyProvider { |
| | | |
| | | /** |
| | | * Adds this managed object to the server or commits any changes made to it |
| | | * depending on whether or not the managed object already exists on the |
| | | * server. Pending property values will be committed to the managed object. |
| | | * If successful, the pending values will become active values. |
| | | * <p> |
| | | * See the class description for more information regarding pending and |
| | | * active values. |
| | | * |
| | | * @throws ManagedObjectAlreadyExistsException |
| | | * If the managed object cannot be added to the server because |
| | | * it already exists. |
| | | * @throws MissingMandatoryPropertiesException |
| | | * If the managed object contains some mandatory properties |
| | | * which have been left undefined. |
| | | * @throws ConcurrentModificationException |
| | | * If the managed object is being added to the server but its |
| | | * parent has been removed by another client, or if this managed |
| | | * object is being modified but it has been removed from the |
| | | * server by another client. |
| | | * @throws OperationRejectedException |
| | | * If this managed object cannot be added or modified due to |
| | | * some client-side or server-side constraint which cannot be |
| | | * satisfied. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | void commit() throws ManagedObjectAlreadyExistsException, MissingMandatoryPropertiesException, |
| | | ConcurrentModificationException, OperationRejectedException, ErrorResultException; |
| | | |
| | | /** |
| | | * Determines whether or not this managed object has been modified since it |
| | | * was constructed. In other words, whether or not the set of pending values |
| | | * differs from the set of active values. |
| | | * |
| | | * @return Returns <code>true</code> if this managed object has been |
| | | * modified since it was constructed. |
| | | */ |
| | | boolean isModified(); |
| | | |
| | | /** |
| | | * Creates a new child managed object bound to the specified instantiable |
| | | * relation. The new managed object will initially not contain any property |
| | | * values (including mandatory properties). Once the managed object has been |
| | | * configured it can be added to the server using the {@link #commit()} |
| | | * method. |
| | | * |
| | | * @param <C> |
| | | * The expected type of the child managed object configuration |
| | | * client. |
| | | * @param <S> |
| | | * The expected type of the child managed object server |
| | | * configuration. |
| | | * @param <C1> |
| | | * The actual type of the added managed object configuration |
| | | * client. |
| | | * @param r |
| | | * The instantiable relation definition. |
| | | * @param d |
| | | * The definition of the managed object to be created. |
| | | * @param name |
| | | * The name of the child managed object. |
| | | * @param exceptions |
| | | * A collection in which to place any |
| | | * {@link DefaultBehaviorException}s that occurred whilst |
| | | * attempting to determine the managed object's default values. |
| | | * @return Returns a new child managed object bound to the specified |
| | | * instantiable relation. |
| | | * @throws IllegalManagedObjectNameException |
| | | * If the name of the child managed object is invalid. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with this |
| | | * managed object's definition. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration, C1 extends C> ManagedObject<C1> createChild( |
| | | InstantiableRelationDefinition<C, S> r, ManagedObjectDefinition<C1, ? extends S> d, String name, |
| | | Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException; |
| | | |
| | | /** |
| | | * Creates a new child managed object bound to the specified optional |
| | | * relation. The new managed object will initially not contain any property |
| | | * values (including mandatory properties). Once the managed object has been |
| | | * configured it can be added to the server using the {@link #commit()} |
| | | * method. |
| | | * |
| | | * @param <C> |
| | | * The expected type of the child managed object configuration |
| | | * client. |
| | | * @param <S> |
| | | * The expected type of the child managed object server |
| | | * configuration. |
| | | * @param <C1> |
| | | * The actual type of the added managed object configuration |
| | | * client. |
| | | * @param r |
| | | * The optional relation definition. |
| | | * @param d |
| | | * The definition of the managed object to be created. |
| | | * @param exceptions |
| | | * A collection in which to place any |
| | | * {@link DefaultBehaviorException}s that occurred whilst |
| | | * attempting to determine the managed object's default values. |
| | | * @return Returns a new child managed object bound to the specified |
| | | * optional relation. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with this |
| | | * managed object's definition. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration, C1 extends C> ManagedObject<C1> createChild( |
| | | OptionalRelationDefinition<C, S> r, ManagedObjectDefinition<C1, ? extends S> d, |
| | | Collection<DefaultBehaviorException> exceptions); |
| | | |
| | | /** |
| | | * Creates a new child managed object bound to the specified set relation. |
| | | * The new managed object will initially not contain any property values |
| | | * (including mandatory properties). Once the managed object has been |
| | | * configured it can be added to the server using the {@link #commit()} |
| | | * method. |
| | | * |
| | | * @param <C> |
| | | * The expected type of the child managed object configuration |
| | | * client. |
| | | * @param <S> |
| | | * The expected type of the child managed object server |
| | | * configuration. |
| | | * @param <C1> |
| | | * The actual type of the added managed object configuration |
| | | * client. |
| | | * @param r |
| | | * The set relation definition. |
| | | * @param d |
| | | * The definition of the managed object to be created. |
| | | * @param exceptions |
| | | * A collection in which to place any |
| | | * {@link DefaultBehaviorException}s that occurred whilst |
| | | * attempting to determine the managed object's default values. |
| | | * @return Returns a new child managed object bound to the specified set |
| | | * relation. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with this |
| | | * managed object's definition. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration, C1 extends C> ManagedObject<C1> createChild( |
| | | SetRelationDefinition<C, S> r, ManagedObjectDefinition<C1, ? extends S> d, |
| | | Collection<DefaultBehaviorException> exceptions); |
| | | |
| | | /** |
| | | * Retrieves an instantiable child managed object. |
| | | * |
| | | * @param <C> |
| | | * The requested type of the child managed object configuration |
| | | * client. |
| | | * @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. |
| | | * @return Returns the instantiable child managed object. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with this |
| | | * managed object's definition. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws ManagedObjectDecodingException |
| | | * If the managed object was found but one or more of its |
| | | * properties could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | InstantiableRelationDefinition<C, S> r, String name) throws |
| | | DefinitionDecodingException, ManagedObjectDecodingException, ManagedObjectNotFoundException, |
| | | ConcurrentModificationException, ErrorResultException; |
| | | |
| | | /** |
| | | * Retrieves an optional child managed object. |
| | | * |
| | | * @param <C> |
| | | * The requested type of the child managed object configuration |
| | | * client. |
| | | * @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 relation definition is not associated with this |
| | | * managed object's definition. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws ManagedObjectDecodingException |
| | | * If the managed object was found but one or more of its |
| | | * properties could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | OptionalRelationDefinition<C, S> r) throws DefinitionDecodingException, |
| | | ManagedObjectDecodingException, ManagedObjectNotFoundException, ConcurrentModificationException, |
| | | ErrorResultException; |
| | | |
| | | /** |
| | | * Retrieves a singleton child managed object. |
| | | * |
| | | * @param <C> |
| | | * The requested type of the child managed object configuration |
| | | * client. |
| | | * @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 relation definition is not associated with this |
| | | * managed object's definition. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws ManagedObjectDecodingException |
| | | * If the managed object was found but one or more of its |
| | | * properties could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | SingletonRelationDefinition<C, S> r) throws DefinitionDecodingException, |
| | | ManagedObjectDecodingException, ManagedObjectNotFoundException, ConcurrentModificationException, |
| | | ErrorResultException; |
| | | |
| | | /** |
| | | * Retrieves a set child managed object. |
| | | * |
| | | * @param <C> |
| | | * The requested type of the child managed object configuration |
| | | * client. |
| | | * @param <S> |
| | | * The type of server managed object configuration that the |
| | | * relation definition refers to. |
| | | * @param r |
| | | * The set relation definition. |
| | | * @param name |
| | | * The name of the child managed object. |
| | | * @return Returns the set child managed object. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with this |
| | | * managed object's definition. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws ManagedObjectDecodingException |
| | | * If the managed object was found but one or more of its |
| | | * properties could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | SetRelationDefinition<C, S> r, String name) throws DefinitionDecodingException, |
| | | ManagedObjectDecodingException, ManagedObjectNotFoundException, ConcurrentModificationException, |
| | | ErrorResultException; |
| | | |
| | | /** |
| | | * Creates a client configuration view of this managed object. Modifications |
| | | * made to this managed object will be reflected in the client configuration |
| | | * view and vice versa. |
| | | * |
| | | * @return Returns a client configuration view of this managed object. |
| | | */ |
| | | T getConfiguration(); |
| | | |
| | | /** |
| | | * Gets the definition associated with this managed object. |
| | | * |
| | | * @return Returns the definition associated with this managed object. |
| | | */ |
| | | ManagedObjectDefinition<T, ? extends Configuration> getManagedObjectDefinition(); |
| | | |
| | | /** |
| | | * Gets the path of this managed object. |
| | | * |
| | | * @return Returns the path of this managed object. |
| | | */ |
| | | ManagedObjectPath<T, ? extends Configuration> getManagedObjectPath(); |
| | | |
| | | /** |
| | | * Gets a mutable copy of the set of default values for the specified |
| | | * property. |
| | | * |
| | | * @param <P> |
| | | * The type of the property to be retrieved. |
| | | * @param pd |
| | | * The property to be retrieved. |
| | | * @return Returns the property's default values, or an empty set if there |
| | | * are no default values defined. |
| | | * @throws IllegalArgumentException |
| | | * If the property definition is not associated with this |
| | | * managed object's definition. |
| | | */ |
| | | <P> SortedSet<P> getPropertyDefaultValues(PropertyDefinition<P> pd); |
| | | |
| | | /** |
| | | * Gets the effective value of the specified property. |
| | | * <p> |
| | | * See the class description for more information about how the effective |
| | | * property value is derived. |
| | | * |
| | | * @param <P> |
| | | * The type of the property to be retrieved. |
| | | * @param pd |
| | | * The property to be retrieved. |
| | | * @return Returns the property's effective value, or <code>null</code> if |
| | | * there is no effective value defined. |
| | | * @throws IllegalArgumentException |
| | | * If the property definition is not associated with this |
| | | * managed object's definition. |
| | | */ |
| | | <P> P getPropertyValue(PropertyDefinition<P> pd); |
| | | |
| | | /** |
| | | * Gets a mutable copy of the set of effective values for the specified |
| | | * property. |
| | | * <p> |
| | | * See the class description for more information about how the effective |
| | | * property values are derived. |
| | | * |
| | | * @param <P> |
| | | * The type of the property to be retrieved. |
| | | * @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. |
| | | * @throws IllegalArgumentException |
| | | * If the property definition is not associated with this |
| | | * managed object's definition. |
| | | */ |
| | | @Override |
| | | <P> SortedSet<P> getPropertyValues(PropertyDefinition<P> pd); |
| | | |
| | | /** |
| | | * Determines whether or not the specified property is set. If the property |
| | | * is unset, then any default behavior associated with the property applies. |
| | | * |
| | | * @param pd |
| | | * The property definition. |
| | | * @return Returns <code>true</code> if the property has been set, or |
| | | * <code>false</code> if it is unset and any default behavior |
| | | * associated with the property applies. |
| | | * @throws IllegalArgumentException |
| | | * If the property definition is not associated with this |
| | | * managed object's definition. |
| | | */ |
| | | boolean isPropertyPresent(PropertyDefinition<?> pd); |
| | | |
| | | /** |
| | | * Determines whether or not the optional managed object associated with the |
| | | * specified optional relations exists. |
| | | * |
| | | * @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. |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If there is any other error. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> boolean hasChild(OptionalRelationDefinition<C, S> r) |
| | | throws ConcurrentModificationException, ErrorResultException; |
| | | |
| | | /** |
| | | * Lists the child managed objects associated with the specified |
| | | * instantiable relation. |
| | | * |
| | | * @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 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 ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> String[] listChildren( |
| | | InstantiableRelationDefinition<C, S> r) throws ConcurrentModificationException, |
| | | ErrorResultException; |
| | | |
| | | /** |
| | | * 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 ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> String[] listChildren( |
| | | InstantiableRelationDefinition<C, S> r, AbstractManagedObjectDefinition<? extends C, ? extends S> d) |
| | | throws ConcurrentModificationException, ErrorResultException; |
| | | |
| | | /** |
| | | * Lists the child managed objects associated with the specified set |
| | | * relation. |
| | | * |
| | | * @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 set relation definition. |
| | | * @return Returns the names of the child managed objects which for set |
| | | * relations are the definition names of each managed object. |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> String[] listChildren(SetRelationDefinition<C, S> r) |
| | | throws ConcurrentModificationException, ErrorResultException; |
| | | |
| | | /** |
| | | * Lists the child managed objects associated with the specified set |
| | | * 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 set relation definition. |
| | | * @param d |
| | | * The managed object definition. |
| | | * @return Returns the names of the child managed objects which for set |
| | | * relations are the definition names of each managed object. |
| | | * @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 ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> String[] listChildren(SetRelationDefinition<C, S> r, |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws |
| | | ConcurrentModificationException, ErrorResultException; |
| | | |
| | | /** |
| | | * Removes the named instantiable child managed object. |
| | | * |
| | | * @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. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with this |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the managed object could not be removed because it could |
| | | * not found on the server. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> void removeChild(InstantiableRelationDefinition<C, S> r, |
| | | String name) throws ManagedObjectNotFoundException, OperationRejectedException, |
| | | ConcurrentModificationException, ErrorResultException; |
| | | |
| | | /** |
| | | * Removes an optional child managed object. |
| | | * |
| | | * @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 ManagedObjectNotFoundException |
| | | * If the managed object could not be removed because it could |
| | | * not found on the server. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> void removeChild(OptionalRelationDefinition<C, S> r) |
| | | throws ManagedObjectNotFoundException, OperationRejectedException, |
| | | ConcurrentModificationException, ErrorResultException; |
| | | |
| | | /** |
| | | * Removes s set child managed object. |
| | | * |
| | | * @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 set relation definition. |
| | | * @param name |
| | | * The name of the child managed object to be removed. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the managed object could not be removed because it could |
| | | * not found on the server. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | <C extends ConfigurationClient, S extends Configuration> void removeChild(SetRelationDefinition<C, S> r, |
| | | String name) throws ManagedObjectNotFoundException, OperationRejectedException, |
| | | ConcurrentModificationException, ErrorResultException; |
| | | |
| | | /** |
| | | * Sets a new pending value for the specified property. |
| | | * <p> |
| | | * See the class description for more information regarding pending values. |
| | | * |
| | | * @param <P> |
| | | * The type of the property to be modified. |
| | | * @param pd |
| | | * The property to be modified. |
| | | * @param value |
| | | * The new pending value for the property, or <code>null</code> |
| | | * if the property should be reset to its default behavior. |
| | | * @throws PropertyIsReadOnlyException |
| | | * If this is not a new managed object and the property is |
| | | * read-only or for monitoring purposes. |
| | | * @throws PropertyIsMandatoryException |
| | | * If an attempt was made to remove a mandatory property. |
| | | */ |
| | | <P> void setPropertyValue(PropertyDefinition<P> pd, P value); |
| | | |
| | | /** |
| | | * Sets a new pending values for the specified property. |
| | | * <p> |
| | | * See the class description for more information regarding pending values. |
| | | * |
| | | * @param <P> |
| | | * The type of the property to be modified. |
| | | * @param pd |
| | | * The property to be modified. |
| | | * @param values |
| | | * A non-<code>null</code> set of new pending values for the |
| | | * property (an empty set indicates that the property should be |
| | | * reset to its default behavior). The set will not be referenced |
| | | * by this managed object. |
| | | * @throws PropertyIsSingleValuedException |
| | | * If an attempt was made to add multiple pending values to a |
| | | * single-valued property. |
| | | * @throws PropertyIsReadOnlyException |
| | | * If this is not a new managed object and the property is |
| | | * read-only or for monitoring purposes. |
| | | * @throws PropertyIsMandatoryException |
| | | * If an attempt was made to remove a mandatory property. |
| | | */ |
| | | <P> void setPropertyValues(PropertyDefinition<P> pd, Collection<P> values); |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.LinkedList; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizableMessageBuilder; |
| | | import org.forgerock.opendj.config.DecodingException; |
| | | import org.forgerock.opendj.config.ManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.PropertyException; |
| | | import org.forgerock.util.Reject; |
| | | |
| | | /** |
| | | * The requested managed object was found but one or more of its properties |
| | | * could not be decoded successfully. |
| | | */ |
| | | public class ManagedObjectDecodingException extends DecodingException { |
| | | |
| | | /** |
| | | * Version ID required by serializable classes. |
| | | */ |
| | | private static final long serialVersionUID = -4268510652395945357L; |
| | | |
| | | // Create the message. |
| | | private static LocalizableMessage createMessage(ManagedObject<?> partialManagedObject, |
| | | Collection<PropertyException> causes) { |
| | | Reject.ifNull(causes); |
| | | Reject.ifFalse(!causes.isEmpty(), "causes should not be empty"); |
| | | |
| | | ManagedObjectDefinition<?, ?> d = partialManagedObject.getManagedObjectDefinition(); |
| | | if (causes.size() == 1) { |
| | | return ERR_MANAGED_OBJECT_DECODING_EXCEPTION_SINGLE.get(d.getUserFriendlyName(), causes.iterator().next() |
| | | .getLocalizableMessageObject()); |
| | | } else { |
| | | LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | |
| | | boolean isFirst = true; |
| | | for (PropertyException cause : causes) { |
| | | if (!isFirst) { |
| | | builder.append("; "); |
| | | } |
| | | builder.append(cause.getLocalizableMessageObject()); |
| | | isFirst = false; |
| | | } |
| | | |
| | | return ERR_MANAGED_OBJECT_DECODING_EXCEPTION_PLURAL.get(d.getUserFriendlyName(), builder.toMessage()); |
| | | } |
| | | } |
| | | |
| | | // The exception(s) that caused this decoding exception. |
| | | private final Collection<PropertyException> causes; |
| | | |
| | | // The partially created managed object. |
| | | private final ManagedObject<?> partialManagedObject; |
| | | |
| | | /** |
| | | * Create a new property decoding exception. |
| | | * |
| | | * @param partialManagedObject |
| | | * The partially created managed object containing properties |
| | | * which were successfully decoded and empty properties for those |
| | | * which were not (this may include empty mandatory properties). |
| | | * @param causes |
| | | * The exception(s) that caused this decoding exception. |
| | | */ |
| | | public ManagedObjectDecodingException(ManagedObject<?> partialManagedObject, Collection<PropertyException> causes) { |
| | | super(createMessage(partialManagedObject, causes)); |
| | | |
| | | this.partialManagedObject = partialManagedObject; |
| | | this.causes = Collections.unmodifiableList(new LinkedList<PropertyException>(causes)); |
| | | } |
| | | |
| | | /** |
| | | * Get an unmodifiable collection view of the causes of this exception. |
| | | * |
| | | * @return Returns an unmodifiable collection view of the causes of this |
| | | * exception. |
| | | */ |
| | | public Collection<PropertyException> getCauses() { |
| | | return causes; |
| | | } |
| | | |
| | | /** |
| | | * Get the partially created managed object containing properties which were |
| | | * successfully decoded and empty properties for those which were not (this |
| | | * may include empty mandatory properties). |
| | | * |
| | | * @return Returns the partially created managed object containing |
| | | * properties which were successfully decoded and empty properties |
| | | * for those which were not (this may include empty mandatory |
| | | * properties). |
| | | */ |
| | | public ManagedObject<?> getPartialManagedObject() { |
| | | return partialManagedObject; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import java.util.Set; |
| | | import java.util.SortedSet; |
| | | |
| | | import org.forgerock.opendj.server.config.client.RootCfgClient; |
| | | import org.forgerock.opendj.config.AbstractManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.Configuration; |
| | | import org.forgerock.opendj.config.ConfigurationClient; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException; |
| | | import org.forgerock.opendj.config.InstantiableRelationDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectNotFoundException; |
| | | import org.forgerock.opendj.config.ManagedObjectPath; |
| | | import org.forgerock.opendj.config.OptionalRelationDefinition; |
| | | import org.forgerock.opendj.config.PropertyDefinition; |
| | | import org.forgerock.opendj.config.PropertyException; |
| | | import org.forgerock.opendj.config.SetRelationDefinition; |
| | | import org.forgerock.opendj.config.client.spi.Driver; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | |
| | | /** |
| | | * Client management connection context. |
| | | */ |
| | | public abstract class ManagementContext { |
| | | |
| | | /** |
| | | * Creates a new management context. |
| | | */ |
| | | protected ManagementContext() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Deletes the named instantiable child managed object from the named parent |
| | | * managed object. |
| | | * |
| | | * @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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The instantiable relation definition. |
| | | * @param name |
| | | * The name of the child managed object to be removed. |
| | | * @return Returns <code>true</code> if the named instantiable child managed |
| | | * object was found, or <code>false</code> if it was not found. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, String name) |
| | | throws ManagedObjectNotFoundException, OperationRejectedException, |
| | | ErrorResultException { |
| | | return getDriver().deleteManagedObject(parent, rd, name); |
| | | } |
| | | |
| | | /** |
| | | * Deletes the optional child managed object from the named parent managed |
| | | * object. |
| | | * |
| | | * @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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The optional relation definition. |
| | | * @return Returns <code>true</code> if the optional child managed object |
| | | * was found, or <code>false</code> if it was not found. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd) throws |
| | | ManagedObjectNotFoundException, OperationRejectedException, ErrorResultException { |
| | | return getDriver().deleteManagedObject(parent, rd); |
| | | } |
| | | |
| | | /** |
| | | * Deletes s set child managed object from the named parent managed object. |
| | | * |
| | | * @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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The set relation definition. |
| | | * @param name |
| | | * The name of the child managed object to be removed. |
| | | * @return Returns <code>true</code> if the set child managed object was |
| | | * found, or <code>false</code> if it was not found. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd, String name) |
| | | throws ManagedObjectNotFoundException, OperationRejectedException, |
| | | ErrorResultException { |
| | | return getDriver().deleteManagedObject(parent, rd, name); |
| | | } |
| | | |
| | | /** |
| | | * Gets the named managed object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that the path |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that the path |
| | | * definition refers to. |
| | | * @param path |
| | | * The path of the managed object. |
| | | * @return Returns the named managed object. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws ManagedObjectDecodingException |
| | | * If the managed object was found but one or more of its |
| | | * properties could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public final <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getManagedObject( |
| | | ManagedObjectPath<C, S> path) throws DefinitionDecodingException, ManagedObjectDecodingException, |
| | | ManagedObjectNotFoundException, ErrorResultException { |
| | | // Be careful to handle the root configuration. |
| | | if (path.isEmpty()) { |
| | | return (ManagedObject<C>) getRootConfigurationManagedObject(); |
| | | } |
| | | |
| | | return getDriver().getManagedObject(path); |
| | | } |
| | | |
| | | /** |
| | | * Gets the effective value of a property in the named managed object. |
| | | * |
| | | * @param <P> |
| | | * The type of the property to be retrieved. |
| | | * @param path |
| | | * The path of the managed object containing the property. |
| | | * @param pd |
| | | * The property to be retrieved. |
| | | * @return Returns the property's effective value, or <code>null</code> if |
| | | * there are no values defined. |
| | | * @throws IllegalArgumentException |
| | | * If the property definition is not associated with the |
| | | * referenced managed object's definition. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws PropertyException |
| | | * If the managed object was found but the requested property |
| | | * could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <P> P getPropertyValue(ManagedObjectPath<?, ?> path, PropertyDefinition<P> pd) |
| | | throws DefinitionDecodingException, ErrorResultException, ManagedObjectNotFoundException { |
| | | Set<P> values = getPropertyValues(path, pd); |
| | | if (values.isEmpty()) { |
| | | return null; |
| | | } else { |
| | | return values.iterator().next(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the effective values of a property in the named managed object. |
| | | * |
| | | * @param <P> |
| | | * The type of the property to be retrieved. |
| | | * @param path |
| | | * The path of the managed object containing the property. |
| | | * @param pd |
| | | * The property to be retrieved. |
| | | * @return Returns the property's effective values, or an empty set if there |
| | | * are no values defined. |
| | | * @throws IllegalArgumentException |
| | | * If the property definition is not associated with the |
| | | * referenced managed object's definition. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws PropertyException |
| | | * If the managed object was found but the requested property |
| | | * could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <P> SortedSet<P> getPropertyValues(ManagedObjectPath<?, ?> path, PropertyDefinition<P> pd) |
| | | throws DefinitionDecodingException, ErrorResultException, ManagedObjectNotFoundException { |
| | | return getDriver().getPropertyValues(path, pd); |
| | | } |
| | | |
| | | /** |
| | | * Gets the root configuration client associated with this management |
| | | * context. |
| | | * |
| | | * @return Returns the root configuration client associated with this |
| | | * management context. |
| | | */ |
| | | public final RootCfgClient getRootConfiguration() { |
| | | return getRootConfigurationManagedObject().getConfiguration(); |
| | | } |
| | | |
| | | /** |
| | | * Gets the root configuration managed object associated with this |
| | | * management context. |
| | | * |
| | | * @return Returns the root configuration managed object associated with |
| | | * this management context. |
| | | */ |
| | | public final ManagedObject<RootCfgClient> getRootConfigurationManagedObject() { |
| | | return getDriver().getRootConfigurationManagedObject(); |
| | | } |
| | | |
| | | /** |
| | | * Lists the child managed objects of the named parent managed object. |
| | | * |
| | | * @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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The instantiable relation definition. |
| | | * @return Returns the names of the child managed objects. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd) throws |
| | | ManagedObjectNotFoundException, ErrorResultException { |
| | | return listManagedObjects(parent, rd, rd.getChildDefinition()); |
| | | } |
| | | |
| | | /** |
| | | * Lists the child managed objects of the named parent managed object 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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * 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 the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws |
| | | ManagedObjectNotFoundException, ErrorResultException { |
| | | return getDriver().listManagedObjects(parent, rd, d); |
| | | } |
| | | |
| | | /** |
| | | * Lists the child managed objects of the named parent managed object. |
| | | * |
| | | * @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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The set relation definition. |
| | | * @return Returns the names of the child managed objects. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects( |
| | | ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd) throws |
| | | ManagedObjectNotFoundException, ErrorResultException { |
| | | return getDriver().listManagedObjects(parent, rd, rd.getChildDefinition()); |
| | | } |
| | | |
| | | /** |
| | | * Determines whether or not the named managed object exists. |
| | | * |
| | | * @param path |
| | | * The path of the named managed object. |
| | | * @return Returns <code>true</code> if the named managed object exists, |
| | | * <code>false</code> otherwise. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final boolean managedObjectExists(ManagedObjectPath<?, ?> path) throws ManagedObjectNotFoundException, |
| | | ErrorResultException { |
| | | return getDriver().managedObjectExists(path); |
| | | } |
| | | |
| | | /** |
| | | * Gets the driver associated with this management context. |
| | | * |
| | | * @return Returns the driver associated with this management context. |
| | | */ |
| | | protected abstract Driver getDriver(); |
| | | |
| | | /** |
| | | * Closes this management context. |
| | | */ |
| | | public final void close() { |
| | | this.getDriver().close(); |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizableMessageBuilder; |
| | | import org.forgerock.opendj.config.OperationsException; |
| | | import org.forgerock.opendj.config.PropertyIsMandatoryException; |
| | | import org.forgerock.util.Reject; |
| | | |
| | | /** |
| | | * This exception is thrown when an attempt is made to add or modify a managed |
| | | * object when one or more of its mandatory properties are undefined. |
| | | */ |
| | | public class MissingMandatoryPropertiesException extends OperationsException { |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 6342522125252055588L; |
| | | |
| | | // Create the message. |
| | | private static LocalizableMessage createMessage(Collection<PropertyIsMandatoryException> causes) { |
| | | Reject.ifNull(causes); |
| | | Reject.ifFalse(!causes.isEmpty(), "causes should not be empty"); |
| | | |
| | | if (causes.size() == 1) { |
| | | return ERR_MISSING_MANDATORY_PROPERTIES_EXCEPTION_SINGLE.get(causes.iterator().next() |
| | | .getPropertyDefinition().getName()); |
| | | } else { |
| | | LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | |
| | | boolean isFirst = true; |
| | | for (PropertyIsMandatoryException cause : causes) { |
| | | if (!isFirst) { |
| | | builder.append(", "); |
| | | } |
| | | builder.append(cause.getPropertyDefinition().getName()); |
| | | isFirst = false; |
| | | } |
| | | |
| | | return ERR_MISSING_MANDATORY_PROPERTIES_EXCEPTION_PLURAL.get(builder.toMessage()); |
| | | } |
| | | } |
| | | |
| | | // The causes of this exception. |
| | | private final Collection<PropertyIsMandatoryException> causes; |
| | | |
| | | // Indicates whether the exception occurred during managed object |
| | | // creation. |
| | | private final boolean isCreate; |
| | | |
| | | // The user friendly name of the component that caused this |
| | | // exception. |
| | | private final LocalizableMessage ufn; |
| | | |
| | | /** |
| | | * Creates a new missing mandatory properties exception with the provided |
| | | * causes. |
| | | * |
| | | * @param ufn |
| | | * The user friendly name of the component that caused this |
| | | * exception. |
| | | * @param causes |
| | | * The causes of this exception (must be non-<code>null</code> |
| | | * and non-empty). |
| | | * @param isCreate |
| | | * Indicates whether the exception occurred during managed object |
| | | * creation. |
| | | */ |
| | | public MissingMandatoryPropertiesException(LocalizableMessage ufn, |
| | | Collection<PropertyIsMandatoryException> causes, boolean isCreate) { |
| | | super(createMessage(causes)); |
| | | |
| | | this.causes = new ArrayList<PropertyIsMandatoryException>(causes); |
| | | this.ufn = ufn; |
| | | this.isCreate = isCreate; |
| | | } |
| | | |
| | | /** |
| | | * Gets the first exception that caused this exception. |
| | | * |
| | | * @return Returns the first exception that caused this exception. |
| | | */ |
| | | @Override |
| | | public PropertyIsMandatoryException getCause() { |
| | | return causes.iterator().next(); |
| | | } |
| | | |
| | | /** |
| | | * Gets an unmodifiable collection view of the causes of this exception. |
| | | * |
| | | * @return Returns an unmodifiable collection view of the causes of this |
| | | * exception. |
| | | */ |
| | | public Collection<PropertyIsMandatoryException> getCauses() { |
| | | return Collections.unmodifiableCollection(causes); |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly name of the component that caused this exception. |
| | | * |
| | | * @return Returns the user friendly name of the component that caused this |
| | | * exception. |
| | | */ |
| | | public LocalizableMessage getUserFriendlyName() { |
| | | return ufn; |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether or not this exception was thrown during managed object |
| | | * creation or during modification. |
| | | * |
| | | * @return Returns <code>true</code> if this exception was thrown during |
| | | * managed object creation. |
| | | */ |
| | | public boolean isCreate() { |
| | | return isCreate; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| | | import static com.forgerock.opendj.ldap.AdminMessages.*; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizableMessageBuilder; |
| | | import org.forgerock.util.Reject; |
| | | |
| | | /** |
| | | * This exception is thrown when the client or server refuses to create, delete, |
| | | * or modify a managed object due to one or more constraints that cannot be |
| | | * satisfied. |
| | | * <p> |
| | | * Operations can be rejected either by a client-side constraint violation |
| | | * triggered by {@link ClientConstraintHandler}, or by a server-side error. |
| | | * <p> |
| | | * For example, the Directory Server might not be able perform an operation due |
| | | * to some OS related problem, such as lack of disk space, or missing files. |
| | | */ |
| | | public class OperationRejectedException extends AdminClientException { |
| | | |
| | | /** |
| | | * The type of operation that caused this exception. |
| | | */ |
| | | public enum OperationType { |
| | | /** |
| | | * A managed object could not be created. |
| | | */ |
| | | CREATE, |
| | | |
| | | /** |
| | | * A managed object could not be deleted. |
| | | */ |
| | | DELETE, |
| | | |
| | | /** |
| | | * A managed object could not be modified. |
| | | */ |
| | | MODIFY; |
| | | } |
| | | |
| | | /** |
| | | * Serialization ID. |
| | | */ |
| | | private static final long serialVersionUID = 8547688890613079044L; |
| | | |
| | | // Gets the default message. |
| | | private static LocalizableMessage getDefaultMessage(Collection<LocalizableMessage> messages) { |
| | | Reject.ifNull(messages); |
| | | Reject.ifFalse(!messages.isEmpty(), "Messages should not be empty"); |
| | | |
| | | if (messages.size() == 1) { |
| | | return ERR_OPERATION_REJECTED_EXCEPTION_SINGLE.get(messages.iterator().next()); |
| | | } else { |
| | | return ERR_OPERATION_REJECTED_EXCEPTION_PLURAL.get(getSingleMessage(messages)); |
| | | } |
| | | } |
| | | |
| | | // Merge the messages into a single message. |
| | | private static LocalizableMessage getSingleMessage(Collection<LocalizableMessage> messages) { |
| | | if (messages.size() == 1) { |
| | | return messages.iterator().next(); |
| | | } else { |
| | | LocalizableMessageBuilder builder = new LocalizableMessageBuilder(); |
| | | |
| | | boolean isFirst = true; |
| | | for (LocalizableMessage m : messages) { |
| | | if (!isFirst) { |
| | | builder.append("; "); |
| | | } |
| | | builder.append(m); |
| | | isFirst = false; |
| | | } |
| | | |
| | | return builder.toMessage(); |
| | | } |
| | | } |
| | | |
| | | // The messages describing the constraint violations that occurred. |
| | | private final Collection<LocalizableMessage> messages; |
| | | |
| | | // The type of operation that caused this exception. |
| | | private final OperationType type; |
| | | |
| | | // The user friendly name of the component that caused this |
| | | // exception. |
| | | private final LocalizableMessage ufn; |
| | | |
| | | /** |
| | | * Creates a new operation rejected exception with a default message. |
| | | * |
| | | * @param type |
| | | * The type of operation that caused this exception. |
| | | * @param ufn |
| | | * The user friendly name of the component that caused this |
| | | * exception. |
| | | */ |
| | | public OperationRejectedException(OperationType type, LocalizableMessage ufn) { |
| | | this(type, ufn, ERR_OPERATION_REJECTED_DEFAULT.get()); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new operation rejected exception with the provided messages. |
| | | * |
| | | * @param type |
| | | * The type of operation that caused this exception. |
| | | * @param ufn |
| | | * The user friendly name of the component that caused this |
| | | * exception. |
| | | * @param messages |
| | | * The messages describing the constraint violations that |
| | | * occurred (must be non-<code>null</code> and non-empty). |
| | | */ |
| | | public OperationRejectedException(OperationType type, LocalizableMessage ufn, |
| | | Collection<LocalizableMessage> messages) { |
| | | super(getDefaultMessage(messages)); |
| | | |
| | | this.messages = new ArrayList<LocalizableMessage>(messages); |
| | | this.type = type; |
| | | this.ufn = ufn; |
| | | } |
| | | |
| | | /** |
| | | * Creates a new operation rejected exception with the provided message. |
| | | * |
| | | * @param type |
| | | * The type of operation that caused this exception. |
| | | * @param ufn |
| | | * The user friendly name of the component that caused this |
| | | * exception. |
| | | * @param message |
| | | * The message describing the constraint violation that occurred. |
| | | */ |
| | | public OperationRejectedException(OperationType type, LocalizableMessage ufn, LocalizableMessage message) { |
| | | this(type, ufn, Collections.singleton(message)); |
| | | } |
| | | |
| | | /** |
| | | * Gets an unmodifiable collection view of the messages describing the |
| | | * constraint violations that occurred. |
| | | * |
| | | * @return Returns an unmodifiable collection view of the messages |
| | | * describing the constraint violations that occurred. |
| | | */ |
| | | public Collection<LocalizableMessage> getMessages() { |
| | | return Collections.unmodifiableCollection(messages); |
| | | } |
| | | |
| | | /** |
| | | * Creates a single message listing all the messages combined into a single |
| | | * list separated by semi-colons. |
| | | * |
| | | * @return Returns a single message listing all the messages combined into a |
| | | * single list separated by semi-colons. |
| | | */ |
| | | public LocalizableMessage getMessagesAsSingleMessage() { |
| | | return getSingleMessage(messages); |
| | | } |
| | | |
| | | /** |
| | | * Gets the type of operation that caused this exception. |
| | | * |
| | | * @return Returns the type of operation that caused this exception. |
| | | */ |
| | | public OperationType getOperationType() { |
| | | return type; |
| | | } |
| | | |
| | | /** |
| | | * Gets the user friendly name of the component that caused this exception. |
| | | * |
| | | * @return Returns the user friendly name of the component that caused this |
| | | * exception. |
| | | */ |
| | | public LocalizableMessage getUserFriendlyName() { |
| | | return ufn; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client.ldap; |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.Entry; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | import org.forgerock.opendj.ldap.requests.ModifyRequest; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | |
| | | /** |
| | | * An LDAP connection adaptor interface which is used to perform LDAP client |
| | | * operations. |
| | | * <p> |
| | | * This interface is provided in order to make it easier to keep track of which |
| | | * JNDI DirContext methods we require and also to facilitate implementation of |
| | | * mock JNDI contexts for unit-testing. |
| | | */ |
| | | public abstract class LDAPConnection { |
| | | |
| | | /** |
| | | * Create a new LDAP connection. |
| | | */ |
| | | protected LDAPConnection() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * Creates a new entry. |
| | | * |
| | | * @param entry |
| | | * The entry to create. |
| | | * @throws ErrorResultException |
| | | * If an error occurred whilst creating the entry. |
| | | */ |
| | | public abstract void createEntry(Entry entry) throws ErrorResultException; |
| | | |
| | | /** |
| | | * Deletes the named subtree. |
| | | * |
| | | * @param dn |
| | | * The name of the subtree to be deleted. |
| | | * @throws ErrorResultException |
| | | * If an error occurred whilst deleting the subtree. |
| | | */ |
| | | public abstract void deleteSubtree(DN dn) throws ErrorResultException; |
| | | |
| | | /** |
| | | * Determines whether or not the named entry exists. |
| | | * |
| | | * @param dn |
| | | * The name of the entry. |
| | | * @return Returns <code>true</code> if the entry exists. |
| | | * @throws ErrorResultException |
| | | * If an error occurred whilst making the determination. |
| | | */ |
| | | public abstract boolean entryExists(DN dn) throws ErrorResultException; |
| | | |
| | | /** |
| | | * Lists the children of the named entry. |
| | | * |
| | | * @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 ErrorResultException |
| | | * If an error occurred whilst listing the children. |
| | | */ |
| | | public abstract Collection<DN> listEntries(DN dn, String filter) throws ErrorResultException; |
| | | |
| | | /** |
| | | * Modifies an entry according to the provided modify request. |
| | | * |
| | | * @param request |
| | | * The modification request to perform. |
| | | * @throws ErrorResultException |
| | | * If an error occurred whilst applying the modifications. |
| | | */ |
| | | public abstract void modifyEntry(ModifyRequest request) throws ErrorResultException; |
| | | |
| | | /** |
| | | * Reads the attributes of the named entry. |
| | | * |
| | | * @param dn |
| | | * The name of the entry to be read. |
| | | * @param attrIds |
| | | * The list of attributes to be retrievd. |
| | | * @return Returns the attributes of the requested entry. |
| | | * @throws ErrorResultException |
| | | * If an error occurred whilst reading the entry. |
| | | */ |
| | | public abstract SearchResultEntry readEntry(DN dn, Collection<String> attrIds) throws ErrorResultException; |
| | | |
| | | /** |
| | | * Closes the LDAP connection. |
| | | */ |
| | | public abstract void unbind(); |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013 ForgeRock, AS. |
| | | */ |
| | | package org.forgerock.opendj.config.client.ldap; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.server.config.client.RootCfgClient; |
| | | import org.forgerock.opendj.server.config.meta.RootCfgDefn; |
| | | import org.forgerock.opendj.config.AbstractManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.AggregationPropertyDefinition; |
| | | import org.forgerock.opendj.config.Configuration; |
| | | import org.forgerock.opendj.config.ConfigurationClient; |
| | | import org.forgerock.opendj.config.DefaultBehaviorException; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException; |
| | | import org.forgerock.opendj.config.DefinitionResolver; |
| | | import org.forgerock.opendj.config.IllegalPropertyValueStringException; |
| | | import org.forgerock.opendj.config.InstantiableRelationDefinition; |
| | | import org.forgerock.opendj.config.LDAPProfile; |
| | | import org.forgerock.opendj.config.ManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectNotFoundException; |
| | | import org.forgerock.opendj.config.ManagedObjectPath; |
| | | import org.forgerock.opendj.config.PropertyDefinition; |
| | | import org.forgerock.opendj.config.PropertyDefinitionVisitor; |
| | | import org.forgerock.opendj.config.PropertyDefinitionsOptions; |
| | | import org.forgerock.opendj.config.PropertyException; |
| | | import org.forgerock.opendj.config.PropertyIsMandatoryException; |
| | | import org.forgerock.opendj.config.PropertyIsSingleValuedException; |
| | | import org.forgerock.opendj.config.PropertyOption; |
| | | import org.forgerock.opendj.config.Reference; |
| | | import org.forgerock.opendj.config.RelationDefinition; |
| | | import org.forgerock.opendj.config.SetRelationDefinition; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException.Reason; |
| | | import org.forgerock.opendj.config.client.ManagedObject; |
| | | import org.forgerock.opendj.config.client.ManagedObjectDecodingException; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException.OperationType; |
| | | import org.forgerock.opendj.config.client.spi.Driver; |
| | | import org.forgerock.opendj.config.client.spi.PropertySet; |
| | | import org.forgerock.opendj.ldap.Attribute; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | import org.forgerock.opendj.ldap.ResultCode; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | |
| | | /** |
| | | * The LDAP management context driver implementation. |
| | | */ |
| | | final class LDAPDriver extends Driver { |
| | | |
| | | /** |
| | | * A visitor which is used to decode property LDAP values. |
| | | */ |
| | | private static final class ValueDecoder extends PropertyDefinitionVisitor<Object, String> { |
| | | |
| | | private final PropertyDefinitionsOptions options; |
| | | |
| | | /** |
| | | * Decodes the provided property LDAP value. |
| | | * |
| | | * @param <P> |
| | | * The type of the property. |
| | | * @param pd |
| | | * The property definition. |
| | | * @param value |
| | | * The LDAP string representation. |
| | | * @param options |
| | | * Decoding options for property definitions. |
| | | * @return Returns the decoded LDAP value. |
| | | * @throws IllegalPropertyValueStringException |
| | | * If the property value could not be decoded because it was |
| | | * invalid. |
| | | */ |
| | | public static <P> P decode(PropertyDefinition<P> pd, Object value, PropertyDefinitionsOptions options) { |
| | | String s = String.valueOf(value); |
| | | return pd.castValue(pd.accept(new ValueDecoder(options), s)); |
| | | } |
| | | |
| | | // Prevent instantiation. |
| | | private ValueDecoder(PropertyDefinitionsOptions options) { |
| | | this.options = options; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> Object visitAggregation( |
| | | AggregationPropertyDefinition<C, S> d, String p) { |
| | | // Aggregations values are stored as full DNs in LDAP, but |
| | | // just their common name is exposed in the admin framework. |
| | | try { |
| | | Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d.getRelationDefinition(), p); |
| | | return reference.getName(); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new IllegalPropertyValueStringException(d, p); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <T> Object visitUnknown(PropertyDefinition<T> d, String p) { |
| | | // By default the property definition's decoder will do. |
| | | return d.decodeValue(p, options); |
| | | } |
| | | } |
| | | |
| | | private LDAPManagementContext context; |
| | | |
| | | private final LDAPConnection connection; |
| | | |
| | | // The LDAP profile which should be used to construct LDAP |
| | | // requests and decode LDAP responses. |
| | | private final LDAPProfile profile; |
| | | |
| | | /** |
| | | * Creates a new LDAP driver using the specified LDAP connection and |
| | | * profile. |
| | | * |
| | | * @param connection |
| | | * The LDAP connection. |
| | | * @param profile |
| | | * The LDAP profile. |
| | | * @param propertyDefOptions |
| | | * Options used to validate property definitions values |
| | | */ |
| | | public LDAPDriver(LDAPConnection connection, LDAPProfile profile, PropertyDefinitionsOptions propertyDefOptions) { |
| | | super(propertyDefOptions); |
| | | this.connection = connection; |
| | | this.profile = profile; |
| | | } |
| | | |
| | | void setManagementContext(LDAPManagementContext context) { |
| | | this.context = context; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public void close() { |
| | | connection.unbind(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getManagedObject( |
| | | ManagedObjectPath<C, S> path) throws DefinitionDecodingException, ManagedObjectDecodingException, |
| | | ManagedObjectNotFoundException, ErrorResultException { |
| | | if (!managedObjectExists(path)) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | |
| | | try { |
| | | // Read the entry associated with the managed object. |
| | | DN dn = LDAPNameBuilder.create(path, profile); |
| | | AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition(); |
| | | ManagedObjectDefinition<? extends C, ? extends S> mod = getEntryDefinition(d, dn); |
| | | |
| | | ArrayList<String> attrIds = new ArrayList<String>(); |
| | | for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) { |
| | | String attrId = profile.getAttributeName(mod, pd); |
| | | attrIds.add(attrId); |
| | | } |
| | | |
| | | SearchResultEntry searchResultEntry = connection.readEntry(dn, attrIds); |
| | | |
| | | // Build the managed object's properties. |
| | | List<PropertyException> exceptions = new LinkedList<PropertyException>(); |
| | | PropertySet newProperties = new PropertySet(); |
| | | for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) { |
| | | String attrID = profile.getAttributeName(mod, pd); |
| | | Attribute attribute = searchResultEntry.getAttribute(attrID); |
| | | try { |
| | | decodeProperty(newProperties, path, pd, attribute); |
| | | } catch (PropertyException e) { |
| | | exceptions.add(e); |
| | | } |
| | | } |
| | | |
| | | // If there were no decoding problems then return the object, |
| | | // otherwise throw an operations exception. |
| | | ManagedObject<? extends C> mo = createExistingManagedObject(mod, path, newProperties); |
| | | if (exceptions.isEmpty()) { |
| | | return mo; |
| | | } else { |
| | | throw new ManagedObjectDecodingException(mo, exceptions); |
| | | } |
| | | } catch (ErrorResultException e) { |
| | | if (e.getResult().getResultCode() == ResultCode.NO_SUCH_OBJECT) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration, P> SortedSet<P> getPropertyValues( |
| | | ManagedObjectPath<C, S> path, PropertyDefinition<P> propertyDef) throws DefinitionDecodingException, |
| | | ManagedObjectNotFoundException, ErrorResultException { |
| | | // Check that the requested property is from the definition |
| | | // associated with the path. |
| | | AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition(); |
| | | PropertyDefinition<?> tmp = d.getPropertyDefinition(propertyDef.getName()); |
| | | if (tmp != propertyDef) { |
| | | throw new IllegalArgumentException("The property " + propertyDef.getName() + " is not associated with a " |
| | | + d.getName()); |
| | | } |
| | | |
| | | if (!managedObjectExists(path)) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | |
| | | try { |
| | | // Read the entry associated with the managed object. |
| | | DN dn = LDAPNameBuilder.create(path, profile); |
| | | ManagedObjectDefinition<? extends C, ? extends S> objectDef = getEntryDefinition(d, dn); |
| | | |
| | | // Make sure we use the correct property definition, the |
| | | // provided one might have been overridden in the resolved |
| | | // definition. |
| | | propertyDef = (PropertyDefinition<P>) objectDef.getPropertyDefinition(propertyDef.getName()); |
| | | |
| | | String attrID = profile.getAttributeName(objectDef, propertyDef); |
| | | SearchResultEntry resultEntry = connection.readEntry(dn, Collections.singleton(attrID)); |
| | | Attribute attribute = resultEntry.getAttribute(attrID); |
| | | |
| | | // Decode the values. |
| | | SortedSet<P> values = new TreeSet<P>(propertyDef); |
| | | PropertyDefinitionsOptions options = context.getPropertyDefOptions(); |
| | | if (attribute != null) { |
| | | for (ByteString byteValue : attribute) { |
| | | P value = ValueDecoder.decode(propertyDef, byteValue, options); |
| | | values.add(value); |
| | | } |
| | | } |
| | | |
| | | // Sanity check the returned values. |
| | | if (values.size() > 1 && !propertyDef.hasOption(PropertyOption.MULTI_VALUED)) { |
| | | throw new PropertyIsSingleValuedException(propertyDef); |
| | | } |
| | | |
| | | if (values.isEmpty() && propertyDef.hasOption(PropertyOption.MANDATORY)) { |
| | | throw new PropertyIsMandatoryException(propertyDef); |
| | | } |
| | | |
| | | if (values.isEmpty()) { |
| | | // Use the property's default values. |
| | | values.addAll(findDefaultValues(path.asSubType(objectDef), propertyDef, false)); |
| | | } |
| | | |
| | | return values; |
| | | } catch (ErrorResultException e) { |
| | | if (e.getResult().getResultCode() == ResultCode.NO_SUCH_OBJECT) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ManagedObject<RootCfgClient> getRootConfigurationManagedObject() { |
| | | return new LDAPManagedObject<RootCfgClient>(this, RootCfgDefn.getInstance(), ManagedObjectPath.emptyPath(), |
| | | new PropertySet(), true, null); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws ManagedObjectNotFoundException, |
| | | ErrorResultException { |
| | | validateRelationDefinition(parent, rd); |
| | | |
| | | if (!managedObjectExists(parent)) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | |
| | | // Get the search base DN. |
| | | DN dn = LDAPNameBuilder.create(parent, rd, profile); |
| | | |
| | | // Retrieve only those entries which are sub-types of the |
| | | // specified definition. |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append("(objectclass="); |
| | | builder.append(profile.getObjectClass(d)); |
| | | builder.append(')'); |
| | | String filter = builder.toString(); |
| | | |
| | | List<String> children = new ArrayList<String>(); |
| | | try { |
| | | for (DN child : connection.listEntries(dn, filter)) { |
| | | children.add(child.rdn().getFirstAVA().getAttributeValue().toString()); |
| | | } |
| | | } catch (ErrorResultException e) { |
| | | if (e.getResult().getResultCode() == ResultCode.NO_SUCH_OBJECT) { |
| | | // Ignore this |
| | | // It means that the base entry does not exist |
| | | // It might not if this managed object has just been created. |
| | | } else { |
| | | throw e; |
| | | } |
| | | } |
| | | return children.toArray(new String[children.size()]); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects( |
| | | ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd, |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws ManagedObjectNotFoundException, |
| | | ErrorResultException { |
| | | validateRelationDefinition(parent, rd); |
| | | |
| | | if (!managedObjectExists(parent)) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | |
| | | // Get the search base DN. |
| | | DN dn = LDAPNameBuilder.create(parent, rd, profile); |
| | | |
| | | // Retrieve only those entries which are sub-types of the |
| | | // specified definition. |
| | | StringBuilder builder = new StringBuilder(); |
| | | builder.append("(objectclass="); |
| | | builder.append(profile.getObjectClass(d)); |
| | | builder.append(')'); |
| | | String filter = builder.toString(); |
| | | |
| | | List<String> children = new ArrayList<String>(); |
| | | try { |
| | | for (DN child : connection.listEntries(dn, filter)) { |
| | | children.add(child.rdn().getFirstAVA().getAttributeValue().toString()); |
| | | } |
| | | } catch (ErrorResultException e) { |
| | | if (e.getResult().getResultCode() == ResultCode.NO_SUCH_OBJECT) { |
| | | // Ignore this |
| | | // It means that the base entry does not exist |
| | | // It might not if this managed object has just been created. |
| | | } else { |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | return children.toArray(new String[children.size()]); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean managedObjectExists(ManagedObjectPath<?, ?> path) throws ManagedObjectNotFoundException, |
| | | ErrorResultException { |
| | | if (path.isEmpty()) { |
| | | return true; |
| | | } |
| | | |
| | | ManagedObjectPath<?, ?> parent = path.parent(); |
| | | DN dn = LDAPNameBuilder.create(parent, profile); |
| | | if (!entryExists(dn)) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | |
| | | dn = LDAPNameBuilder.create(path, profile); |
| | | return entryExists(dn); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected <C extends ConfigurationClient, S extends Configuration> void deleteManagedObject( |
| | | ManagedObjectPath<C, S> path) throws OperationRejectedException, ErrorResultException { |
| | | // Delete the entry and any subordinate entries. |
| | | DN dn = LDAPNameBuilder.create(path, profile); |
| | | try { |
| | | connection.deleteSubtree(dn); |
| | | } catch (ErrorResultException e) { |
| | | if (e.getResult().getResultCode() == ResultCode.UNWILLING_TO_PERFORM) { |
| | | AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition(); |
| | | LocalizableMessage m = LocalizableMessage.raw("%s", e.getMessage()); |
| | | throw new OperationRejectedException(OperationType.DELETE, d.getUserFriendlyName(), m); |
| | | } |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected LDAPManagementContext getManagementContext() { |
| | | return context; |
| | | } |
| | | |
| | | /** |
| | | * Determines whether the named LDAP entry exists. |
| | | * |
| | | * @param dn |
| | | * The LDAP entry name. |
| | | * @return Returns <code>true</code> if the named LDAP entry exists. |
| | | * @throws ErrorResultException |
| | | * if a problem occurs. |
| | | */ |
| | | boolean entryExists(DN dn) throws ErrorResultException { |
| | | return connection.entryExists(dn); |
| | | } |
| | | |
| | | /** |
| | | * Gets the LDAP connection used for interacting with the server. |
| | | * |
| | | * @return Returns the LDAP connection used for interacting with the server. |
| | | */ |
| | | LDAPConnection getLDAPConnection() { |
| | | return connection; |
| | | } |
| | | |
| | | /** |
| | | * Gets the LDAP profile which should be used to construct LDAP requests and |
| | | * decode LDAP responses. |
| | | * |
| | | * @return Returns the LDAP profile which should be used to construct LDAP |
| | | * requests and decode LDAP responses. |
| | | */ |
| | | LDAPProfile getLDAPProfile() { |
| | | return profile; |
| | | } |
| | | |
| | | // Create a managed object which already exists on the server. |
| | | private <M extends ConfigurationClient, N extends Configuration> ManagedObject<M> createExistingManagedObject( |
| | | 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; |
| | | pd = ird.getNamingPropertyDefinition(); |
| | | } |
| | | return new LDAPManagedObject<M>(this, d, p.asSubType(d), properties, true, pd); |
| | | } |
| | | |
| | | // Create a property using the provided string values. |
| | | private <P> void decodeProperty(PropertySet newProperties, ManagedObjectPath<?, ?> path, |
| | | PropertyDefinition<P> propertyDef, Attribute attribute) { |
| | | PropertyException exception = null; |
| | | |
| | | // Get the property's active values. |
| | | SortedSet<P> activeValues = new TreeSet<P>(propertyDef); |
| | | PropertyDefinitionsOptions options = context.getPropertyDefOptions(); |
| | | if (attribute != null) { |
| | | for (ByteString byteValue : attribute) { |
| | | P value = ValueDecoder.decode(propertyDef, byteValue, options); |
| | | activeValues.add(value); |
| | | } |
| | | } |
| | | |
| | | if (activeValues.size() > 1 && !propertyDef.hasOption(PropertyOption.MULTI_VALUED)) { |
| | | // This exception takes precedence over previous exceptions. |
| | | exception = new PropertyIsSingleValuedException(propertyDef); |
| | | P value = activeValues.first(); |
| | | activeValues.clear(); |
| | | activeValues.add(value); |
| | | } |
| | | |
| | | // Get the property's default values. |
| | | Collection<P> defaultValues; |
| | | try { |
| | | defaultValues = findDefaultValues(path, propertyDef, false); |
| | | } catch (DefaultBehaviorException e) { |
| | | defaultValues = Collections.emptySet(); |
| | | exception = e; |
| | | } |
| | | |
| | | newProperties.addProperty(propertyDef, defaultValues, activeValues); |
| | | |
| | | if (activeValues.isEmpty() && defaultValues.isEmpty() && propertyDef.hasOption(PropertyOption.MANDATORY)) { |
| | | // The active values maybe empty because of a previous |
| | | // exception. |
| | | if (exception == null) { |
| | | exception = new PropertyIsMandatoryException(propertyDef); |
| | | } |
| | | } |
| | | |
| | | if (exception != null) { |
| | | throw exception; |
| | | } |
| | | } |
| | | |
| | | // Determine the type of managed object associated with the named |
| | | // entry. |
| | | // @Checkstyle:off |
| | | private <C extends ConfigurationClient, S extends Configuration> ManagedObjectDefinition<? extends C, ? extends S> |
| | | getEntryDefinition(AbstractManagedObjectDefinition<C, S> d, DN dn) throws ErrorResultException, |
| | | DefinitionDecodingException { |
| | | // @Checkstyle:on |
| | | SearchResultEntry searchResultEntry = connection.readEntry(dn, Collections.singleton("objectclass")); |
| | | Attribute objectClassAttr = searchResultEntry.getAttribute("objectclass"); |
| | | |
| | | if (objectClassAttr == null) { |
| | | // No object classes. |
| | | throw new DefinitionDecodingException(d, Reason.NO_TYPE_INFORMATION); |
| | | } |
| | | |
| | | final Set<String> objectClasses = new HashSet<String>(); |
| | | for (ByteString byteValue : objectClassAttr) { |
| | | objectClasses.add(byteValue.toString().toLowerCase().trim()); |
| | | } |
| | | |
| | | if (objectClasses.isEmpty()) { |
| | | // No object classes. |
| | | throw new DefinitionDecodingException(d, Reason.NO_TYPE_INFORMATION); |
| | | } |
| | | |
| | | // Resolve the appropriate sub-type based on the object classes. |
| | | DefinitionResolver resolver = new DefinitionResolver() { |
| | | @Override |
| | | public boolean matches(AbstractManagedObjectDefinition<?, ?> d) { |
| | | String objectClass = profile.getObjectClass(d); |
| | | return objectClasses.contains(objectClass); |
| | | } |
| | | }; |
| | | |
| | | return d.resolveManagedObjectDefinition(resolver); |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2007-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config.client.ldap; |
| | | |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.config.AggregationPropertyDefinition; |
| | | import org.forgerock.opendj.config.Configuration; |
| | | import org.forgerock.opendj.config.ConfigurationClient; |
| | | import org.forgerock.opendj.config.InstantiableRelationDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectAlreadyExistsException; |
| | | import org.forgerock.opendj.config.ManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectNotFoundException; |
| | | import org.forgerock.opendj.config.ManagedObjectPath; |
| | | import org.forgerock.opendj.config.PropertyDefinition; |
| | | import org.forgerock.opendj.config.PropertyOption; |
| | | import org.forgerock.opendj.config.PropertyValueVisitor; |
| | | import org.forgerock.opendj.config.Reference; |
| | | import org.forgerock.opendj.config.RelationDefinition; |
| | | import org.forgerock.opendj.config.SetRelationDefinition; |
| | | import org.forgerock.opendj.config.client.ConcurrentModificationException; |
| | | import org.forgerock.opendj.config.client.ManagedObject; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException.OperationType; |
| | | import org.forgerock.opendj.config.client.spi.AbstractManagedObject; |
| | | import org.forgerock.opendj.config.client.spi.Driver; |
| | | import org.forgerock.opendj.config.client.spi.Property; |
| | | import org.forgerock.opendj.config.client.spi.PropertySet; |
| | | import org.forgerock.opendj.ldap.Attribute; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.Entry; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | import org.forgerock.opendj.ldap.LinkedAttribute; |
| | | import org.forgerock.opendj.ldap.LinkedHashMapEntry; |
| | | import org.forgerock.opendj.ldap.ModificationType; |
| | | import org.forgerock.opendj.ldap.ResultCode; |
| | | import org.forgerock.opendj.ldap.requests.ModifyRequest; |
| | | import org.forgerock.opendj.ldap.requests.Requests; |
| | | |
| | | /** |
| | | * A managed object bound to an LDAP connection. |
| | | * |
| | | * @param <T> |
| | | * The type of client configuration represented by the client managed |
| | | * object. |
| | | */ |
| | | final class LDAPManagedObject<T extends ConfigurationClient> extends AbstractManagedObject<T> { |
| | | |
| | | /** |
| | | * A visitor which is used to encode property LDAP values. |
| | | */ |
| | | private static final class ValueEncoder extends PropertyValueVisitor<Object, Void> { |
| | | |
| | | // Prevent instantiation. |
| | | private ValueEncoder() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> Object visitAggregation( |
| | | AggregationPropertyDefinition<C, S> pd, String v, Void p) { |
| | | // Aggregations values are stored as full DNs in LDAP, but |
| | | // just their common name is exposed in the admin framework. |
| | | Reference<C, S> reference = Reference.parseName(pd.getParentPath(), pd.getRelationDefinition(), v); |
| | | return reference.toDN().toString(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <P> Object visitUnknown(PropertyDefinition<P> propertyDef, P value, Void p) { |
| | | return propertyDef.encodeValue(value); |
| | | } |
| | | } |
| | | |
| | | // The LDAP management driver associated with this managed object. |
| | | private final LDAPDriver driver; |
| | | |
| | | /** |
| | | * Creates a new LDAP managed object instance. |
| | | * |
| | | * @param driver |
| | | * The underlying LDAP management driver. |
| | | * @param d |
| | | * The managed object's definition. |
| | | * @param path |
| | | * The managed object's path. |
| | | * @param properties |
| | | * The managed object's properties. |
| | | * @param existsOnServer |
| | | * Indicates whether or not the managed object already exists. |
| | | * @param namingPropertyDefinition |
| | | * The managed object's naming property definition if there is |
| | | * one. |
| | | */ |
| | | LDAPManagedObject(LDAPDriver driver, ManagedObjectDefinition<T, ? extends Configuration> d, |
| | | ManagedObjectPath<T, ? extends Configuration> path, PropertySet properties, boolean existsOnServer, |
| | | PropertyDefinition<?> namingPropertyDefinition) { |
| | | super(d, path, properties, existsOnServer, namingPropertyDefinition, |
| | | driver.getManagementContext().getPropertyDefOptions()); |
| | | this.driver = driver; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void addNewManagedObject() throws ErrorResultException, OperationRejectedException, |
| | | ConcurrentModificationException, ManagedObjectAlreadyExistsException { |
| | | // First make sure that the parent managed object still exists. |
| | | ManagedObjectDefinition<?, ?> d = getManagedObjectDefinition(); |
| | | ManagedObjectPath<?, ?> path = getManagedObjectPath(); |
| | | ManagedObjectPath<?, ?> parent = path.parent(); |
| | | |
| | | try { |
| | | if (!driver.managedObjectExists(parent)) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | |
| | | // We may need to create the parent "relation" entry if this is a |
| | | // child of an instantiable or set relation. |
| | | RelationDefinition<?, ?> r = path.getRelationDefinition(); |
| | | if (r instanceof InstantiableRelationDefinition || r instanceof SetRelationDefinition) { |
| | | |
| | | // TODO: this implementation does not handle relations which |
| | | // comprise of more than one RDN arc (this will probably never |
| | | // be required anyway). |
| | | DN dn; |
| | | if (r instanceof InstantiableRelationDefinition) { |
| | | dn = LDAPNameBuilder.create(parent, (InstantiableRelationDefinition<?, ?>) r, |
| | | driver.getLDAPProfile()); |
| | | } else { |
| | | dn = LDAPNameBuilder.create(parent, (SetRelationDefinition<?, ?>) r, |
| | | driver.getLDAPProfile()); |
| | | } |
| | | |
| | | if (!driver.entryExists(dn)) { |
| | | Entry entry = new LinkedHashMapEntry(dn); |
| | | |
| | | // Create the branch's object class attribute. |
| | | List<String> objectClasses = driver.getLDAPProfile().getRelationObjectClasses(r); |
| | | addObjectClassesToEntry(objectClasses, entry); |
| | | |
| | | // Create the branch's naming attribute. |
| | | entry.addAttribute(dn.rdn().getFirstAVA().toAttribute()); |
| | | |
| | | // Create the entry. |
| | | try { |
| | | driver.getLDAPConnection().createEntry(entry); |
| | | } catch (ErrorResultException e) { |
| | | if (e.getResult().getResultCode() == ResultCode.UNWILLING_TO_PERFORM) { |
| | | LocalizableMessage m = LocalizableMessage.raw("%s", e.getLocalizedMessage()); |
| | | throw new OperationRejectedException(OperationType.CREATE, d.getUserFriendlyName(), m); |
| | | } else { |
| | | throw e; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Now add the entry representing this new managed object. |
| | | DN dn = LDAPNameBuilder.create(path, driver.getLDAPProfile()); |
| | | Entry entry = new LinkedHashMapEntry(dn); |
| | | |
| | | // Create the object class attribute. |
| | | ManagedObjectDefinition<?, ?> definition = getManagedObjectDefinition(); |
| | | List<String> objectClasses = driver.getLDAPProfile().getObjectClasses(definition); |
| | | addObjectClassesToEntry(objectClasses, entry); |
| | | |
| | | // Create the naming attribute if there is not naming property. |
| | | PropertyDefinition<?> namingPropertyDef = getNamingPropertyDefinition(); |
| | | if (namingPropertyDef == null) { |
| | | entry.addAttribute(dn.rdn().getFirstAVA().toAttribute()); |
| | | } |
| | | |
| | | // Create the remaining attributes. |
| | | for (PropertyDefinition<?> propertyDef : definition.getAllPropertyDefinitions()) { |
| | | String attrID = driver.getLDAPProfile().getAttributeName(definition, propertyDef); |
| | | Attribute attribute = new LinkedAttribute(attrID); |
| | | encodeProperty(attribute, propertyDef); |
| | | if (attribute.size() != 0) { |
| | | entry.addAttribute(attribute); |
| | | } |
| | | } |
| | | |
| | | try { |
| | | // Create the entry. |
| | | driver.getLDAPConnection().createEntry(entry); |
| | | } catch (ErrorResultException e) { |
| | | if (e.getResult().getResultCode() == ResultCode.ENTRY_ALREADY_EXISTS) { |
| | | throw new ManagedObjectAlreadyExistsException(); |
| | | } else if (e.getResult().getResultCode() == ResultCode.UNWILLING_TO_PERFORM) { |
| | | LocalizableMessage m = LocalizableMessage.raw("%s", e.getLocalizedMessage()); |
| | | throw new OperationRejectedException(OperationType.CREATE, d.getUserFriendlyName(), m); |
| | | } else { |
| | | throw e; |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void addObjectClassesToEntry(List<String> objectClasses, Entry entry) { |
| | | for (String objectClass : objectClasses) { |
| | | Attribute attr = new LinkedAttribute("objectClass"); |
| | | attr.add(ByteString.valueOf(objectClass)); |
| | | entry.addAttribute(attr); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected Driver getDriver() { |
| | | return driver; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected void modifyExistingManagedObject() throws ConcurrentModificationException, OperationRejectedException, |
| | | ErrorResultException { |
| | | // Build the modify request |
| | | ManagedObjectPath<?, ?> path = getManagedObjectPath(); |
| | | DN dn = LDAPNameBuilder.create(path, driver.getLDAPProfile()); |
| | | ModifyRequest request = Requests.newModifyRequest(dn); |
| | | ManagedObjectDefinition<?, ?> d = getManagedObjectDefinition(); |
| | | for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { |
| | | Property<?> p = getProperty(pd); |
| | | if (p.isModified()) { |
| | | String attrID = driver.getLDAPProfile().getAttributeName(d, pd); |
| | | Attribute attribute = new LinkedAttribute(attrID); |
| | | encodeProperty(attribute, pd); |
| | | request.addModification(ModificationType.REPLACE, attrID, |
| | | attribute.toArray(new Object[attribute.size()])); |
| | | } |
| | | } |
| | | |
| | | // Perform the LDAP modification if something has changed. |
| | | if (!request.getModifications().isEmpty()) { |
| | | try { |
| | | driver.getLDAPConnection().modifyEntry(request); |
| | | } catch (ErrorResultException e) { |
| | | if (e.getResult().getResultCode() == ResultCode.UNWILLING_TO_PERFORM) { |
| | | LocalizableMessage m = LocalizableMessage.raw("%s", e.getLocalizedMessage()); |
| | | throw new OperationRejectedException(OperationType.CREATE, d.getUserFriendlyName(), m); |
| | | } else { |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | protected <M extends ConfigurationClient> ManagedObject<M> newInstance(ManagedObjectDefinition<M, ?> d, |
| | | ManagedObjectPath<M, ?> path, PropertySet properties, boolean existsOnServer, |
| | | PropertyDefinition<?> namingPropertyDefinition) { |
| | | return new LDAPManagedObject<M>(driver, d, path, properties, existsOnServer, namingPropertyDefinition); |
| | | } |
| | | |
| | | // Encode a property into LDAP string values. |
| | | private <P> void encodeProperty(Attribute attribute, PropertyDefinition<P> propertyDef) { |
| | | PropertyValueVisitor<Object, Void> visitor = new ValueEncoder(); |
| | | Property<P> property = getProperty(propertyDef); |
| | | if (propertyDef.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 (P value : property.getEffectiveValues()) { |
| | | attribute.add(propertyDef.accept(visitor, value, null)); |
| | | } |
| | | } else { |
| | | for (P value : property.getPendingValues()) { |
| | | attribute.add(propertyDef.accept(visitor, value, null)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isModified() { |
| | | ManagedObjectDefinition<?, ?> d = getManagedObjectDefinition(); |
| | | for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { |
| | | Property<?> p = getProperty(pd); |
| | | if (p.isModified()) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config.client.ldap; |
| | | |
| | | import org.forgerock.opendj.config.LDAPProfile; |
| | | import org.forgerock.opendj.config.PropertyDefinitionsOptions; |
| | | import org.forgerock.opendj.config.client.ManagementContext; |
| | | import org.forgerock.opendj.config.client.spi.Driver; |
| | | import org.forgerock.util.Reject; |
| | | |
| | | /** |
| | | * An LDAP management connection context. |
| | | */ |
| | | public final class LDAPManagementContext extends ManagementContext { |
| | | |
| | | /** |
| | | * Create a new LDAP management context using the provided LDAP connection. |
| | | * |
| | | * @param connection |
| | | * The LDAP connection. |
| | | * @param profile |
| | | * The LDAP profile. |
| | | * @param options |
| | | * Options to decode values of property definitions. |
| | | * @return Returns the new management context. |
| | | */ |
| | | public static ManagementContext createFromContext(LDAPConnection connection, LDAPProfile profile, |
| | | PropertyDefinitionsOptions options) { |
| | | Reject.ifNull(connection, profile, options); |
| | | LDAPDriver driver = new LDAPDriver(connection, profile, options); |
| | | LDAPManagementContext context = new LDAPManagementContext(driver, options); |
| | | driver.setManagementContext(context); |
| | | return context; |
| | | } |
| | | |
| | | /** The LDAP management context driver. */ |
| | | private final LDAPDriver driver; |
| | | |
| | | /** Options to validate and decode values of property definitions. */ |
| | | private final PropertyDefinitionsOptions options; |
| | | |
| | | /** Private constructor. */ |
| | | private LDAPManagementContext(LDAPDriver driver, PropertyDefinitionsOptions options) { |
| | | this.driver = driver; |
| | | this.options = options; |
| | | } |
| | | |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | protected Driver getDriver() { |
| | | return driver; |
| | | } |
| | | |
| | | /** |
| | | * Returns the property definitions options. |
| | | * |
| | | * @return the options to validate and decode values of property |
| | | * definitions. |
| | | */ |
| | | protected PropertyDefinitionsOptions getPropertyDefOptions() { |
| | | return options; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.config.client.ldap; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.config.AbstractManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.Configuration; |
| | | import org.forgerock.opendj.config.ConfigurationClient; |
| | | import org.forgerock.opendj.config.InstantiableRelationDefinition; |
| | | import org.forgerock.opendj.config.LDAPProfile; |
| | | import org.forgerock.opendj.config.ManagedObjectPath; |
| | | import org.forgerock.opendj.config.ManagedObjectPathSerializer; |
| | | import org.forgerock.opendj.config.OptionalRelationDefinition; |
| | | import org.forgerock.opendj.config.RelationDefinition; |
| | | import org.forgerock.opendj.config.SetRelationDefinition; |
| | | import org.forgerock.opendj.config.SingletonRelationDefinition; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.RDN; |
| | | |
| | | /** |
| | | * A strategy for creating <code>DN</code>s from managed object paths. |
| | | */ |
| | | final class LDAPNameBuilder implements ManagedObjectPathSerializer { |
| | | |
| | | /** |
| | | * Creates a new DN representing the specified managed object path. |
| | | * |
| | | * @param path |
| | | * The managed object path. |
| | | * @param profile |
| | | * The LDAP profile which should be used to construct LDAP names. |
| | | * @return Returns a new DN representing the specified managed object path. |
| | | */ |
| | | public static DN create(ManagedObjectPath<?, ?> path, LDAPProfile profile) { |
| | | LDAPNameBuilder builder = new LDAPNameBuilder(profile); |
| | | path.serialize(builder); |
| | | return builder.getInstance(); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new DN representing the specified managed object path and |
| | | * instantiable relation. |
| | | * |
| | | * @param path |
| | | * The managed object path. |
| | | * @param relation |
| | | * The child instantiable relation. |
| | | * @param profile |
| | | * The LDAP profile which should be used to construct LDAP names. |
| | | * @return Returns a new DN representing the specified managed object path |
| | | * and instantiable relation. |
| | | */ |
| | | public static DN create(ManagedObjectPath<?, ?> path, InstantiableRelationDefinition<?, ?> relation, |
| | | LDAPProfile profile) { |
| | | LDAPNameBuilder builder = new LDAPNameBuilder(profile); |
| | | path.serialize(builder); |
| | | builder.appendManagedObjectPathElement(relation); |
| | | return builder.getInstance(); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new DN representing the specified managed object path and set |
| | | * relation. |
| | | * |
| | | * @param path |
| | | * The managed object path. |
| | | * @param relation |
| | | * The child set relation. |
| | | * @param profile |
| | | * The LDAP profile which should be used to construct LDAP names. |
| | | * @return Returns a new DN representing the specified managed object path |
| | | * and set relation. |
| | | */ |
| | | public static DN create(ManagedObjectPath<?, ?> path, SetRelationDefinition<?, ?> relation, LDAPProfile profile) { |
| | | LDAPNameBuilder builder = new LDAPNameBuilder(profile); |
| | | path.serialize(builder); |
| | | builder.appendManagedObjectPathElement(relation); |
| | | return builder.getInstance(); |
| | | } |
| | | |
| | | /** The list of RDNs in big-endian order. */ |
| | | private final LinkedList<RDN> rdns; |
| | | |
| | | private final LDAPProfile profile; |
| | | |
| | | /** |
| | | * Create a new DN builder. |
| | | * |
| | | * @param profile |
| | | * The LDAP profile which should be used to construct DNs. |
| | | */ |
| | | public LDAPNameBuilder(LDAPProfile profile) { |
| | | this.rdns = new LinkedList<RDN>(); |
| | | this.profile = profile; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | InstantiableRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d, |
| | | String name) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement(r); |
| | | |
| | | // Now add the single RDN representing the named instance. |
| | | String type = profile.getRelationChildRDNType(r); |
| | | RDN rdn = new RDN(type, name.trim()); |
| | | rdns.add(rdn); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Appends the RDN sequence representing the provided relation. |
| | | * |
| | | * @param r |
| | | * The relation definition. |
| | | */ |
| | | public void appendManagedObjectPathElement(RelationDefinition<?, ?> r) { |
| | | // Add the RDN sequence representing the relation. |
| | | DN dn = DN.valueOf(profile.getRelationRDNSequence(r)); |
| | | List<RDN> rdnsOfDn = getRdnsInBigEndianOrder(dn); |
| | | rdns.addAll(rdnsOfDn); |
| | | } |
| | | |
| | | /** |
| | | * Returns list of RDNs of provided DN in big-endian order. |
| | | * |
| | | * @param dn |
| | | * The DN to decompose in RDNs. |
| | | * @return rdns in big endian order |
| | | */ |
| | | private List<RDN> getRdnsInBigEndianOrder(DN dn) { |
| | | List<RDN> rdnsOfDn = new ArrayList<RDN>(); |
| | | for (RDN rdn : dn) { |
| | | rdnsOfDn.add(rdn); |
| | | } |
| | | Collections.reverse(rdnsOfDn); |
| | | return rdnsOfDn; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | OptionalRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement(r); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | SingletonRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement(r); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public <C extends ConfigurationClient, S extends Configuration> void appendManagedObjectPathElement( |
| | | SetRelationDefinition<? super C, ? super S> r, AbstractManagedObjectDefinition<C, S> d) { |
| | | // Add the RDN sequence representing the relation. |
| | | appendManagedObjectPathElement(r); |
| | | |
| | | // Now add the single RDN representing the named instance. |
| | | String type = profile.getRelationChildRDNType(r); |
| | | RDN rdn = new RDN(type, d.getName()); |
| | | rdns.add(rdn); |
| | | } |
| | | |
| | | /** |
| | | * Create a new DN using the current state of this builder. |
| | | * |
| | | * @return Returns the new DN instance. |
| | | */ |
| | | public DN getInstance() { |
| | | DN dn = DN.rootDN(); |
| | | for (RDN rdn : rdns) { |
| | | dn = dn.child(rdn); |
| | | } |
| | | return dn; |
| | | } |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | |
| | | |
| | | /** |
| | | * LDAP configuration transport implementation. |
| | | * <p> |
| | | * This implementation uses JNDI for all communication. It is expected |
| | | * that, at some point in the future, we will replace this implementation |
| | | * with our own LDAP client SDK based implementation. |
| | | */ |
| | | package org.forgerock.opendj.config.client.ldap; |
| | | |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | /** |
| | | * Common client-side administration classes. |
| | | * <p> |
| | | * This package contains classes which client applications are |
| | | * expected to use. |
| | | */ |
| | | package org.forgerock.opendj.config.client; |
| | | |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client.spi; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.config.AbstractManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.Configuration; |
| | | import org.forgerock.opendj.config.ConfigurationClient; |
| | | import org.forgerock.opendj.config.Constraint; |
| | | import org.forgerock.opendj.config.DefaultBehaviorException; |
| | | import org.forgerock.opendj.config.DefaultManagedObject; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException; |
| | | import org.forgerock.opendj.config.IllegalPropertyValueStringException; |
| | | import org.forgerock.opendj.config.InstantiableRelationDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectAlreadyExistsException; |
| | | import org.forgerock.opendj.config.ManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectNotFoundException; |
| | | import org.forgerock.opendj.config.ManagedObjectPath; |
| | | import org.forgerock.opendj.config.OptionalRelationDefinition; |
| | | import org.forgerock.opendj.config.PropertyDefinition; |
| | | import org.forgerock.opendj.config.PropertyDefinitionsOptions; |
| | | import org.forgerock.opendj.config.PropertyIsMandatoryException; |
| | | import org.forgerock.opendj.config.PropertyIsReadOnlyException; |
| | | import org.forgerock.opendj.config.PropertyOption; |
| | | import org.forgerock.opendj.config.RelationDefinition; |
| | | import org.forgerock.opendj.config.RelationDefinitionVisitor; |
| | | import org.forgerock.opendj.config.SetRelationDefinition; |
| | | import org.forgerock.opendj.config.SingletonRelationDefinition; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException.Reason; |
| | | import org.forgerock.opendj.config.client.ClientConstraintHandler; |
| | | import org.forgerock.opendj.config.client.ConcurrentModificationException; |
| | | import org.forgerock.opendj.config.client.IllegalManagedObjectNameException; |
| | | import org.forgerock.opendj.config.client.ManagedObject; |
| | | import org.forgerock.opendj.config.client.ManagedObjectDecodingException; |
| | | import org.forgerock.opendj.config.client.ManagementContext; |
| | | import org.forgerock.opendj.config.client.MissingMandatoryPropertiesException; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException.OperationType; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | |
| | | /** |
| | | * An abstract managed object implementation. |
| | | * |
| | | * @param <T> |
| | | * The type of client configuration represented by the client managed |
| | | * object. |
| | | */ |
| | | public abstract class AbstractManagedObject<T extends ConfigurationClient> implements ManagedObject<T> { |
| | | |
| | | /** |
| | | * Creates any default managed objects associated with a relation |
| | | * definition. |
| | | */ |
| | | private final class DefaultManagedObjectFactory implements RelationDefinitionVisitor<Void, Void> { |
| | | |
| | | // Possible exceptions. |
| | | private ManagedObjectAlreadyExistsException moaee = null; |
| | | |
| | | private MissingMandatoryPropertiesException mmpe = null; |
| | | |
| | | private ConcurrentModificationException cme = null; |
| | | |
| | | private OperationRejectedException ore = null; |
| | | |
| | | private ErrorResultException ere = null; |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> Void visitInstantiable( |
| | | InstantiableRelationDefinition<C, S> rd, Void p) { |
| | | for (String name : rd.getDefaultManagedObjectNames()) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd.getDefaultManagedObject(name); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo.getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child; |
| | | try { |
| | | child = createChild(rd, d, name, null); |
| | | } catch (IllegalManagedObjectNameException e) { |
| | | // This should not happen. |
| | | throw new RuntimeException(e); |
| | | } |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> Void visitOptional( |
| | | OptionalRelationDefinition<C, S> rd, Void p) { |
| | | if (rd.getDefaultManagedObject() != null) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd.getDefaultManagedObject(); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo.getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child = createChild(rd, d, null); |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> Void visitSingleton( |
| | | SingletonRelationDefinition<C, S> rd, Void p) { |
| | | // Do nothing - not possible to create singletons |
| | | // dynamically. |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public <C extends ConfigurationClient, S extends Configuration> Void visitSet(SetRelationDefinition<C, S> rd, |
| | | Void p) { |
| | | for (String name : rd.getDefaultManagedObjectNames()) { |
| | | DefaultManagedObject<? extends C, ? extends S> dmo = rd.getDefaultManagedObject(name); |
| | | ManagedObjectDefinition<? extends C, ? extends S> d = dmo.getManagedObjectDefinition(); |
| | | ManagedObject<? extends C> child = createChild(rd, d, null); |
| | | createDefaultManagedObject(d, child, dmo); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // Create the child managed object. |
| | | private void createDefaultManagedObject(ManagedObjectDefinition<?, ?> d, ManagedObject<?> child, |
| | | DefaultManagedObject<?, ?> dmo) { |
| | | for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { |
| | | setPropertyValues(child, pd, dmo); |
| | | } |
| | | |
| | | try { |
| | | child.commit(); |
| | | } catch (ManagedObjectAlreadyExistsException e) { |
| | | moaee = e; |
| | | } catch (MissingMandatoryPropertiesException e) { |
| | | mmpe = e; |
| | | } catch (ConcurrentModificationException e) { |
| | | cme = e; |
| | | } catch (OperationRejectedException e) { |
| | | ore = e; |
| | | } catch (ErrorResultException e) { |
| | | ere = e; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Creates the default managed objects associated with the provided |
| | | * relation definition. |
| | | * |
| | | * @param rd |
| | | * The relation definition. |
| | | */ |
| | | private void createDefaultManagedObjects(RelationDefinition<?, ?> rd) throws ErrorResultException, |
| | | ConcurrentModificationException, MissingMandatoryPropertiesException, |
| | | ManagedObjectAlreadyExistsException, OperationRejectedException { |
| | | rd.accept(this, null); |
| | | |
| | | if (ere != null) { |
| | | throw ere; |
| | | } else if (cme != null) { |
| | | throw cme; |
| | | } else if (mmpe != null) { |
| | | throw mmpe; |
| | | } else if (moaee != null) { |
| | | throw moaee; |
| | | } else if (ore != null) { |
| | | throw ore; |
| | | } |
| | | } |
| | | |
| | | // Set property values. |
| | | private <P> void setPropertyValues(ManagedObject<?> mo, PropertyDefinition<P> pd, |
| | | DefaultManagedObject<?, ?> dmo) { |
| | | mo.setPropertyValues(pd, dmo.getPropertyValues(pd)); |
| | | } |
| | | } |
| | | |
| | | // The managed object definition associated with this managed |
| | | // object. |
| | | 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 |
| | | // committed). |
| | | private boolean existsOnServer; |
| | | |
| | | // Optional naming property definition. |
| | | private final PropertyDefinition<?> namingPropertyDefinition; |
| | | |
| | | // The path associated with this managed object. |
| | | private ManagedObjectPath<T, ? extends Configuration> path; |
| | | |
| | | // The managed object's properties. |
| | | private final PropertySet properties; |
| | | |
| | | /** Decoding options for property definitions values. */ |
| | | private final PropertyDefinitionsOptions propertyDefOptions; |
| | | |
| | | /** |
| | | * Creates a new abstract managed object. |
| | | * |
| | | * @param d |
| | | * The managed object's definition. |
| | | * @param path |
| | | * The managed object's path. |
| | | * @param properties |
| | | * The managed object's properties. |
| | | * @param existsOnServer |
| | | * Indicates whether or not the managed object exists on the |
| | | * server (false means the managed object is new and has not been |
| | | * committed). |
| | | * @param namingPropertyDefinition |
| | | * Optional naming property definition. |
| | | * @param propertyDefOptions TODO |
| | | */ |
| | | protected AbstractManagedObject(ManagedObjectDefinition<T, ? extends Configuration> d, |
| | | ManagedObjectPath<T, ? extends Configuration> path, PropertySet properties, boolean existsOnServer, |
| | | PropertyDefinition<?> namingPropertyDefinition, PropertyDefinitionsOptions propertyDefOptions) { |
| | | this.definition = d; |
| | | this.path = path; |
| | | this.properties = properties; |
| | | this.existsOnServer = existsOnServer; |
| | | this.namingPropertyDefinition = namingPropertyDefinition; |
| | | this.propertyDefOptions = propertyDefOptions; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final void commit() throws ManagedObjectAlreadyExistsException, MissingMandatoryPropertiesException, |
| | | ConcurrentModificationException, OperationRejectedException, ErrorResultException { |
| | | // First make sure all mandatory properties are defined. |
| | | List<PropertyIsMandatoryException> exceptions = new LinkedList<PropertyIsMandatoryException>(); |
| | | |
| | | for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) { |
| | | Property<?> p = getProperty(pd); |
| | | if (pd.hasOption(PropertyOption.MANDATORY) && p.getEffectiveValues().isEmpty()) { |
| | | exceptions.add(new PropertyIsMandatoryException(pd)); |
| | | } |
| | | } |
| | | |
| | | if (!exceptions.isEmpty()) { |
| | | throw new MissingMandatoryPropertiesException(definition.getUserFriendlyName(), exceptions, |
| | | !existsOnServer); |
| | | } |
| | | |
| | | // Now enforce any constraints. |
| | | List<LocalizableMessage> messages = new LinkedList<LocalizableMessage>(); |
| | | boolean isAcceptable = true; |
| | | ManagementContext context = getDriver().getManagementContext(); |
| | | |
| | | for (Constraint constraint : definition.getAllConstraints()) { |
| | | for (ClientConstraintHandler handler : constraint.getClientConstraintHandlers()) { |
| | | if (existsOnServer) { |
| | | if (!handler.isModifyAcceptable(context, this, messages)) { |
| | | isAcceptable = false; |
| | | } |
| | | } else { |
| | | if (!handler.isAddAcceptable(context, this, messages)) { |
| | | isAcceptable = false; |
| | | } |
| | | } |
| | | } |
| | | if (!isAcceptable) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!isAcceptable) { |
| | | if (existsOnServer) { |
| | | throw new OperationRejectedException(OperationType.MODIFY, definition.getUserFriendlyName(), messages); |
| | | } else { |
| | | throw new OperationRejectedException(OperationType.CREATE, definition.getUserFriendlyName(), messages); |
| | | } |
| | | } |
| | | |
| | | // Commit the managed object. |
| | | if (existsOnServer) { |
| | | modifyExistingManagedObject(); |
| | | } else { |
| | | addNewManagedObject(); |
| | | } |
| | | |
| | | // Make all pending property values active. |
| | | properties.commit(); |
| | | |
| | | // If the managed object was created make sure that any default |
| | | // subordinate managed objects are also created. |
| | | if (!existsOnServer) { |
| | | DefaultManagedObjectFactory factory = new DefaultManagedObjectFactory(); |
| | | for (RelationDefinition<?, ?> rd : definition.getAllRelationDefinitions()) { |
| | | factory.createDefaultManagedObjects(rd); |
| | | } |
| | | |
| | | existsOnServer = true; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration, C1 extends C> ManagedObject<C1> createChild( |
| | | InstantiableRelationDefinition<C, S> r, ManagedObjectDefinition<C1, ? extends S> d, String name, |
| | | Collection<DefaultBehaviorException> exceptions) throws IllegalManagedObjectNameException { |
| | | validateRelationDefinition(r); |
| | | |
| | | // Empty names are not allowed. |
| | | if (name.trim().length() == 0) { |
| | | throw new IllegalManagedObjectNameException(name); |
| | | } |
| | | |
| | | // If the relation uses a naming property definition then it must |
| | | // be a valid value. |
| | | PropertyDefinition<?> pd = r.getNamingPropertyDefinition(); |
| | | if (pd != null) { |
| | | try { |
| | | pd.decodeValue(name, propertyDefOptions); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | throw new IllegalManagedObjectNameException(name, pd, propertyDefOptions); |
| | | } |
| | | } |
| | | |
| | | ManagedObjectPath<C1, ? extends S> childPath = path.child(r, d, name); |
| | | return createNewManagedObject(d, childPath, pd, name, exceptions); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration, C1 extends C> ManagedObject<C1> createChild( |
| | | OptionalRelationDefinition<C, S> r, ManagedObjectDefinition<C1, ? extends S> d, |
| | | Collection<DefaultBehaviorException> exceptions) { |
| | | validateRelationDefinition(r); |
| | | ManagedObjectPath<C1, ? extends S> childPath = path.child(r, d); |
| | | return createNewManagedObject(d, childPath, null, null, exceptions); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration, C1 extends C> ManagedObject<C1> createChild( |
| | | SetRelationDefinition<C, S> r, ManagedObjectDefinition<C1, ? extends S> d, |
| | | Collection<DefaultBehaviorException> exceptions) { |
| | | validateRelationDefinition(r); |
| | | |
| | | ManagedObjectPath<C1, ? extends S> childPath = path.child(r, d); |
| | | return createNewManagedObject(d, childPath, null, null, exceptions); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | InstantiableRelationDefinition<C, S> r, String name) throws DefinitionDecodingException, |
| | | ManagedObjectDecodingException, ManagedObjectNotFoundException, ConcurrentModificationException, |
| | | ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | ensureThisManagedObjectExists(); |
| | | Driver ctx = getDriver(); |
| | | return ctx.getManagedObject(path.child(r, name)); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | OptionalRelationDefinition<C, S> r) throws DefinitionDecodingException, ManagedObjectDecodingException, |
| | | ManagedObjectNotFoundException, ConcurrentModificationException, ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | ensureThisManagedObjectExists(); |
| | | Driver ctx = getDriver(); |
| | | return ctx.getManagedObject(path.child(r)); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | SingletonRelationDefinition<C, S> r) throws DefinitionDecodingException, ManagedObjectDecodingException, |
| | | ManagedObjectNotFoundException, ConcurrentModificationException, ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | ensureThisManagedObjectExists(); |
| | | Driver ctx = getDriver(); |
| | | return ctx.getManagedObject(path.child(r)); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getChild( |
| | | SetRelationDefinition<C, S> r, String name) throws DefinitionDecodingException, |
| | | ManagedObjectDecodingException, ManagedObjectNotFoundException, ConcurrentModificationException, |
| | | ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | ensureThisManagedObjectExists(); |
| | | Driver ctx = getDriver(); |
| | | |
| | | AbstractManagedObjectDefinition<C, S> d = r.getChildDefinition(); |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> cd; |
| | | |
| | | try { |
| | | cd = d.getChild(name); |
| | | } catch (IllegalArgumentException e) { |
| | | // Unrecognized definition name - report this as a decoding |
| | | // exception. |
| | | throw new DefinitionDecodingException(d, Reason.WRONG_TYPE_INFORMATION); |
| | | } |
| | | |
| | | return ctx.getManagedObject(path.child(r, cd)); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final T getConfiguration() { |
| | | return definition.createClientConfiguration(this); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final ManagedObjectDefinition<T, ? extends Configuration> getManagedObjectDefinition() { |
| | | return definition; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final ManagedObjectPath<T, ? extends Configuration> getManagedObjectPath() { |
| | | return path; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <P> SortedSet<P> getPropertyDefaultValues(PropertyDefinition<P> pd) { |
| | | return new TreeSet<P>(getProperty(pd).getDefaultValues()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <P> P getPropertyValue(PropertyDefinition<P> pd) { |
| | | Set<P> values = getProperty(pd).getEffectiveValues(); |
| | | if (values.isEmpty()) { |
| | | return null; |
| | | } else { |
| | | return values.iterator().next(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <P> SortedSet<P> getPropertyValues(PropertyDefinition<P> pd) { |
| | | return new TreeSet<P>(getProperty(pd).getEffectiveValues()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> boolean hasChild( |
| | | OptionalRelationDefinition<C, S> r) throws ConcurrentModificationException, ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | Driver ctx = getDriver(); |
| | | try { |
| | | return ctx.managedObjectExists(path.child(r)); |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final boolean isPropertyPresent(PropertyDefinition<?> pd) { |
| | | return !getProperty(pd).isEmpty(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> String[] listChildren( |
| | | InstantiableRelationDefinition<C, S> r) throws ConcurrentModificationException, ErrorResultException { |
| | | return listChildren(r, r.getChildDefinition()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> String[] listChildren( |
| | | InstantiableRelationDefinition<C, S> r, AbstractManagedObjectDefinition<? extends C, ? extends S> d) |
| | | throws ConcurrentModificationException, ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | Driver ctx = getDriver(); |
| | | try { |
| | | return ctx.listManagedObjects(path, r, d); |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> String[] listChildren( |
| | | SetRelationDefinition<C, S> r) throws ConcurrentModificationException, ErrorResultException { |
| | | return listChildren(r, r.getChildDefinition()); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> String[] listChildren( |
| | | SetRelationDefinition<C, S> r, AbstractManagedObjectDefinition<? extends C, ? extends S> d) |
| | | throws ConcurrentModificationException, ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | Driver ctx = getDriver(); |
| | | try { |
| | | return ctx.listManagedObjects(path, r, d); |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> void removeChild( |
| | | InstantiableRelationDefinition<C, S> r, String name) throws ManagedObjectNotFoundException, |
| | | OperationRejectedException, ConcurrentModificationException, ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | Driver ctx = getDriver(); |
| | | boolean found; |
| | | |
| | | try { |
| | | found = ctx.deleteManagedObject(path, r, name); |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | |
| | | if (!found) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> void removeChild( |
| | | OptionalRelationDefinition<C, S> r) throws ManagedObjectNotFoundException, OperationRejectedException, |
| | | ConcurrentModificationException, ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | Driver ctx = getDriver(); |
| | | boolean found; |
| | | |
| | | try { |
| | | found = ctx.deleteManagedObject(path, r); |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | |
| | | if (!found) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <C extends ConfigurationClient, S extends Configuration> void removeChild( |
| | | SetRelationDefinition<C, S> r, String name) throws ManagedObjectNotFoundException, |
| | | OperationRejectedException, ConcurrentModificationException, ErrorResultException { |
| | | validateRelationDefinition(r); |
| | | Driver ctx = getDriver(); |
| | | boolean found; |
| | | |
| | | try { |
| | | found = ctx.deleteManagedObject(path, r, name); |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | |
| | | if (!found) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <P> void setPropertyValue(PropertyDefinition<P> pd, P value) { |
| | | if (value == null) { |
| | | setPropertyValues(pd, Collections.<P> emptySet()); |
| | | } else { |
| | | setPropertyValues(pd, Collections.singleton(value)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public final <P> void setPropertyValues(PropertyDefinition<P> pd, Collection<P> values) { |
| | | if (pd.hasOption(PropertyOption.MONITORING)) { |
| | | throw new PropertyIsReadOnlyException(pd); |
| | | } |
| | | |
| | | if (existsOnServer && pd.hasOption(PropertyOption.READ_ONLY)) { |
| | | throw new PropertyIsReadOnlyException(pd); |
| | | } |
| | | |
| | | properties.setPropertyValues(pd, values, propertyDefOptions); |
| | | |
| | | // If this is a naming property then update the name. |
| | | if (pd.equals(namingPropertyDefinition)) { |
| | | // The property must be single-valued and mandatory. |
| | | String newName = pd.encodeValue(values.iterator().next()); |
| | | path = path.rename(newName); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | StringBuilder builder = new StringBuilder(); |
| | | |
| | | builder.append("{ TYPE="); |
| | | builder.append(definition.getName()); |
| | | builder.append(", PATH=\""); |
| | | builder.append(path); |
| | | builder.append('\"'); |
| | | for (PropertyDefinition<?> pd : definition.getAllPropertyDefinitions()) { |
| | | builder.append(", "); |
| | | builder.append(pd.getName()); |
| | | builder.append('='); |
| | | builder.append(getPropertyValues(pd)); |
| | | } |
| | | builder.append(" }"); |
| | | |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Adds this new managed object. |
| | | * |
| | | * @throws ManagedObjectAlreadyExistsException |
| | | * If the managed object cannot be added to the server because |
| | | * it already exists. |
| | | * @throws ConcurrentModificationException |
| | | * If the managed object's parent has been removed by another |
| | | * client. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be added due to some client-side |
| | | * or server-side constraint which cannot be satisfied. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | protected abstract void addNewManagedObject() throws ErrorResultException, OperationRejectedException, |
| | | ConcurrentModificationException, ManagedObjectAlreadyExistsException; |
| | | |
| | | /** |
| | | * Gets the management context driver associated with this managed object. |
| | | * |
| | | * @return Returns the management context driver associated with this |
| | | * managed object. |
| | | */ |
| | | protected abstract Driver getDriver(); |
| | | |
| | | /** |
| | | * Gets the naming property definition associated with this managed object. |
| | | * |
| | | * @return Returns the naming property definition associated with this |
| | | * managed object, or <code>null</code> if this managed object does |
| | | * not have a naming property. |
| | | */ |
| | | protected final PropertyDefinition<?> getNamingPropertyDefinition() { |
| | | return namingPropertyDefinition; |
| | | } |
| | | |
| | | /** |
| | | * Gets the property associated with the specified property definition. |
| | | * |
| | | * @param <P> |
| | | * The underlying type of the property. |
| | | * @param pd |
| | | * The Property definition. |
| | | * @return Returns the property associated with the specified property |
| | | * definition. |
| | | * @throws IllegalArgumentException |
| | | * If this property provider does not recognize the requested |
| | | * property definition. |
| | | */ |
| | | protected final <P> Property<P> getProperty(PropertyDefinition<P> pd) { |
| | | return properties.getProperty(pd); |
| | | } |
| | | |
| | | /** |
| | | * Applies changes made to this managed object. |
| | | * |
| | | * @throws ConcurrentModificationException |
| | | * If this managed object has been removed from the server by |
| | | * another client. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be added due to some client-side |
| | | * or server-side constraint which cannot be satisfied. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | protected abstract void modifyExistingManagedObject() throws ConcurrentModificationException, |
| | | OperationRejectedException, ErrorResultException; |
| | | |
| | | /** |
| | | * Creates a new managed object. |
| | | * |
| | | * @param <M> |
| | | * The type of client configuration represented by the client |
| | | * managed object. |
| | | * @param d |
| | | * The managed object's definition. |
| | | * @param path |
| | | * The managed object's path. |
| | | * @param properties |
| | | * The managed object's properties. |
| | | * @param existsOnServer |
| | | * Indicates whether or not the managed object exists on the |
| | | * server (false means the managed object is new and has not been |
| | | * committed). |
| | | * @param namingPropertyDefinition |
| | | * Optional naming property definition. |
| | | * @return Returns the new managed object. |
| | | */ |
| | | protected abstract <M extends ConfigurationClient> ManagedObject<M> newInstance(ManagedObjectDefinition<M, ?> d, |
| | | ManagedObjectPath<M, ?> path, PropertySet properties, boolean existsOnServer, |
| | | PropertyDefinition<?> namingPropertyDefinition); |
| | | |
| | | // Creates a new managed object with no active values, just default |
| | | // values. |
| | | private <M extends ConfigurationClient, P> ManagedObject<M> createNewManagedObject( |
| | | ManagedObjectDefinition<M, ?> d, ManagedObjectPath<M, ?> p, PropertyDefinition<P> namingPropertyDefinition, |
| | | String name, Collection<DefaultBehaviorException> exceptions) { |
| | | PropertySet childProperties = new PropertySet(); |
| | | for (PropertyDefinition<?> pd : d.getAllPropertyDefinitions()) { |
| | | try { |
| | | createProperty(childProperties, p, pd); |
| | | } catch (DefaultBehaviorException e) { |
| | | // Add the exception if requested. |
| | | if (exceptions != null) { |
| | | exceptions.add(e); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Set the naming property if there is one. |
| | | if (namingPropertyDefinition != null) { |
| | | P value = namingPropertyDefinition.decodeValue(name, propertyDefOptions); |
| | | childProperties.setPropertyValues(namingPropertyDefinition, Collections.singleton(value), |
| | | propertyDefOptions); |
| | | } |
| | | |
| | | return newInstance(d, p, childProperties, false, namingPropertyDefinition); |
| | | } |
| | | |
| | | // Create an empty property. |
| | | private <P> void createProperty(PropertySet properties, ManagedObjectPath<?, ?> p, PropertyDefinition<P> pd) { |
| | | try { |
| | | Driver context = getDriver(); |
| | | Collection<P> defaultValues = context.findDefaultValues(p, pd, true); |
| | | properties.addProperty(pd, defaultValues, Collections.<P> emptySet()); |
| | | } catch (DefaultBehaviorException e) { |
| | | // Make sure that we have still created the property. |
| | | properties.addProperty(pd, Collections.<P> emptySet(), Collections.<P> emptySet()); |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | // Makes sure that this managed object exists. |
| | | private void ensureThisManagedObjectExists() throws ConcurrentModificationException, ErrorResultException { |
| | | if (!path.isEmpty()) { |
| | | Driver ctx = getDriver(); |
| | | |
| | | try { |
| | | if (!ctx.managedObjectExists(path)) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new ConcurrentModificationException(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Validate that a relation definition belongs to this managed |
| | | // object. |
| | | private void validateRelationDefinition(RelationDefinition<?, ?> rd) { |
| | | 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()); |
| | | } |
| | | } |
| | | |
| | | } |
| 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 legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.forgerock.opendj.config.client.spi; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.SortedSet; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.server.config.client.RootCfgClient; |
| | | import org.forgerock.opendj.config.AbsoluteInheritedDefaultBehaviorProvider; |
| | | import org.forgerock.opendj.config.AbstractManagedObjectDefinition; |
| | | import org.forgerock.opendj.config.AliasDefaultBehaviorProvider; |
| | | import org.forgerock.opendj.config.Configuration; |
| | | import org.forgerock.opendj.config.ConfigurationClient; |
| | | import org.forgerock.opendj.config.Constraint; |
| | | import org.forgerock.opendj.config.DefaultBehaviorException; |
| | | import org.forgerock.opendj.config.DefaultBehaviorProviderVisitor; |
| | | import org.forgerock.opendj.config.DefinedDefaultBehaviorProvider; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException; |
| | | import org.forgerock.opendj.config.IllegalPropertyValueStringException; |
| | | import org.forgerock.opendj.config.InstantiableRelationDefinition; |
| | | import org.forgerock.opendj.config.ManagedObjectNotFoundException; |
| | | import org.forgerock.opendj.config.ManagedObjectPath; |
| | | import org.forgerock.opendj.config.OptionalRelationDefinition; |
| | | import org.forgerock.opendj.config.PropertyDefinition; |
| | | import org.forgerock.opendj.config.PropertyDefinitionsOptions; |
| | | import org.forgerock.opendj.config.PropertyException; |
| | | import org.forgerock.opendj.config.PropertyIsSingleValuedException; |
| | | import org.forgerock.opendj.config.PropertyNotFoundException; |
| | | import org.forgerock.opendj.config.PropertyOption; |
| | | import org.forgerock.opendj.config.RelationDefinition; |
| | | import org.forgerock.opendj.config.RelativeInheritedDefaultBehaviorProvider; |
| | | import org.forgerock.opendj.config.SetRelationDefinition; |
| | | import org.forgerock.opendj.config.UndefinedDefaultBehaviorProvider; |
| | | import org.forgerock.opendj.config.DefinitionDecodingException.Reason; |
| | | import org.forgerock.opendj.config.client.ClientConstraintHandler; |
| | | import org.forgerock.opendj.config.client.ManagedObject; |
| | | import org.forgerock.opendj.config.client.ManagedObjectDecodingException; |
| | | import org.forgerock.opendj.config.client.ManagementContext; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException; |
| | | import org.forgerock.opendj.config.client.OperationRejectedException.OperationType; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | |
| | | /** |
| | | * An abstract management connection context driver which should form the basis |
| | | * of driver implementations. |
| | | */ |
| | | public abstract class Driver { |
| | | |
| | | /** |
| | | * A default behavior visitor used for retrieving the default values of a |
| | | * property. |
| | | * |
| | | * @param <T> |
| | | * The type of the property. |
| | | */ |
| | | private final class DefaultValueFinder<T> implements DefaultBehaviorProviderVisitor<T, Collection<T>, Void> { |
| | | |
| | | // Any exception that occurred whilst retrieving inherited default |
| | | // values. |
| | | private DefaultBehaviorException exception = null; |
| | | |
| | | // The path of the managed object containing the first property. |
| | | private final ManagedObjectPath<?, ?> firstPath; |
| | | |
| | | // Indicates whether the managed object has been created yet. |
| | | private final boolean isCreate; |
| | | |
| | | // The path of the managed object containing the next property. |
| | | private ManagedObjectPath<?, ?> nextPath = null; |
| | | |
| | | // The next property whose default values were required. |
| | | private PropertyDefinition<T> nextProperty = null; |
| | | |
| | | // Private constructor. |
| | | private DefaultValueFinder(ManagedObjectPath<?, ?> p, boolean isCreate) { |
| | | this.firstPath = p; |
| | | this.isCreate = isCreate; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Collection<T> visitAbsoluteInherited(AbsoluteInheritedDefaultBehaviorProvider<T> d, Void p) { |
| | | try { |
| | | return getInheritedProperty(d.getManagedObjectPath(), d.getManagedObjectDefinition(), |
| | | d.getPropertyName()); |
| | | } catch (DefaultBehaviorException e) { |
| | | exception = e; |
| | | return Collections.emptySet(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) { |
| | | return Collections.emptySet(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> d, Void p) { |
| | | Collection<String> stringValues = d.getDefaultValues(); |
| | | List<T> values = new ArrayList<T>(stringValues.size()); |
| | | |
| | | for (String stringValue : stringValues) { |
| | | try { |
| | | values.add(nextProperty.decodeValue(stringValue, propertyDefOptions)); |
| | | } catch (IllegalPropertyValueStringException e) { |
| | | exception = new DefaultBehaviorException(nextProperty, e); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | return values; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Collection<T> visitRelativeInherited(RelativeInheritedDefaultBehaviorProvider<T> d, Void p) { |
| | | try { |
| | | return getInheritedProperty(d.getManagedObjectPath(nextPath), d.getManagedObjectDefinition(), |
| | | d.getPropertyName()); |
| | | } catch (DefaultBehaviorException e) { |
| | | exception = e; |
| | | return Collections.emptySet(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d, Void p) { |
| | | return Collections.emptySet(); |
| | | } |
| | | |
| | | // Find the default values for the next path/property. |
| | | private Collection<T> find(ManagedObjectPath<?, ?> p, PropertyDefinition<T> pd) { |
| | | this.nextPath = p; |
| | | this.nextProperty = pd; |
| | | |
| | | Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept(this, null); |
| | | |
| | | if (exception != null) { |
| | | throw exception; |
| | | } |
| | | |
| | | if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) { |
| | | throw new DefaultBehaviorException(pd, new PropertyIsSingleValuedException(pd)); |
| | | } |
| | | |
| | | return values; |
| | | } |
| | | |
| | | // Get an inherited property value. |
| | | @SuppressWarnings("unchecked") |
| | | private Collection<T> getInheritedProperty(ManagedObjectPath<?, ?> target, |
| | | AbstractManagedObjectDefinition<?, ?> d, String propertyName) { |
| | | // First check that the requested type of managed object |
| | | // corresponds to the path. |
| | | AbstractManagedObjectDefinition<?, ?> supr = target.getManagedObjectDefinition(); |
| | | if (!supr.isParentOf(d)) { |
| | | throw new DefaultBehaviorException(nextProperty, new DefinitionDecodingException(supr, |
| | | Reason.WRONG_TYPE_INFORMATION)); |
| | | } |
| | | |
| | | // Save the current property in case of recursion. |
| | | PropertyDefinition<T> pd1 = nextProperty; |
| | | |
| | | try { |
| | | // Determine the requested property definition. |
| | | PropertyDefinition<T> pd2; |
| | | try { |
| | | // FIXME: we use the definition taken from the default |
| | | // behavior here when we should really use the exact |
| | | // definition of the component being created. |
| | | PropertyDefinition<?> pdTmp = d.getPropertyDefinition(propertyName); |
| | | pd2 = pd1.getClass().cast(pdTmp); |
| | | } catch (IllegalArgumentException e) { |
| | | throw new PropertyNotFoundException(propertyName); |
| | | } catch (ClassCastException e) { |
| | | // FIXME: would be nice to throw a better exception here. |
| | | throw new PropertyNotFoundException(propertyName); |
| | | } |
| | | |
| | | // If the path relates to the current managed object and the |
| | | // managed object is in the process of being created it won't |
| | | // exist, so we should just use the default values of the |
| | | // referenced property. |
| | | if (isCreate && firstPath.equals(target)) { |
| | | // Recursively retrieve this property's default values. |
| | | Collection<T> tmp = find(target, pd2); |
| | | Collection<T> values = new ArrayList<T>(tmp.size()); |
| | | for (T value : tmp) { |
| | | pd1.validateValue(value, propertyDefOptions); |
| | | values.add(value); |
| | | } |
| | | return values; |
| | | } else { |
| | | // FIXME: issue 2481 - this is broken if the referenced |
| | | // property |
| | | // inherits its defaults from the newly created managed |
| | | // object. |
| | | return getPropertyValues(target, pd2); |
| | | } |
| | | } catch (DefaultBehaviorException e) { |
| | | // Wrap any errors due to recursion. |
| | | throw new DefaultBehaviorException(pd1, e); |
| | | } catch (DefinitionDecodingException e) { |
| | | throw new DefaultBehaviorException(pd1, e); |
| | | } catch (PropertyNotFoundException e) { |
| | | throw new DefaultBehaviorException(pd1, e); |
| | | } catch (ErrorResultException e) { |
| | | throw new DefaultBehaviorException(pd1, e); |
| | | } catch (ManagedObjectNotFoundException e) { |
| | | throw new DefaultBehaviorException(pd1, e); |
| | | } catch (PropertyException e) { |
| | | throw new DefaultBehaviorException(pd1, e); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | private final PropertyDefinitionsOptions propertyDefOptions; |
| | | |
| | | /** |
| | | * Creates a new abstract driver. |
| | | * |
| | | * @param propertyDefOptions |
| | | * Decoding options for property definitions values. |
| | | */ |
| | | protected Driver(PropertyDefinitionsOptions propertyDefOptions) { |
| | | this.propertyDefOptions = propertyDefOptions; |
| | | } |
| | | |
| | | /** |
| | | * Closes any context associated with this management context driver. |
| | | */ |
| | | public void close() { |
| | | // do nothing by default |
| | | } |
| | | |
| | | /** |
| | | * Deletes the named instantiable child managed object from the named parent |
| | | * managed object. |
| | | * |
| | | * @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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The instantiable relation definition. |
| | | * @param name |
| | | * The name of the child managed object to be removed. |
| | | * @return Returns <code>true</code> if the named instantiable child managed |
| | | * object was found, or <code>false</code> if it was not found. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, String name) |
| | | throws ManagedObjectNotFoundException, OperationRejectedException, ErrorResultException { |
| | | validateRelationDefinition(parent, rd); |
| | | ManagedObjectPath<?, ?> child = parent.child(rd, name); |
| | | return doDeleteManagedObject(child); |
| | | } |
| | | |
| | | /** |
| | | * Deletes the optional child managed object from the named parent managed |
| | | * object. |
| | | * |
| | | * @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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The optional relation definition. |
| | | * @return Returns <code>true</code> if the optional child managed object |
| | | * was found, or <code>false</code> if it was not found. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd) throws ManagedObjectNotFoundException, |
| | | OperationRejectedException, ErrorResultException { |
| | | validateRelationDefinition(parent, rd); |
| | | ManagedObjectPath<?, ?> child = parent.child(rd); |
| | | return doDeleteManagedObject(child); |
| | | } |
| | | |
| | | /** |
| | | * Deletes the named instantiable child managed object from the named parent |
| | | * managed object. |
| | | * |
| | | * @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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The instantiable relation definition. |
| | | * @param name |
| | | * The name of the child managed object to be removed. |
| | | * @return Returns <code>true</code> if the named instantiable child managed |
| | | * object was found, or <code>false</code> if it was not found. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition is not associated with the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * client-side or server-side constraint which cannot be |
| | | * satisfied (for example, if it is referenced by another |
| | | * managed object). |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public final <C extends ConfigurationClient, S extends Configuration> boolean deleteManagedObject( |
| | | ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd, String name) |
| | | throws ManagedObjectNotFoundException, OperationRejectedException, ErrorResultException { |
| | | validateRelationDefinition(parent, rd); |
| | | ManagedObjectPath<?, ?> child = parent.child(rd, name); |
| | | return doDeleteManagedObject(child); |
| | | } |
| | | |
| | | /** |
| | | * Gets the named managed object. The path is guaranteed to be non-empty, so |
| | | * implementations do not need to worry about handling this special case. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that the path |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that the path |
| | | * definition refers to. |
| | | * @param path |
| | | * The non-empty path of the managed object. |
| | | * @return Returns the named managed object. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws ManagedObjectDecodingException |
| | | * If the managed object was found but one or more of its |
| | | * properties could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | // @Checkstyle:ignore |
| | | public abstract <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getManagedObject( |
| | | ManagedObjectPath<C, S> path) throws DefinitionDecodingException, ManagedObjectDecodingException, |
| | | ManagedObjectNotFoundException, ErrorResultException; |
| | | |
| | | /** |
| | | * Gets the effective values of a property in the named managed object. |
| | | * <p> |
| | | * Implementations MUST NOT not use |
| | | * {@link #getManagedObject(ManagedObjectPath)} to read the referenced |
| | | * managed object in its entirety. Specifically, implementations MUST only |
| | | * attempt to resolve the default values for the requested property and its |
| | | * dependencies (if it uses inherited defaults). This is to avoid infinite |
| | | * recursion where a managed object contains a property which inherits |
| | | * default values from another property in the same managed object. |
| | | * |
| | | * @param <C> |
| | | * The type of client managed object configuration that the path |
| | | * definition refers to. |
| | | * @param <S> |
| | | * The type of server managed object configuration that the path |
| | | * definition refers to. |
| | | * @param <P> |
| | | * The type of the property to be retrieved. |
| | | * @param path |
| | | * The path of the managed object containing the property. |
| | | * @param pd |
| | | * The property to be retrieved. |
| | | * @return Returns the property's effective values, or an empty set if there |
| | | * are no values defined. |
| | | * @throws IllegalArgumentException |
| | | * If the property definition is not associated with the |
| | | * referenced managed object's definition. |
| | | * @throws DefinitionDecodingException |
| | | * If the managed object was found but its type could not be |
| | | * determined. |
| | | * @throws PropertyException |
| | | * If the managed object was found but the requested property |
| | | * could not be decoded. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the requested managed object could not be found on the |
| | | * server. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public abstract <C extends ConfigurationClient, S extends Configuration, P> SortedSet<P> getPropertyValues( |
| | | ManagedObjectPath<C, S> path, PropertyDefinition<P> pd) throws DefinitionDecodingException, |
| | | ManagedObjectNotFoundException, ErrorResultException; |
| | | |
| | | /** |
| | | * Gets the root configuration managed object associated with this |
| | | * management context driver. |
| | | * |
| | | * @return Returns the root configuration managed object associated with |
| | | * this management context driver. |
| | | */ |
| | | public abstract ManagedObject<RootCfgClient> getRootConfigurationManagedObject(); |
| | | |
| | | /** |
| | | * Lists the child managed objects of the named parent managed object 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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * 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 the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public abstract <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects( |
| | | ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws ManagedObjectNotFoundException, |
| | | ErrorResultException; |
| | | |
| | | /** |
| | | * Lists the child managed objects of the named parent managed object 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 parent |
| | | * The path of the parent managed object. |
| | | * @param rd |
| | | * The set 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 the parent |
| | | * managed object's definition. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public abstract <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects( |
| | | ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd, |
| | | AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws ManagedObjectNotFoundException, |
| | | ErrorResultException; |
| | | |
| | | /** |
| | | * Determines whether or not the named managed object exists. |
| | | * <p> |
| | | * Implementations should always return <code>true</code> when the provided |
| | | * path is empty. |
| | | * |
| | | * @param path |
| | | * The path of the named managed object. |
| | | * @return Returns <code>true</code> if the named managed object exists, |
| | | * <code>false</code> otherwise. |
| | | * @throws ManagedObjectNotFoundException |
| | | * If the parent managed object could not be found. |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | public abstract boolean managedObjectExists(ManagedObjectPath<?, ?> path) throws ManagedObjectNotFoundException, |
| | | ErrorResultException; |
| | | |
| | | /** |
| | | * Deletes the named managed object. |
| | | * <p> |
| | | * Implementations do not need check whether the named managed object |
| | | * exists, nor do they need to enforce client constraints. |
| | | * |
| | | * @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 path |
| | | * The path of the managed object to be deleted. |
| | | * @throws OperationRejectedException |
| | | * If the managed object cannot be removed due to some |
| | | * server-side constraint which cannot be satisfied (for |
| | | * example, if it is referenced by another managed object). |
| | | * @throws ErrorResultException |
| | | * If any other error occurs. |
| | | */ |
| | | protected abstract <C extends ConfigurationClient, S extends Configuration> void deleteManagedObject( |
| | | ManagedObjectPath<C, S> path) throws OperationRejectedException, ErrorResultException; |
| | | |
| | | /** |
| | | * Gets the default values for the specified property. |
| | | * |
| | | * @param <P> |
| | | * The type of the property. |
| | | * @param p |
| | | * The managed object path of the current managed object. |
| | | * @param pd |
| | | * The property definition. |
| | | * @param isCreate |
| | | * Indicates whether the managed object has been created yet. |
| | | * @return Returns the default values for the specified property. |
| | | * @throws DefaultBehaviorException |
| | | * If the default values could not be retrieved or decoded |
| | | * properly. |
| | | */ |
| | | protected final <P> Collection<P> findDefaultValues(ManagedObjectPath<?, ?> p, PropertyDefinition<P> pd, |
| | | boolean isCreate) { |
| | | DefaultValueFinder<P> v = new DefaultValueFinder<P>(p, isCreate); |
| | | return v.find(p, pd); |
| | | } |
| | | |
| | | /** |
| | | * Gets the management context associated with this driver. |
| | | * |
| | | * @return Returns the management context associated with this driver. |
| | | */ |
| | | protected abstract ManagementContext getManagementContext(); |
| | | |
| | | /** |
| | | * Validate that a relation definition belongs to the managed object |
| | | * referenced by the provided path. |
| | | * |
| | | * @param path |
| | | * The parent managed object path. |
| | | * @param rd |
| | | * The relation definition. |
| | | * @throws IllegalArgumentException |
| | | * If the relation definition does not belong to the managed |
| | | * object definition. |
| | | */ |
| | | protected final void validateRelationDefinition(ManagedObjectPath<?, ?> path, RelationDefinition<?, ?> rd) { |
| | | AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition(); |
| | | RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName()); |
| | | if (tmp != rd) { |
| | | throw new IllegalArgumentException("The relation " + rd.getName() + " is not associated with a " |
| | | + d.getName()); |
| | | } |
| | | } |
| | | |
| | | // Remove a managed object, first ensuring that the parent exists, |
| | | // then ensuring that the child exists, before ensuring that any |
| | | // constraints are satisfied. |
| | | private <C extends ConfigurationClient, S extends Configuration> boolean doDeleteManagedObject( |
| | | ManagedObjectPath<C, S> path) throws ManagedObjectNotFoundException, OperationRejectedException, |
| | | ErrorResultException { |
| | | // First make sure that the parent exists. |
| | | if (!managedObjectExists(path.parent())) { |
| | | throw new ManagedObjectNotFoundException(); |
| | | } |
| | | |
| | | // Make sure that the targeted managed object exists. |
| | | if (!managedObjectExists(path)) { |
| | | return false; |
| | | } |
| | | |
| | | // The targeted managed object is guaranteed to exist, so enforce |
| | | // any constraints. |
| | | AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition(); |
| | | List<LocalizableMessage> messages = new LinkedList<LocalizableMessage>(); |
| | | boolean isAcceptable = true; |
| | | |
| | | for (Constraint constraint : d.getAllConstraints()) { |
| | | for (ClientConstraintHandler handler : constraint.getClientConstraintHandlers()) { |
| | | ManagementContext context = getManagementContext(); |
| | | if (!handler.isDeleteAcceptable(context, path, messages)) { |
| | | isAcceptable = false; |
| | | } |
| | | } |
| | | if (!isAcceptable) { |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!isAcceptable) { |
| | | throw new OperationRejectedException(OperationType.DELETE, d.getUserFriendlyName(), messages); |
| | | } |
| | | |
| | | deleteManagedObject(path); |
| | | return true; |
| | | } |
| | | |
| | | } |
| opendj-config/src/main/java/org/forgerock/opendj/config/client/spi/Property.java
opendj-config/src/main/java/org/forgerock/opendj/config/client/spi/PropertySet.java
opendj-config/src/main/java/org/forgerock/opendj/config/client/spi/package-info.java
opendj-config/src/main/java/org/forgerock/opendj/config/conditions/ANDCondition.java
opendj-config/src/main/java/org/forgerock/opendj/config/conditions/Condition.java
opendj-config/src/main/java/org/forgerock/opendj/config/conditions/Conditions.java
opendj-config/src/main/java/org/forgerock/opendj/config/conditions/ContainsCondition.java
opendj-config/src/main/java/org/forgerock/opendj/config/conditions/IsPresentCondition.java
opendj-config/src/main/java/org/forgerock/opendj/config/conditions/NOTCondition.java
opendj-config/src/main/java/org/forgerock/opendj/config/conditions/ORCondition.java
opendj-config/src/main/java/org/forgerock/opendj/config/conditions/package-info.java
opendj-config/src/main/java/org/forgerock/opendj/config/package-info.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/AbstractConfigListenerAdaptor.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigAddListenerAdaptor.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigChangeListenerAdaptor.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigChangeResult.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigDeleteListenerAdaptor.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigException.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigExceptionFactory.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigurationAddListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigurationChangeListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConfigurationDeleteListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ConstraintViolationException.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/DNBuilder.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/DelayedConfigAddListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerConstraintHandler.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagedObject.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagedObjectAddListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagedObjectAddListenerAdaptor.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagedObjectChangeListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagedObjectChangeListenerAdaptor.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagedObjectDecodingException.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagedObjectDeleteListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagedObjectDeleteListenerAdaptor.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/ServerManagementContext.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/package-info.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/spi/ConfigAddListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/spi/ConfigChangeListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/spi/ConfigDeleteListener.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/spi/ConfigurationRepository.java
opendj-config/src/main/java/org/forgerock/opendj/config/server/spi/package-info.java
opendj-config/src/main/java/org/opends/server/admin/ACIPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/AbsoluteInheritedDefaultBehaviorProvider.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/AbstractManagedObjectDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/AdminException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/AdminRuntimeException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/AdministratorAction.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/AggregationPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/AliasDefaultBehaviorProvider.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/AttributeTypePropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/BooleanPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ClassLoaderProvider.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ClassPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/Configuration.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ConfigurationClient.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/Constraint.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DNPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DecodingException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DefaultBehaviorException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DefaultBehaviorProvider.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DefaultBehaviorProviderVisitor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DefaultManagedObject.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DefinedDefaultBehaviorProvider.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DefinitionDecodingException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DefinitionResolver.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DurationPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/DurationUnit.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/EnumPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/GenericConstraint.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/IPAddressMaskPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/IPAddressPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/IllegalPropertyValueException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/IllegalPropertyValueStringException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/InstantiableRelationDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/IntegerPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/LDAPProfile.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ManagedObjectAlreadyExistsException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ManagedObjectDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ManagedObjectDefinitionResource.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ManagedObjectNotFoundException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ManagedObjectOption.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ManagedObjectPath.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/ManagedObjectPathSerializer.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/OperationsException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/OptionalRelationDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyDefinitionUsageBuilder.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyDefinitionVisitor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyDefinitionsOptions.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyIsMandatoryException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyIsReadOnlyException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyIsSingleValuedException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyNotFoundException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyOption.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyProvider.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/PropertyValueVisitor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/Reference.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/RelationDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/RelationDefinitionVisitor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/RelationOption.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/RelativeInheritedDefaultBehaviorProvider.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/SetRelationDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/SingletonRelationDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/SizePropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/SizeUnit.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/StringPropertyDefinition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/Tag.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/TopCfgDefn.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/UndefinedDefaultBehaviorProvider.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/UnknownPropertyDefinitionException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/AdminClientException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/AdminSecurityException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/AuthenticationException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/AuthenticationNotSupportedException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ClientConstraintHandler.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ConcurrentModificationException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/IllegalManagedObjectNameException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ManagedObject.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ManagedObjectDecodingException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ManagementContext.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/MissingMandatoryPropertiesException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/OperationRejectedException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ldap/LDAPConnection.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ldap/LDAPDriver.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ldap/LDAPManagedObject.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ldap/LDAPManagementContext.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ldap/LDAPNameBuilder.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/ldap/package-info.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/package-info.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/spi/AbstractManagedObject.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/spi/Driver.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/spi/Property.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/spi/PropertySet.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/client/spi/package-info.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/condition/ANDCondition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/condition/Condition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/condition/Conditions.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/condition/ContainsCondition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/condition/IsPresentCondition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/condition/NOTCondition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/condition/ORCondition.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/condition/package-info.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/package-info.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/AbstractConfigListenerAdaptor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConfigAddListenerAdaptor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConfigChangeListenerAdaptor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConfigChangeResult.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConfigDeleteListenerAdaptor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConfigExceptionFactory.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConfigurationAddListener.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConfigurationChangeListener.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConfigurationDeleteListener.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ConstraintViolationException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/DNBuilder.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/DelayedConfigAddListener.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerConstraintHandler.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagedObject.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagedObjectAddListener.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagedObjectAddListenerAdaptor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagedObjectChangeListener.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagedObjectChangeListenerAdaptor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagedObjectDecodingException.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagedObjectDeleteListener.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagedObjectDeleteListenerAdaptor.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/ServerManagementContext.java (deleted)
opendj-config/src/main/java/org/opends/server/admin/server/package-info.java (deleted)
opendj-config/src/main/java/org/opends/server/config/spi/ConfigAddListener.java (deleted)
opendj-config/src/main/java/org/opends/server/config/spi/ConfigChangeListener.java (deleted)
opendj-config/src/main/java/org/opends/server/config/spi/ConfigDeleteListener.java (deleted)
opendj-config/src/main/java/org/opends/server/config/spi/ConfigException.java (deleted)
opendj-config/src/main/java/org/opends/server/config/spi/ConfigurationRepository.java (deleted)
opendj-config/src/main/java/org/opends/server/config/spi/package-info.java (deleted)
opendj-config/src/main/java/org/opends/server/types/AddressMask.java
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AESPasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AccessControlHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AccessLogFilteringCriteriaConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AccessLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AccountStatusNotificationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AdministrationConnectorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AlertHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AnonymousSASLMechanismHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AttributeCleanupPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AttributeSyntaxConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AttributeTypeDescriptionAttributeSyntaxConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AttributeValuePasswordValidatorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/AuthenticationPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/BackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/BackupBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/Base64PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/BlindTrustManagerProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/BlowfishPasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CancelExtendedOperationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CertificateAttributeSyntaxConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CertificateMapperConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ChangeNumberControlPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CharacterSetPasswordValidatorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ClearPasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ClientConnectionMonitorProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CollationMatchingRuleConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CollectiveAttributeSubentriesVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ConfigFileHandlerBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ConnectionHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CountryStringAttributeSyntaxConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CramMD5SASLMechanismHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CryptPasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/CryptoManagerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/DebugLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/DebugTargetConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/DictionaryPasswordValidatorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/DigestMD5SASLMechanismHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/DirectoryStringAttributeSyntaxConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/DseeCompatAccessControlHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/DynamicGroupImplementationConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/EntityTagVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/EntryCacheConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/EntryCacheMonitorProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/EntryDNVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/EntryUUIDPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/EntryUUIDVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ErrorLogAccountStatusNotificationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ErrorLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ExactMatchIdentityMapperConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ExtendedOperationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ExtensionConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ExternalChangelogDomainConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ExternalSASLMechanismHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FIFOEntryCacheConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileBasedAccessLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileBasedAuditLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileBasedDebugLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileBasedErrorLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileBasedHTTPAccessLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileBasedKeyManagerProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileBasedTrustManagerProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileCountLogRetentionPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FileSystemEntryCacheConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FingerprintCertificateMapperConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FixedTimeLogRotationPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FractionalLDIFImportPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/FreeDiskSpaceLogRetentionPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/GSSAPISASLMechanismHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/GetConnectionIdExtendedOperationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/GetSymmetricKeyExtendedOperationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/GlobalConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/GoverningStructureRuleVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/GroupImplementationConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/HTTPAccessLogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/HTTPConnectionHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/HasSubordinatesVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/IdentityMapperConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/IsMemberOfVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/JMXAlertHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/JMXConnectionHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/JPEGAttributeSyntaxConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/KeyManagerProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LDAPAttributeDescriptionListPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LDAPConnectionHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LDAPPassThroughAuthenticationPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LDIFBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LDIFConnectionHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LastModPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LengthBasedPasswordValidatorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LocalBackendWorkflowElementConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LocalDBBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LocalDBIndexConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LocalDBVLVIndexConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LogPublisherConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LogRetentionPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/LogRotationPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/MD5PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/MatchingRuleConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/MemberVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/MemoryBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/MemoryUsageMonitorProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/MonitorBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/MonitorProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/NetworkGroupConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/NetworkGroupPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/NullBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/NumSubordinatesVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PBKDF2PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PKCS11KeyManagerProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/Package.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ParallelWorkQueueConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordExpirationTimeVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordGeneratorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordModifyExtendedOperationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordPolicyImportPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordPolicyStateExtendedOperationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordPolicySubentryVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PasswordValidatorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PlainSASLMechanismHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/PluginRootConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ProfilerPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/QOSPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RC4PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RandomPasswordGeneratorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ReferentialIntegrityPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RegularExpressionIdentityMapperConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RepeatedCharactersPasswordValidatorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ReplicationDomainConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ReplicationServerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ReplicationSynchronizationProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RequestFilteringQOSPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/ResourceLimitsQOSPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RootConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RootDNConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RootDNUserConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/RootDSEBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SASLMechanismHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SHA1PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SMTPAccountStatusNotificationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SMTPAlertHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SNMPConnectionHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SaltedMD5PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SaltedSHA1PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SaltedSHA256PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SaltedSHA384PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SaltedSHA512PasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SambaPasswordPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SchemaBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SevenBitCleanPluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SimilarityBasedPasswordValidatorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SizeLimitLogRetentionPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SizeLimitLogRotationPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SoftReferenceEntryCacheConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/StackTraceMonitorProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/StartTLSExtendedOperationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/StaticGroupImplementationConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/StructuralObjectClassVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SubjectAttributeToUserAttributeCertificateMapperConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SubjectDNToUserAttributeCertificateMapperConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SubjectEqualsDNCertificateMapperConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SubschemaSubentryVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SynchronizationProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/SystemInfoMonitorProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/TaskBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/TelephoneNumberAttributeSyntaxConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/TimeLimitLogRotationPolicyConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/TraditionalWorkQueueConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/TripleDESPasswordStorageSchemeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/TrustManagerProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/TrustStoreBackendConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/UniqueAttributePluginConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/UniqueCharactersPasswordValidatorConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/UserDefinedVirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/VersionMonitorProviderConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/VirtualAttributeConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/VirtualStaticGroupImplementationConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/WhoAmIExtendedOperationHandlerConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/WorkQueueConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/WorkflowConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/admin/WorkflowElementConfiguration.xml (deleted)
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AESPasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AccessControlHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AccessLogFilteringCriteriaConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AccessLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AccountStatusNotificationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AdministrationConnectorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AlertHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AnonymousSASLMechanismHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AttributeCleanupPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AttributeSyntaxConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AttributeTypeDescriptionAttributeSyntaxConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AttributeValuePasswordValidatorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/AuthenticationPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/BackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/BackupBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/Base64PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/BlindTrustManagerProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/BlowfishPasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CancelExtendedOperationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CertificateAttributeSyntaxConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CertificateMapperConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ChangeNumberControlPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CharacterSetPasswordValidatorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ClearPasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ClientConnectionMonitorProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CollationMatchingRuleConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CollectiveAttributeSubentriesVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ConfigFileHandlerBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ConnectionHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CountryStringAttributeSyntaxConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CramMD5SASLMechanismHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CryptPasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/CryptoManagerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/DebugLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/DebugTargetConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/DictionaryPasswordValidatorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/DigestMD5SASLMechanismHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/DirectoryStringAttributeSyntaxConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/DseeCompatAccessControlHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/DynamicGroupImplementationConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/EntityTagVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/EntryCacheConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/EntryCacheMonitorProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/EntryDNVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/EntryUUIDPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/EntryUUIDVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ErrorLogAccountStatusNotificationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ErrorLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ExactMatchIdentityMapperConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ExtendedOperationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ExtensionConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ExternalChangelogDomainConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ExternalSASLMechanismHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FIFOEntryCacheConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileBasedAccessLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileBasedAuditLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileBasedDebugLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileBasedErrorLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileBasedHTTPAccessLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileBasedKeyManagerProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileBasedTrustManagerProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileCountLogRetentionPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FileSystemEntryCacheConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FingerprintCertificateMapperConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FixedTimeLogRotationPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FractionalLDIFImportPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/FreeDiskSpaceLogRetentionPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/GSSAPISASLMechanismHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/GetConnectionIdExtendedOperationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/GetSymmetricKeyExtendedOperationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/GlobalConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/GoverningStructureRuleVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/GroupImplementationConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/HTTPAccessLogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/HTTPConnectionHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/HasSubordinatesVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/IdentityMapperConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/IsMemberOfVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/JMXAlertHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/JMXConnectionHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/JPEGAttributeSyntaxConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/KeyManagerProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LDAPAttributeDescriptionListPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LDAPConnectionHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LDAPPassThroughAuthenticationPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LDIFBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LDIFConnectionHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LastModPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LengthBasedPasswordValidatorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LocalBackendWorkflowElementConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LocalDBBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LocalDBIndexConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LocalDBVLVIndexConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LogPublisherConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LogRetentionPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/LogRotationPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/MD5PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/MatchingRuleConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/MemberVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/MemoryBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/MemoryUsageMonitorProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/MonitorBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/MonitorProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/NetworkGroupConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/NetworkGroupPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/NullBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/NumSubordinatesVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PBKDF2PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PKCS11KeyManagerProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/Package.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ParallelWorkQueueConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordExpirationTimeVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordGeneratorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordModifyExtendedOperationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordPolicyImportPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordPolicyStateExtendedOperationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordPolicySubentryVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PasswordValidatorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PlainSASLMechanismHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/PluginRootConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ProfilerPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/QOSPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RC4PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RandomPasswordGeneratorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ReferentialIntegrityPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RegularExpressionIdentityMapperConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RepeatedCharactersPasswordValidatorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ReplicationDomainConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ReplicationServerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ReplicationSynchronizationProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RequestFilteringQOSPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/ResourceLimitsQOSPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RootConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RootDNConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RootDNUserConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/RootDSEBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SASLMechanismHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SHA1PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SMTPAccountStatusNotificationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SMTPAlertHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SNMPConnectionHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SaltedMD5PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SaltedSHA1PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SaltedSHA256PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SaltedSHA384PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SaltedSHA512PasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SambaPasswordPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SchemaBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SevenBitCleanPluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SimilarityBasedPasswordValidatorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SizeLimitLogRetentionPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SizeLimitLogRotationPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SoftReferenceEntryCacheConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/StackTraceMonitorProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/StartTLSExtendedOperationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/StaticGroupImplementationConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/StructuralObjectClassVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SubjectAttributeToUserAttributeCertificateMapperConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SubjectDNToUserAttributeCertificateMapperConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SubjectEqualsDNCertificateMapperConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SubschemaSubentryVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SynchronizationProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/SystemInfoMonitorProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/TaskBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/TelephoneNumberAttributeSyntaxConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/TimeLimitLogRotationPolicyConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/TraditionalWorkQueueConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/TripleDESPasswordStorageSchemeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/TrustManagerProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/TrustStoreBackendConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/UniqueAttributePluginConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/UniqueCharactersPasswordValidatorConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/UserDefinedVirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/VersionMonitorProviderConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/VirtualAttributeConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/VirtualStaticGroupImplementationConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/WhoAmIExtendedOperationHandlerConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/WorkQueueConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/WorkflowConfiguration.xml
opendj-config/src/main/resources/definitions/org/forgerock/opendj/server/config/WorkflowElementConfiguration.xml
opendj-config/src/main/resources/stylesheets/admin-cli.xsd
opendj-config/src/main/resources/stylesheets/admin-ldap.xsd
opendj-config/src/main/resources/stylesheets/admin-preprocessor.xsd
opendj-config/src/main/resources/stylesheets/admin.xsd
opendj-config/src/main/resources/stylesheets/cliMOProfile.xsl
opendj-config/src/main/resources/stylesheets/clientMO.xsl
opendj-config/src/main/resources/stylesheets/conditions.xsl
opendj-config/src/main/resources/stylesheets/ldapMOProfile.xsl
opendj-config/src/main/resources/stylesheets/manifestMO.xsl
opendj-config/src/main/resources/stylesheets/messagesMO.xsl
opendj-config/src/main/resources/stylesheets/metaMO.xsl
opendj-config/src/main/resources/stylesheets/package-info.xsl
opendj-config/src/main/resources/stylesheets/preprocessor.xsl
opendj-config/src/main/resources/stylesheets/property-types.xsl
opendj-config/src/main/resources/stylesheets/property-types/aci.xsl
opendj-config/src/main/resources/stylesheets/property-types/aggregation.xsl
opendj-config/src/main/resources/stylesheets/property-types/attribute-type.xsl
opendj-config/src/main/resources/stylesheets/property-types/boolean.xsl
opendj-config/src/main/resources/stylesheets/property-types/dn.xsl
opendj-config/src/main/resources/stylesheets/property-types/duration.xsl
opendj-config/src/main/resources/stylesheets/property-types/enumeration.xsl
opendj-config/src/main/resources/stylesheets/property-types/extensible-matching-rule-type.xsl
opendj-config/src/main/resources/stylesheets/property-types/integer.xsl
opendj-config/src/main/resources/stylesheets/property-types/ip-address-mask.xsl
opendj-config/src/main/resources/stylesheets/property-types/ip-address.xsl
opendj-config/src/main/resources/stylesheets/property-types/java-class.xsl
opendj-config/src/main/resources/stylesheets/property-types/oid.xsl
opendj-config/src/main/resources/stylesheets/property-types/password.xsl
opendj-config/src/main/resources/stylesheets/property-types/size.xsl
opendj-config/src/main/resources/stylesheets/property-types/string.xsl
opendj-config/src/main/resources/stylesheets/serverMO.xsl
opendj-config/src/test/java/org/forgerock/opendj/config/AbstractManagedObjectDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/AdminTestCase.java
opendj-config/src/test/java/org/forgerock/opendj/config/AggregationPropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/AttributeTypePropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/BooleanPropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/ClassPropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/ConfigurationMock.java
opendj-config/src/test/java/org/forgerock/opendj/config/ConfigurationMockTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/DNPropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/DurationPropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/DurationUnitTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/EnumPropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/IntegerPropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/LDAPProfileTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/ManagedObjectDefinitionI18NResourceTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/ManagedObjectPathTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/MockLDAPProfile.java
opendj-config/src/test/java/org/forgerock/opendj/config/RelativeInheritedDefaultBehaviorProviderTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/SizePropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/SizeUnitTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/StringPropertyDefinitionTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/TestCfg.java
opendj-config/src/test/java/org/forgerock/opendj/config/TestChildCfg.java
opendj-config/src/test/java/org/forgerock/opendj/config/TestChildCfgClient.java
opendj-config/src/test/java/org/forgerock/opendj/config/TestChildCfgDefn.java
opendj-config/src/test/java/org/forgerock/opendj/config/TestParentCfg.java
opendj-config/src/test/java/org/forgerock/opendj/config/TestParentCfgClient.java
opendj-config/src/test/java/org/forgerock/opendj/config/TestParentCfgDefn.java
opendj-config/src/test/java/org/forgerock/opendj/config/TestTopCfgDefnTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/ValidateConfigDefinitionsTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/AggregationClientTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/CreateEntryMockLDAPConnection.java
opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/DeleteSubtreeMockLDAPConnection.java
opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/LDAPClientTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/MockConstraint.java
opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/MockLDAPConnection.java
opendj-config/src/test/java/org/forgerock/opendj/config/client/ldap/ModifyEntryMockLDAPConnection.java
opendj-config/src/test/java/org/forgerock/opendj/config/server/AdminTestCaseUtils.java
opendj-config/src/test/java/org/forgerock/opendj/config/server/AggregationServerTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/server/ConstraintTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/server/DNBuilderTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/server/DefaultBehaviorTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/server/ListenerTest.java
opendj-config/src/test/java/org/forgerock/opendj/config/server/MockConstraint.java
opendj-config/src/test/java/org/opends/server/admin/AbstractManagedObjectDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/AdminTestCase.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/AggregationPropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/AttributeTypePropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/BooleanPropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/ClassPropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/DNPropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/DurationPropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/DurationUnitTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/EnumPropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/IntegerPropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/LDAPProfileTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/ManagedObjectDefinitionI18NResourceTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/ManagedObjectPathTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/MockLDAPProfile.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/RelativeInheritedDefaultBehaviorProviderTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/SizePropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/SizeUnitTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/StringPropertyDefinitionTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/TestCfg.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/TestChildCfg.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/TestChildCfgClient.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/TestChildCfgDefn.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/TestParentCfg.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/TestParentCfgClient.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/TestParentCfgDefn.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/TestTopCfgDefnTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/ValidateConfigDefinitionsTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/client/ldap/AggregationClientTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/client/ldap/CreateEntryMockLDAPConnection.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/client/ldap/DeleteSubtreeMockLDAPConnection.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/client/ldap/LDAPClientTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/client/ldap/MockConstraint.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/client/ldap/MockLDAPConnection.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/client/ldap/ModifyEntryMockLDAPConnection.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/server/AdminTestCaseUtils.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/server/AggregationServerTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/server/ConstraintTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/server/DNBuilderTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/server/DefaultBehaviorTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/server/ListenerTest.java (deleted)
opendj-config/src/test/java/org/opends/server/admin/server/MockConstraint.java (deleted)
opendj-config/src/test/resources/org/forgerock/opendj/config/TestChildCfgDefn.properties
opendj-config/src/test/resources/org/forgerock/opendj/config/TestChildConfiguration.xml
opendj-config/src/test/resources/org/forgerock/opendj/config/TestParentCfgDefn.properties
opendj-config/src/test/resources/org/forgerock/opendj/config/TestParentConfiguration.xml
opendj-config/src/test/resources/org/opends/server/admin/TestChildConfiguration.xml (deleted)
opendj-config/src/test/resources/org/opends/server/admin/TestParentConfiguration.xml (deleted) |