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