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 Sun Microsystems, Inc.
015 * Portions Copyright 2015 ForgeRock AS.
016 */
017package org.opends.server.admin;
018
019
020
021import java.util.Arrays;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025import java.util.SortedSet;
026import java.util.TreeSet;
027
028
029
030/**
031 * A default managed object which should be created when a parent
032 * managed object is created. Default managed objects are associated
033 * with a {@link RelationDefinition}.
034 *
035 * @param <C>
036 *          The type of client default managed object configuration.
037 * @param <S>
038 *          The type of server default managed object configuration.
039 */
040public final class DefaultManagedObject
041    <C extends ConfigurationClient, S extends Configuration>
042    implements PropertyProvider {
043
044  /**
045   * An interface for incrementally constructing default managed
046   * objects.
047   *
048   * @param <C>
049   *          The type of client default managed object configuration.
050   * @param <S>
051   *          The type of server default managed object configuration.
052   */
053  public static final class Builder
054      <C extends ConfigurationClient, S extends Configuration> {
055
056    /** The default managed object's definition. */
057    private final ManagedObjectDefinition<C, S> definition;
058
059    /** The string encoded default managed object's properties. */
060    private final Map<String, List<String>> propertyStringValues = new HashMap<>();
061
062    /**
063     * Creates a new default managed object builder.
064     *
065     * @param definition
066     *          The default managed object's definition.
067     */
068    public Builder(ManagedObjectDefinition<C, S> definition) {
069      this.definition = definition;
070    }
071
072
073
074    /**
075     * Construct a default managed object based on the properties of
076     * this builder.
077     *
078     * @return Returns the new default managed object.
079     */
080    public DefaultManagedObject<C, S> getInstance() {
081      return new DefaultManagedObject<>(definition, propertyStringValues);
082    }
083
084
085
086    /**
087     * Defines a property's values for the default managed object.
088     *
089     * @param name
090     *          The name of the property.
091     * @param values
092     *          One or more property values in the string
093     *          representation.
094     */
095    public void setPropertyValues(String name, String... values) {
096      if (values == null || values.length == 0) {
097        throw new IllegalArgumentException(
098            "null or empty values specified for property " + name);
099      }
100
101      propertyStringValues.put(name, Arrays.asList(values));
102    }
103  }
104
105  /** The default managed object's definition. */
106  private final ManagedObjectDefinition<C, S> definition;
107
108  /** The string encoded default managed object's properties. */
109  private final Map<String, List<String>> propertyStringValues;
110
111
112
113  /** Private constructor. */
114  private DefaultManagedObject(ManagedObjectDefinition<C, S> definition,
115      Map<String, List<String>> propertyStringValues) {
116    this.definition = definition;
117    this.propertyStringValues = propertyStringValues;
118  }
119
120
121
122  /**
123   * Gets the managed object definition associated with this default
124   * managed object.
125   *
126   * @return Returns the managed object definition associated with
127   *         this default managed object.
128   */
129  public ManagedObjectDefinition<C, S> getManagedObjectDefinition() {
130    return definition;
131  }
132
133
134
135  /**
136   * Gets a mutable copy of the set of property values for the
137   * specified property.
138   *
139   * @param <T>
140   *          The type of the property to be retrieved.
141   * @param pd
142   *          The property to be retrieved.
143   * @return Returns a newly allocated set containing a copy of the
144   *         property's values. An empty set indicates that the
145   *         property has no values defined and any default behavior
146   *         is applicable.
147   * @throws IllegalArgumentException
148   *           If the property definition is not associated with this
149   *           managed object's definition.
150   */
151  public <T> SortedSet<T> getPropertyValues(PropertyDefinition<T> pd)
152      throws IllegalArgumentException {
153    // Validate the property definition.
154    definition.getPropertyDefinition(pd.getName());
155
156    // Do a defensive copy.
157    SortedSet<T> values = new TreeSet<>(pd);
158    List<String> stringValues = propertyStringValues.get(pd.getName());
159    if (stringValues != null) {
160      for (String stringValue : stringValues) {
161        values.add(pd.decodeValue(stringValue));
162      }
163    }
164    return values;
165  }
166
167
168
169  /**
170   * Performs run-time initialization of properties.
171   *
172   * @throws Exception
173   *           If this default managed object could not be
174   *           initialized.
175   */
176  void initialize() throws Exception {
177    // FIXME: it would be nice if we could decode all property values
178    // at this point. However this is not possible on the server side
179    // since some properties will be determined to be invalid since
180    // the schema is not loaded.
181
182    // Validate provided property names.
183    for (String name : propertyStringValues.keySet()) {
184      definition.getPropertyDefinition(name);
185    }
186  }
187}