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