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 028 package org.opends.server.admin; 029 030 031 032 import java.util.Arrays; 033 import java.util.HashSet; 034 import java.util.LinkedList; 035 import java.util.List; 036 import java.util.MissingResourceException; 037 import java.util.NoSuchElementException; 038 import java.util.Set; 039 040 041 042 /** 043 * This class is used to map configuration elements to their LDAP 044 * schema names. 045 * <p> 046 * It is possible to augment the core LDAP profile with additional 047 * profile mappings at run-time using instances of {@link Wrapper}. 048 * This is useful for unit tests which need to add and remove mock 049 * components. 050 */ 051 public final class LDAPProfile { 052 053 /** 054 * LDAP profile wrappers can be used to provide temporary LDAP 055 * profile information for components which do not have LDAP profile 056 * property files. These components are typically "mock" components 057 * used in unit-tests. 058 */ 059 public static abstract class Wrapper { 060 061 /** 062 * Default constructor. 063 */ 064 protected Wrapper() { 065 // No implementation required. 066 } 067 068 069 070 /** 071 * Get the name of the LDAP attribute associated with the 072 * specified property definition. 073 * <p> 074 * The default implementation of this method is to return 075 * <code>null</code>. 076 * 077 * @param d 078 * The managed object definition. 079 * @param pd 080 * The property definition. 081 * @return Returns the name of the LDAP attribute associated with 082 * the specified property definition, or <code>null</code> 083 * if the property definition is not handled by this LDAP 084 * profile wrapper. 085 */ 086 public String getAttributeName(AbstractManagedObjectDefinition<?, ?> d, 087 PropertyDefinition<?> pd) { 088 return null; 089 } 090 091 092 093 /** 094 * Gets the LDAP RDN attribute type for child entries of an 095 * instantiable relation. 096 * <p> 097 * The default implementation of this method is to return 098 * <code>null</code>. 099 * 100 * @param r 101 * The instantiable relation. 102 * @return Returns the LDAP RDN attribute type for child entries 103 * of an instantiable relation, or <code>null</code> if 104 * the instantiable relation is not handled by this LDAP 105 * profile wrapper. 106 */ 107 public String getInstantiableRelationChildRDNType( 108 InstantiableRelationDefinition<?, ?> r) { 109 return null; 110 } 111 112 113 114 /** 115 * Get the principle object class associated with the specified 116 * definition. 117 * <p> 118 * The default implementation of this method is to return 119 * <code>null</code>. 120 * 121 * @param d 122 * The managed object definition. 123 * @return Returns the principle object class associated with the 124 * specified definition, or <code>null</code> if the 125 * managed object definition is not handled by this LDAP 126 * profile wrapper. 127 */ 128 public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) { 129 return null; 130 } 131 132 133 134 /** 135 * Get an LDAP RDN sequence associatied with a relation. 136 * <p> 137 * The default implementation of this method is to return 138 * <code>null</code>. 139 * 140 * @param r 141 * The relation. 142 * @return Returns the LDAP RDN sequence associatied with a 143 * relation, or <code>null</code> if the relation is not 144 * handled by this LDAP profile wrapper. 145 */ 146 public String getRelationRDNSequence(RelationDefinition<?, ?> r) { 147 return null; 148 } 149 } 150 151 // The singleton instance. 152 private static final LDAPProfile INSTANCE = new LDAPProfile(); 153 154 155 156 /** 157 * Get the global LDAP profile instance. 158 * 159 * @return Returns the global LDAP profile instance. 160 */ 161 public static LDAPProfile getInstance() { 162 return INSTANCE; 163 } 164 165 // The list of profile wrappers. 166 private final LinkedList<Wrapper> profiles = new LinkedList<Wrapper>();; 167 168 // The LDAP profile property table. 169 private final ManagedObjectDefinitionResource resource = 170 ManagedObjectDefinitionResource.createForProfile("ldap"); 171 172 173 174 // Prevent construction. 175 private LDAPProfile() { 176 // No implementation required. 177 } 178 179 180 181 /** 182 * Get the name of the LDAP attribute associated with the specified 183 * property definition. 184 * 185 * @param d 186 * The managed object definition. 187 * @param pd 188 * The property definition. 189 * @return Returns the name of the LDAP attribute associated with 190 * the specified property definition. 191 * @throws MissingResourceException 192 * If the LDAP profile properties file associated with the 193 * provided managed object definition could not be loaded. 194 */ 195 public String getAttributeName(AbstractManagedObjectDefinition<?, ?> d, 196 PropertyDefinition<?> pd) throws MissingResourceException { 197 for (Wrapper profile : profiles) { 198 String attributeName = profile.getAttributeName(d, pd); 199 if (attributeName != null) { 200 return attributeName; 201 } 202 } 203 return resource.getString(d, "attribute." + pd.getName()); 204 } 205 206 207 208 /** 209 * Gets the LDAP RDN attribute type for child entries of an 210 * instantiable relation. 211 * 212 * @param r 213 * The instantiable relation. 214 * @return Returns the LDAP RDN attribute type for child entries of 215 * an instantiable relation. 216 * @throws MissingResourceException 217 * If the LDAP profile properties file associated with the 218 * provided managed object definition could not be loaded. 219 */ 220 public String getInstantiableRelationChildRDNType( 221 InstantiableRelationDefinition<?, ?> r) throws MissingResourceException { 222 if (r.getNamingPropertyDefinition() != null) { 223 // Use the attribute associated with the naming property. 224 return getAttributeName(r.getChildDefinition(), r 225 .getNamingPropertyDefinition()); 226 } else { 227 for (Wrapper profile : profiles) { 228 String rdnType = profile.getInstantiableRelationChildRDNType(r); 229 if (rdnType != null) { 230 return rdnType; 231 } 232 } 233 return resource.getString(r.getParentDefinition(), "naming-attribute." 234 + r.getName()); 235 } 236 } 237 238 239 240 /** 241 * Gets the LDAP object classes associated with an instantiable 242 * relation branch. The branch is the parent entry of child managed 243 * objects. 244 * 245 * @param r 246 * The instantiable relation. 247 * @return Returns the LDAP object classes associated with an 248 * instantiable relation branch. 249 */ 250 public List<String> getInstantiableRelationObjectClasses( 251 InstantiableRelationDefinition<?, ?> r) { 252 return Arrays.asList(new String[] { "top", "ds-cfg-branch" }); 253 } 254 255 256 257 /** 258 * Get the principle object class associated with the specified 259 * definition. 260 * 261 * @param d 262 * The managed object definition. 263 * @return Returns the principle object class associated with the 264 * specified definition. 265 * @throws MissingResourceException 266 * If the LDAP profile properties file associated with the 267 * provided managed object definition could not be loaded. 268 */ 269 public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) 270 throws MissingResourceException { 271 if (d.isTop()) { 272 return "top"; 273 } 274 275 for (Wrapper profile : profiles) { 276 String objectClass = profile.getObjectClass(d); 277 if (objectClass != null) { 278 return objectClass; 279 } 280 } 281 return resource.getString(d, "objectclass"); 282 } 283 284 285 286 /** 287 * Get all the object classes associated with the specified 288 * definition. 289 * <p> 290 * The returned list is ordered such that the uppermost object 291 * classes appear first (e.g. top). 292 * 293 * @param d 294 * The managed object definition. 295 * @return Returns all the object classes associated with the 296 * specified definition. 297 * @throws MissingResourceException 298 * If the LDAP profile properties file associated with the 299 * provided managed object definition could not be loaded. 300 */ 301 public List<String> getObjectClasses(AbstractManagedObjectDefinition<?, ?> d) 302 throws MissingResourceException { 303 LinkedList<String> objectClasses = new LinkedList<String>(); 304 Set<String> s = new HashSet<String>(); 305 306 // Add the object classes from the parent hierarchy. 307 while (d != null) { 308 String oc = getObjectClass(d); 309 if (!s.contains(oc)) { 310 objectClasses.addFirst(oc); 311 s.add(oc); 312 } 313 d = d.getParent(); 314 } 315 316 if (!s.contains("top")) { 317 objectClasses.addFirst("top"); 318 } 319 320 return objectClasses; 321 } 322 323 324 325 /** 326 * Get an LDAP RDN sequence associatied with a relation. 327 * 328 * @param r 329 * The relation. 330 * @return Returns the LDAP RDN sequence associatied with a 331 * relation. 332 * @throws MissingResourceException 333 * If the LDAP profile properties file associated with the 334 * provided managed object definition could not be loaded. 335 */ 336 public String getRelationRDNSequence(RelationDefinition<?, ?> r) 337 throws MissingResourceException { 338 for (Wrapper profile : profiles) { 339 String rdnSequence = profile.getRelationRDNSequence(r); 340 if (rdnSequence != null) { 341 return rdnSequence; 342 } 343 } 344 return resource.getString(r.getParentDefinition(), "rdn." + r.getName()); 345 } 346 347 348 349 /** 350 * Removes the last LDAP profile wrapper added using 351 * {@link #pushWrapper(org.opends.server.admin.LDAPProfile.Wrapper)}. 352 * 353 * @throws NoSuchElementException 354 * If there are no LDAP profile wrappers. 355 */ 356 public void popWrapper() throws NoSuchElementException { 357 profiles.removeFirst(); 358 } 359 360 361 362 /** 363 * Decorates the core LDAP profile with the provided LDAP profile 364 * wrapper. All profile requests will be directed to the provided 365 * wrapper before being forwarded onto the core profile if the 366 * request could not be satisfied. 367 * 368 * @param wrapper 369 * The LDAP profile wrapper. 370 */ 371 public void pushWrapper(Wrapper wrapper) { 372 profiles.addFirst(wrapper); 373 } 374 }