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 2006-2008 Sun Microsystems, Inc. 015 * Portions Copyright 2013-2015 ForgeRock AS. 016 */ 017package org.opends.server.types; 018 019import java.util.LinkedHashMap; 020import java.util.LinkedHashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024 025import org.forgerock.i18n.slf4j.LocalizedLogger; 026 027import static org.forgerock.util.Reject.*; 028import static org.opends.server.util.ServerConstants.*; 029 030/** 031 * This class defines a DIT structure rule, which is used to indicate 032 * the types of children that entries may have. 033 */ 034@org.opends.server.types.PublicAPI( 035 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED, 036 mayInstantiate=false, 037 mayExtend=false, 038 mayInvoke=true) 039public final class DITStructureRule 040 implements SchemaFileElement 041{ 042 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 043 044 /** Indicates whether this DIT structure rule is declared "obsolete". */ 045 private final boolean isObsolete; 046 047 /** The rule ID for this DIT structure rule. */ 048 private final int ruleID; 049 050 /** The name form for this DIT structure rule. */ 051 private final NameForm nameForm; 052 053 /** 054 * The set of additional name-value pairs associated with this DIT 055 * structure rule. 056 */ 057 private final Map<String,List<String>> extraProperties; 058 059 /** 060 * The set of names for this DIT structure rule, in a mapping 061 * between the all-lowercase form and the user-defined form. 062 */ 063 private final Map<String,String> names; 064 065 /** The set of superior DIT structure rules. */ 066 private final Set<DITStructureRule> superiorRules; 067 068 /** The definition string for this DIT structure rule. */ 069 private final String definition; 070 071 /** The description for this DIT structure rule. */ 072 private final String description; 073 074 075 076 /** 077 * Creates a new DIT structure rule with the provided information. 078 * 079 * @param definition The definition string used to create 080 * this DIT structure rule. It must not be 081 * {@code null}. 082 * @param names The set of names for this DIT structure 083 * rule, mapping the lowercase names to the 084 * user-defined values. 085 * @param ruleID The rule ID for this DIT structure rule. 086 * @param description The description for this DIT structure 087 * rule. 088 * @param isObsolete Indicates whether this DIT structure 089 * rule is declared "obsolete". 090 * @param nameForm The name form for this DIT structure 091 * rule. 092 * @param superiorRules References to the superior rules for 093 * this DIT structure rule. 094 * @param extraProperties The set of "extra" properties associated 095 * with this DIT structure rules. 096 */ 097 public DITStructureRule(String definition, Map<String,String> names, 098 int ruleID, String description, 099 boolean isObsolete, NameForm nameForm, 100 Set<DITStructureRule> superiorRules, 101 Map<String,List<String>> extraProperties) 102 { 103 ifNull(definition); 104 105 this.ruleID = ruleID; 106 this.description = description; 107 this.isObsolete = isObsolete; 108 this.nameForm = nameForm; 109 110 int schemaFilePos = definition.indexOf(SCHEMA_PROPERTY_FILENAME); 111 if (schemaFilePos > 0) 112 { 113 String defStr; 114 try 115 { 116 int firstQuotePos = definition.indexOf('\'', schemaFilePos); 117 int secondQuotePos = definition.indexOf('\'', 118 firstQuotePos+1); 119 120 defStr = definition.substring(0, schemaFilePos).trim() + " " + 121 definition.substring(secondQuotePos+1).trim(); 122 } 123 catch (Exception e) 124 { 125 logger.traceException(e); 126 127 defStr = definition; 128 } 129 130 this.definition = defStr; 131 } 132 else 133 { 134 this.definition = definition; 135 } 136 137 if (names == null || names.isEmpty()) 138 { 139 this.names = new LinkedHashMap<>(0); 140 } 141 else 142 { 143 this.names = new LinkedHashMap<>(names); 144 } 145 146 if (superiorRules == null || superiorRules.isEmpty()) 147 { 148 this.superiorRules = new LinkedHashSet<>(0); 149 } 150 else 151 { 152 this.superiorRules = new LinkedHashSet<>(superiorRules); 153 } 154 155 if (extraProperties == null || extraProperties.isEmpty()) 156 { 157 this.extraProperties = new LinkedHashMap<>(0); 158 } 159 else 160 { 161 this.extraProperties = new LinkedHashMap<>(extraProperties); 162 } 163 } 164 165 166 167 /** 168 * Retrieves the set of names that may be used to reference this DIT 169 * structure rule. The returned mapping will be between an all 170 * lower-case form of the name and a name in the user-defined form 171 * (which may include mixed capitalization). 172 * 173 * @return The set of names that may be used to reference this DIT 174 * structure rule. 175 */ 176 public Map<String,String> getNames() 177 { 178 return names; 179 } 180 181 182 183 /** 184 * Indicates whether this DIT structure rule has the specified name. 185 * 186 * @param lowerName The lowercase name for which to make the 187 * determination. 188 * 189 * @return {@code true} if the specified name is assigned to this 190 * DIT structure rule, or {@code false} if not. 191 */ 192 public boolean hasName(String lowerName) 193 { 194 return names.containsKey(lowerName); 195 } 196 197 198 199 /** 200 * Retrieves the rule ID for this DIT structure rule. 201 * 202 * @return The rule ID for this DIT structure rule. 203 */ 204 public int getRuleID() 205 { 206 return ruleID; 207 } 208 209 210 211 /** 212 * Retrieves the name or rule ID for this DIT structure rule. If it 213 * has one or more names, then the primary name will be returned. 214 * If it does not have any names, then the rule ID will be returned. 215 * 216 * @return The name or rule ID for this DIT structure rule. 217 */ 218 public String getNameOrRuleID() 219 { 220 if (names.isEmpty()) 221 { 222 return String.valueOf(ruleID); 223 } 224 else 225 { 226 return names.values().iterator().next(); 227 } 228 } 229 230 231 232 /** 233 * Retrieves the description for this DIT structure rule. 234 * 235 * @return The description for this DIT structure rule. 236 */ 237 public String getDescription() 238 { 239 return description; 240 } 241 242 243 244 /** 245 * Retrieves the name form for this DIT structure rule. 246 * 247 * @return The name form for this DIT structure rule. 248 */ 249 public NameForm getNameForm() 250 { 251 return nameForm; 252 } 253 254 255 256 /** 257 * Retrieves the structural objectclass for the name form with which 258 * this DIT structure rule is associated. 259 * 260 * @return The structural objectclass for the name form with which 261 * this DIT structure rule is associated. 262 */ 263 public ObjectClass getStructuralClass() 264 { 265 return nameForm.getStructuralClass(); 266 } 267 268 269 270 /** 271 * Retrieves the set of superior rules for this DIT structure rule. 272 * 273 * @return The set of superior rules for this DIT structure rule. 274 */ 275 public Set<DITStructureRule> getSuperiorRules() 276 { 277 return superiorRules; 278 } 279 280 281 282 /** 283 * Indicates whether this DIT structure rule has one or more 284 * superior rules. 285 * 286 * @return {@code true} if this DIT structure rule has one or more 287 * superior rules, or {@code false} if not. 288 */ 289 boolean hasSuperiorRules() 290 { 291 return superiorRules != null && !superiorRules.isEmpty(); 292 } 293 294 295 296 /** 297 * Indicates whether this DIT structure rule is declared "obsolete". 298 * 299 * @return {@code true} if this DIT structure rule is declared 300 * "obsolete", or {@code false} if not. 301 */ 302 public boolean isObsolete() 303 { 304 return isObsolete; 305 } 306 307 308 309 /** 310 * Retrieves a mapping between the names of any extra non-standard 311 * properties that may be associated with this DIT structure rule 312 * and the value for that property. 313 * 314 * @return A mapping between the names of any extra non-standard 315 * properties that may be associated with this DIT 316 * structure rule and the value for that property. 317 */ 318 @Override 319 public Map<String,List<String>> getExtraProperties() 320 { 321 return extraProperties; 322 } 323 324 325 326 /** 327 * Indicates whether the provided object is equal to this DIT 328 * structure rule. The object will be considered equal if it is a 329 * DIT structure rule with the same OID as the current type. 330 * 331 * @param o The object for which to make the determination. 332 * 333 * @return {@code true} if the provided object is equal to this 334 * attribute, or {@code false} if not. 335 */ 336 @Override 337 public boolean equals(Object o) 338 { 339 if (this == o) 340 { 341 return true; 342 } 343 if (!(o instanceof DITStructureRule)) 344 { 345 return false; 346 } 347 return ruleID == ((DITStructureRule) o).ruleID; 348 } 349 350 351 352 /** 353 * Retrieves the hash code for this DIT structure rule. It will be 354 * equal to the rule ID. 355 * 356 * @return The hash code for this DIT structure rule. 357 */ 358 @Override 359 public int hashCode() 360 { 361 return ruleID; 362 } 363 364 365 366 /** 367 * Retrieves the string representation of this attribute type in the 368 * form specified in RFC 2252. 369 * 370 * @return The string representation of this attribute type in the 371 * form specified in RFC 2252. 372 */ 373 @Override 374 public String toString() 375 { 376 return definition; 377 } 378 379}