001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027
028package org.opends.server.admin;
029import org.forgerock.i18n.LocalizableMessage;
030
031
032
033import static org.forgerock.util.Reject.*;
034
035import java.util.Collections;
036import java.util.HashMap;
037import java.util.Locale;
038import java.util.Map;
039import java.util.Set;
040
041
042
043/**
044 * A managed object composite relationship definition which represents
045 * a composition of zero or more managed objects.
046 *
047 * @param <C>
048 *          The type of client managed object configuration that this
049 *          relation definition refers to.
050 * @param <S>
051 *          The type of server managed object configuration that this
052 *          relation definition refers to.
053 */
054public final class InstantiableRelationDefinition
055    <C extends ConfigurationClient, S extends Configuration>
056    extends RelationDefinition<C, S> {
057
058  /**
059   * An interface for incrementally constructing instantiable relation
060   * definitions.
061   *
062   * @param <C>
063   *          The type of client managed object configuration that
064   *          this relation definition refers to.
065   * @param <S>
066   *          The type of server managed object configuration that
067   *          this relation definition refers to.
068   */
069  public static final class Builder
070      <C extends ConfigurationClient, S extends Configuration>
071      extends AbstractBuilder<C, S, InstantiableRelationDefinition<C, S>> {
072
073    /** The optional naming property definition. */
074    private PropertyDefinition<?> namingPropertyDefinition;
075
076    /** The plural name of the relation. */
077    private final String pluralName;
078
079    /**
080     * The optional default managed objects associated with this
081     * instantiable relation definition.
082     */
083    private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects = new HashMap<>();
084
085
086    /**
087     * Creates a new builder which can be used to incrementally build
088     * an instantiable relation definition.
089     *
090     * @param pd
091     *          The parent managed object definition.
092     * @param name
093     *          The name of the relation.
094     * @param pluralName
095     *          The plural name of the relation.
096     * @param cd
097     *          The child managed object definition.
098     */
099    public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name,
100        String pluralName, AbstractManagedObjectDefinition<C, S> cd) {
101      super(pd, name, cd);
102      this.pluralName = pluralName;
103    }
104
105
106
107    /**
108     * Adds the named default managed object to this instantiable
109     * relation definition.
110     *
111     * @param name
112     *          The name of the default managed object.
113     * @param defaultManagedObject
114     *          The default managed object.
115     */
116    public void setDefaultManagedObject(String name,
117        DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
118      this.defaultManagedObjects.put(name, defaultManagedObject);
119    }
120
121
122
123    /**
124     * Sets the naming property for the instantiable relation
125     * definition.
126     *
127     * @param namingPropertyDefinition
128     *          The property of the child managed object definition
129     *          which should be used for naming, or <code>null</code>
130     *          if this relation does not use a property for naming.
131     */
132    public void setNamingProperty(
133        PropertyDefinition<?> namingPropertyDefinition) {
134      ifNull(namingPropertyDefinition);
135      this.namingPropertyDefinition = namingPropertyDefinition;
136    }
137
138
139
140    /** {@inheritDoc} */
141    @Override
142    protected InstantiableRelationDefinition<C, S> buildInstance(
143        Common<C, S> common) {
144      return new InstantiableRelationDefinition<>(common, pluralName,
145          namingPropertyDefinition, defaultManagedObjects);
146    }
147
148  }
149
150  /** The optional naming property definition. */
151  private final PropertyDefinition<?> namingPropertyDefinition;
152
153  /** The plural name of the relation. */
154  private final String pluralName;
155
156  /**
157   * The optional default managed objects associated with this
158   * instantiable relation definition.
159   */
160  private final Map<String, DefaultManagedObject<? extends C, ? extends S>>
161    defaultManagedObjects;
162
163
164
165  /** Private constructor. */
166  private InstantiableRelationDefinition(Common<C, S> common,
167      String pluralName,
168      PropertyDefinition<?> namingPropertyDefinition,
169      Map<String, DefaultManagedObject<? extends C, ? extends S>>
170        defaultManagedObjects) {
171    super(common);
172    this.pluralName = pluralName;
173    this.namingPropertyDefinition = namingPropertyDefinition;
174    this.defaultManagedObjects = defaultManagedObjects;
175  }
176
177
178
179  /** {@inheritDoc} */
180  @Override
181  public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) {
182    return v.visitInstantiable(this, p);
183  }
184
185
186
187  /**
188   * Gets the named default managed object associated with this
189   * instantiable relation definition.
190   *
191   * @param name
192   *          The name of the default managed object.
193   * @return Returns the named default managed object.
194   * @throws IllegalArgumentException
195   *           If there is no default managed object associated with
196   *           the provided name.
197   */
198  public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(
199      String name) throws IllegalArgumentException {
200    if (!defaultManagedObjects.containsKey(name)) {
201      throw new IllegalArgumentException(
202          "unrecognized default managed object \"" + name + "\"");
203    }
204    return defaultManagedObjects.get(name);
205  }
206
207
208
209  /**
210   * Gets the names of the default managed objects associated with
211   * this instantiable relation definition.
212   *
213   * @return Returns an unmodifiable set containing the names of the
214   *         default managed object.
215   */
216  public Set<String> getDefaultManagedObjectNames() {
217    return Collections.unmodifiableSet(defaultManagedObjects.keySet());
218  }
219
220
221
222  /**
223   * Get the property of the child managed object definition which
224   * should be used for naming children.
225   *
226   * @return Returns the property of the child managed object
227   *         definition which should be used for naming, or
228   *         <code>null</code> if this relation does not use a
229   *         property for naming.
230   */
231  public PropertyDefinition<?> getNamingPropertyDefinition() {
232    return namingPropertyDefinition;
233  }
234
235
236
237  /**
238   * Get the plural name of the relation.
239   *
240   * @return Returns the plural name of the relation.
241   */
242  public String getPluralName() {
243    return pluralName;
244  }
245
246
247
248  /**
249   * Gets the user friendly plural name of this relation definition in
250   * the default locale.
251   *
252   * @return Returns the user friendly plural name of this relation
253   *         definition in the default locale.
254   */
255  public LocalizableMessage getUserFriendlyPluralName() {
256    return getUserFriendlyPluralName(Locale.getDefault());
257  }
258
259
260
261  /**
262   * Gets the user friendly plural name of this relation definition in
263   * the specified locale.
264   *
265   * @param locale
266   *          The locale.
267   * @return Returns the user friendly plural name of this relation
268   *         definition in the specified locale.
269   */
270  public LocalizableMessage getUserFriendlyPluralName(Locale locale) {
271    String property = "relation." + getName() + ".user-friendly-plural-name";
272    return ManagedObjectDefinitionI18NResource.getInstance().getMessage(
273        getParentDefinition(), property, locale);
274  }
275
276
277
278  /** {@inheritDoc} */
279  @Override
280  public void toString(StringBuilder builder) {
281    builder.append("name=");
282    builder.append(getName());
283    builder.append(" type=collection parent=");
284    builder.append(getParentDefinition().getName());
285    builder.append(" child=");
286    builder.append(getChildDefinition().getName());
287  }
288
289
290
291  /** {@inheritDoc} */
292  @Override
293  protected void initialize() throws Exception {
294    for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) {
295      dmo.initialize();
296    }
297  }
298}