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