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