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