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 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.types; 028 029 030 031 import static org.opends.server.loggers.debug.DebugLogger.*; 032 import static org.opends.server.util.Validator.*; 033 034 import org.opends.server.api.EqualityMatchingRule; 035 import org.opends.server.loggers.debug.DebugTracer; 036 import org.opends.server.protocols.asn1.ASN1OctetString; 037 038 039 040 /** 041 * This class defines a data structure that holds information about a 042 * single value of an attribute. It will always store the value in 043 * user-provided form, and will also store either a reference to the 044 * associated attribute type or the normalized form of the value. The 045 * normalized form of the value should only be used in cases where 046 * equality matching between two values can be performed with 047 * byte-for-byte comparisons of the normalized values. 048 */ 049 @org.opends.server.types.PublicAPI( 050 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED, 051 mayInstantiate=true, 052 mayExtend=false, 053 mayInvoke=true) 054 public final class AttributeValue 055 { 056 /** 057 * The tracer object for the debug logger. 058 */ 059 private static final DebugTracer TRACER = getTracer(); 060 061 062 063 // The normalized form of this value. 064 private ByteString normalizedValue; 065 066 // The user-provided form of this value. 067 private final ByteString value; 068 069 // The attribute type with which this value is associated. 070 private final AttributeType attributeType; 071 072 073 074 /** 075 * Creates a new attribute value with the provided information. 076 * 077 * @param attributeType The attribute type for this attribute 078 * value. It must not be {@code null}. 079 * @param value The value in user-provided form for this 080 * attribute value. It must not be 081 * {@code null}. 082 */ 083 public AttributeValue(AttributeType attributeType, ByteString value) 084 { 085 ensureNotNull(attributeType, value); 086 087 this.attributeType = attributeType; 088 this.value = value; 089 090 normalizedValue = null; 091 } 092 093 094 /** 095 * Creates a new attribute value with the provided information. 096 * 097 * @param attributeType The attribute type for this attribute 098 * value. It must not be {@code null}. 099 * @param value The value in user-provided form for this 100 * attribute value. It must not be 101 * {@code null}. 102 */ 103 public AttributeValue(AttributeType attributeType, String value) 104 { 105 ensureNotNull(attributeType, value); 106 107 this.attributeType = attributeType; 108 this.value = new ASN1OctetString(value); 109 110 normalizedValue = null; 111 } 112 113 114 /** 115 * Creates a new attribute value with the provided information. 116 * Note that this version of the constructor should only be used for 117 * attribute types in which equality matching can be performed by 118 * byte-for-byte comparison of normalized values. 119 * 120 * @param value The user-provided form of this value. 121 * It must not be {@code null}. 122 * @param normalizedValue The normalized form of this value. It 123 * must not be {@code null}. 124 */ 125 public AttributeValue(ByteString value, ByteString normalizedValue) 126 { 127 ensureNotNull(value, normalizedValue); 128 129 this.value = value; 130 this.normalizedValue = normalizedValue; 131 132 attributeType = null; 133 } 134 135 136 137 /** 138 * Retrieves the user-defined form of this attribute value. 139 * 140 * @return The user-defined form of this attribute value. 141 */ 142 public ByteString getValue() 143 { 144 return value; 145 } 146 147 148 149 /** 150 * Retrieves the raw bytes that make up this attribute value. 151 * 152 * @return The raw bytes that make up this attribute value. 153 */ 154 public byte[] getValueBytes() 155 { 156 return value.value(); 157 } 158 159 160 161 /** 162 * Retrieves a string representation of the user-defined form of 163 * this attribute value. 164 * 165 * @return The string representation of the user-defined form of 166 * this attribute value. 167 */ 168 public String getStringValue() 169 { 170 return value.stringValue(); 171 } 172 173 174 175 /** 176 * Retrieves the normalized form of this attribute value. 177 * 178 * @return The normalized form of this attribute value. 179 * 180 * @throws DirectoryException If an error occurs while trying to 181 * normalize the value (e.g., if it is 182 * not acceptable for use with the 183 * associated equality matching rule). 184 */ 185 public ByteString getNormalizedValue() 186 throws DirectoryException 187 { 188 if (normalizedValue == null) 189 { 190 normalizedValue = attributeType.normalize(value); 191 } 192 193 return normalizedValue; 194 } 195 196 197 198 /** 199 * Retrieves the bytes that make up the normalized form of this 200 * value. 201 * 202 * @return The bytes that make up the normalized form of this 203 * value. 204 * 205 * @throws DirectoryException If an error occurs while trying to 206 * normalize the value (e.g., if it is 207 * not acceptable for use with the 208 * associated equality matching rule). 209 */ 210 public byte[] getNormalizedValueBytes() 211 throws DirectoryException 212 { 213 return getNormalizedValue().value(); 214 } 215 216 217 218 /** 219 * Retrieves a string representation of the normalized form of this 220 * attribute value. 221 * 222 * @return The string representation of the normalized form of this 223 * attribute value. 224 * 225 * @throws DirectoryException If an error occurs while trying to 226 * normalize the value (e.g., if it is 227 * not acceptable for use with the 228 * associated equality matching rule). 229 */ 230 public String getNormalizedStringValue() 231 throws DirectoryException 232 { 233 if (normalizedValue == null) 234 { 235 normalizedValue = attributeType.normalize(value); 236 } 237 238 return normalizedValue.stringValue(); 239 } 240 241 242 243 244 /** 245 * Determines whether this attribute value is equal to the provided 246 * object. 247 * 248 * @param o The object for which to make the determination. 249 * 250 * @return <CODE>true</CODE> if this attribute value is equal to 251 * the provided object, or <CODE>false</CODE> if not. 252 */ 253 public boolean equals(Object o) 254 { 255 if (this == o) 256 { 257 return true; 258 } 259 260 if ((o != null) && (o instanceof AttributeValue)) 261 { 262 AttributeValue attrValue = (AttributeValue) o; 263 264 265 try 266 { 267 if (attributeType != null) 268 { 269 EqualityMatchingRule matchingRule = 270 attributeType.getEqualityMatchingRule(); 271 if (matchingRule == null) 272 { 273 return getNormalizedValue().equals( 274 attrValue.getNormalizedValue()); 275 } 276 else 277 { 278 return (matchingRule.valuesMatch(getNormalizedValue(), 279 attrValue.getNormalizedValue()) == 280 ConditionResult.TRUE); 281 } 282 } 283 else if (attrValue.attributeType != null) 284 { 285 EqualityMatchingRule matchingRule = 286 attrValue.attributeType.getEqualityMatchingRule(); 287 if (matchingRule == null) 288 { 289 return getNormalizedValue().equals( 290 attrValue.getNormalizedValue()); 291 } 292 else 293 { 294 return (matchingRule.valuesMatch(getNormalizedValue(), 295 attrValue.getNormalizedValue()) == 296 ConditionResult.TRUE); 297 } 298 } 299 else 300 { 301 return normalizedValue.equals( 302 attrValue.getNormalizedValue()); 303 } 304 } 305 catch (Exception e) 306 { 307 if (debugEnabled()) 308 { 309 TRACER.debugCaught(DebugLogLevel.ERROR, e); 310 } 311 312 return value.equals(attrValue.getValue()); 313 } 314 } 315 316 return false; 317 } 318 319 320 321 /** 322 * Retrieves the hash code for this attribute value. It will be 323 * calculated as the sum of the first two bytes in the value, or the 324 * value of a single-byte value, or zero for an empty value. 325 * 326 * @return A hash code for this attribute value. 327 */ 328 public int hashCode() 329 { 330 try 331 { 332 if (attributeType == null) 333 { 334 if (normalizedValue != null) 335 { 336 return normalizedValue.hashCode(); 337 } 338 else 339 { 340 return value.hashCode(); 341 } 342 } 343 else 344 { 345 return attributeType.generateHashCode(this); 346 } 347 } 348 catch (Exception e) 349 { 350 if (debugEnabled()) 351 { 352 TRACER.debugCaught(DebugLogLevel.ERROR, e); 353 } 354 355 return value.hashCode(); 356 } 357 } 358 359 360 361 /** 362 * Retrieves a string representation of this attribute value. 363 * 364 * @return A string representation of this attribute value. 365 */ 366 public String toString() 367 { 368 if (value == null) 369 { 370 return "null"; 371 } 372 else 373 { 374 return value.stringValue(); 375 } 376 } 377 378 379 380 /** 381 * Appends a string representation of this attribute value to the 382 * provided buffer. 383 * 384 * @param buffer The buffer to which the information should be 385 * appended. 386 */ 387 public void toString(StringBuilder buffer) 388 { 389 buffer.append(value.toString()); 390 } 391 } 392