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 2015-2016 ForgeRock AS. 016 */ 017 018package org.forgerock.opendj.config; 019 020import org.forgerock.util.Reject; 021 022import java.util.Collections; 023import java.util.HashMap; 024import java.util.Locale; 025import java.util.Map; 026import java.util.Set; 027 028import org.forgerock.i18n.LocalizableMessage; 029 030/** 031 * A managed object composite relationship definition which represents a 032 * composition of zero or more managed objects. 033 * 034 * @param <C> 035 * The type of client managed object configuration that this relation 036 * definition refers to. 037 * @param <S> 038 * The type of server managed object configuration that this relation 039 * definition refers to. 040 */ 041public final class InstantiableRelationDefinition<C extends ConfigurationClient, S extends Configuration> extends 042 RelationDefinition<C, S> { 043 044 /** 045 * An interface for incrementally constructing instantiable relation 046 * definitions. 047 * 048 * @param <C> 049 * The type of client managed object configuration that this 050 * relation definition refers to. 051 * @param <S> 052 * The type of server managed object configuration that this 053 * relation definition refers to. 054 */ 055 public static final class Builder<C extends ConfigurationClient, S extends Configuration> extends 056 AbstractBuilder<C, S, InstantiableRelationDefinition<C, S>> { 057 058 /** The optional naming property definition. */ 059 private PropertyDefinition<?> namingPropertyDefinition; 060 061 /** The plural name of the relation. */ 062 private final String pluralName; 063 064 /** The optional default managed objects associated with this instantiable relation definition. */ 065 private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects = 066 new HashMap<>(); 067 068 /** 069 * Creates a new builder which can be used to incrementally build an 070 * instantiable relation definition. 071 * 072 * @param pd 073 * The parent managed object definition. 074 * @param name 075 * The name of the relation. 076 * @param pluralName 077 * The plural name of the relation. 078 * @param cd 079 * The child managed object definition. 080 */ 081 public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name, String pluralName, 082 AbstractManagedObjectDefinition<C, S> cd) { 083 super(pd, name, cd); 084 this.pluralName = pluralName; 085 } 086 087 /** 088 * Adds the named default managed object to this instantiable relation 089 * definition. 090 * 091 * @param name 092 * The name of the default managed object. 093 * @param defaultManagedObject 094 * The default managed object. 095 */ 096 public void setDefaultManagedObject(String name, 097 DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) { 098 this.defaultManagedObjects.put(name, defaultManagedObject); 099 } 100 101 /** 102 * Sets the naming property for the instantiable relation definition. 103 * 104 * @param namingPropertyDefinition 105 * The property of the child managed object definition which 106 * should be used for naming, or <code>null</code> if this 107 * relation does not use a property for naming. 108 */ 109 public void setNamingProperty(PropertyDefinition<?> namingPropertyDefinition) { 110 Reject.ifNull(namingPropertyDefinition); 111 this.namingPropertyDefinition = namingPropertyDefinition; 112 } 113 114 @Override 115 protected InstantiableRelationDefinition<C, S> buildInstance(Common<C, S> common) { 116 return new InstantiableRelationDefinition<>(common, pluralName, namingPropertyDefinition, 117 defaultManagedObjects); 118 } 119 120 } 121 122 /** The optional naming property definition. */ 123 private final PropertyDefinition<?> namingPropertyDefinition; 124 125 /** The plural name of the relation. */ 126 private final String pluralName; 127 128 /** The optional default managed objects associated with this instantiable relation definition. */ 129 private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects; 130 131 /** Private constructor. */ 132 private InstantiableRelationDefinition(Common<C, S> common, String pluralName, 133 PropertyDefinition<?> namingPropertyDefinition, 134 Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects) { 135 super(common); 136 this.pluralName = pluralName; 137 this.namingPropertyDefinition = namingPropertyDefinition; 138 this.defaultManagedObjects = defaultManagedObjects; 139 } 140 141 @Override 142 public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) { 143 return v.visitInstantiable(this, p); 144 } 145 146 /** 147 * Gets the named default managed object associated with this instantiable 148 * relation definition. 149 * 150 * @param name 151 * The name of the default managed object. 152 * @return Returns the named default managed object. 153 * @throws IllegalArgumentException 154 * If there is no default managed object associated with the 155 * provided name. 156 */ 157 public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(String name) { 158 if (!defaultManagedObjects.containsKey(name)) { 159 throw new IllegalArgumentException("unrecognized default managed object \"" + name + "\""); 160 } 161 return defaultManagedObjects.get(name); 162 } 163 164 /** 165 * Gets the names of the default managed objects associated with this 166 * instantiable relation definition. 167 * 168 * @return Returns an unmodifiable set containing the names of the default 169 * managed object. 170 */ 171 public Set<String> getDefaultManagedObjectNames() { 172 return Collections.unmodifiableSet(defaultManagedObjects.keySet()); 173 } 174 175 /** 176 * Get the property of the child managed object definition which should be 177 * used for naming children. 178 * 179 * @return Returns the property of the child managed object definition which 180 * should be used for naming, or <code>null</code> if this relation 181 * does not use a property for naming. 182 */ 183 public PropertyDefinition<?> getNamingPropertyDefinition() { 184 return namingPropertyDefinition; 185 } 186 187 /** 188 * Get the plural name of the relation. 189 * 190 * @return Returns the plural name of the relation. 191 */ 192 public String getPluralName() { 193 return pluralName; 194 } 195 196 /** 197 * Gets the user friendly plural name of this relation definition in the 198 * default locale. 199 * 200 * @return Returns the user friendly plural name of this relation definition 201 * in the default locale. 202 */ 203 public LocalizableMessage getUserFriendlyPluralName() { 204 return getUserFriendlyPluralName(Locale.getDefault()); 205 } 206 207 /** 208 * Gets the user friendly plural name of this relation definition in the 209 * specified locale. 210 * 211 * @param locale 212 * The locale. 213 * @return Returns the user friendly plural name of this relation definition 214 * in the specified locale. 215 */ 216 public LocalizableMessage getUserFriendlyPluralName(Locale locale) { 217 String property = "relation." + getName() + ".user-friendly-plural-name"; 218 return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale); 219 } 220 221 @Override 222 public void toString(StringBuilder builder) { 223 builder.append("name="); 224 builder.append(getName()); 225 builder.append(" type=collection parent="); 226 builder.append(getParentDefinition().getName()); 227 builder.append(" child="); 228 builder.append(getChildDefinition().getName()); 229 } 230 231 @Override 232 protected void initialize() throws Exception { 233 for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) { 234 dmo.initialize(); 235 } 236 } 237}