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