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 import org.opends.messages.Message;
029
030
031
032 import java.util.ArrayList;
033 import java.util.List;
034
035 import org.opends.server.protocols.asn1.ASN1Element;
036 import org.opends.server.protocols.asn1.ASN1OctetString;
037 import org.opends.server.protocols.asn1.ASN1Sequence;
038 import org.opends.server.protocols.asn1.ASN1Set;
039 import org.opends.server.protocols.ldap.LDAPAttribute;
040
041 import static org.opends.server.loggers.debug.DebugLogger.*;
042 import org.opends.server.loggers.debug.DebugTracer;
043 import static org.opends.messages.ProtocolMessages.*;
044 import static org.opends.server.protocols.ldap.LDAPResultCode.*;
045 import static org.opends.server.util.Validator.*;
046
047
048
049 /**
050 * This class defines a raw attribute, which has a type (which may
051 * include zero or more options), and zero or more values. It is an
052 * unprocessed element, so it will not have undergone any syntax or
053 * other forms of validity checking.
054 */
055 @org.opends.server.types.PublicAPI(
056 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
057 mayInstantiate=true,
058 mayExtend=false,
059 mayInvoke=true)
060 public abstract class RawAttribute
061 {
062 /**
063 * The tracer object for the debug logger.
064 */
065 private static final DebugTracer TRACER = getTracer();
066
067
068
069 /**
070 * Creates a new raw attribute with the provided type and no values.
071 *
072 * @param attributeType The attribute type for this attribute. It
073 * must not be {@code null}.
074 *
075 * @return The created raw attribute.
076 */
077 public static RawAttribute create(String attributeType)
078 {
079 ensureNotNull(attributeType);
080
081 return new LDAPAttribute(attributeType);
082 }
083
084
085
086 /**
087 * Creates a new raw attribute with the provided type value.
088 *
089 * @param attributeType The attribute type for this attribute. It
090 * must not be {@code null}.
091 * @param value The value to use for this attribute. It
092 * must not be {@code null}.
093 *
094 * @return The created raw attribute.
095 */
096 public static RawAttribute create(String attributeType,
097 String value)
098 {
099 ensureNotNull(attributeType, value);
100
101 return new LDAPAttribute(attributeType, value);
102 }
103
104
105
106 /**
107 * Creates a new raw attribute with the provided type value.
108 *
109 * @param attributeType The attribute type for this attribute. It
110 * must not be {@code null}.
111 * @param value The value to use for this attribute. It
112 * must not be {@code null}.
113 *
114 * @return The created raw attribute.
115 */
116 public static RawAttribute create(String attributeType,
117 ByteString value)
118 {
119 ensureNotNull(attributeType);
120
121 return new LDAPAttribute(attributeType,
122 value.toASN1OctetString());
123 }
124
125
126
127 /**
128 * Creates a new raw attribute with the provided type and values.
129 *
130 * @param attributeType The attribute type for this attribute. It
131 * must not be {@code null}.
132 * @param values The set of values for this attribute.
133 *
134 * @return The created raw attribute.
135 */
136 public static RawAttribute create(String attributeType,
137 List<ByteString> values)
138 {
139 ensureNotNull(attributeType);
140
141 return new LDAPAttribute(attributeType, convertValues(values));
142 }
143
144
145
146 /**
147 * Creates a new raw attribute from the provided attribute.
148 *
149 * @param attribute The attribute to use to create this raw
150 * attribute. It must not be {@code null}.
151 *
152 * @return The created raw attribute.
153 */
154 public static RawAttribute create(Attribute attribute)
155 {
156 ensureNotNull(attribute);
157
158 return new LDAPAttribute(attribute);
159 }
160
161
162
163 /**
164 * Converts the provided <CODE>List<ByteString></CODE> to an
165 * <CODE>ArrayList<ASN1OctetString></CODE>.
166 *
167 * @param values The list to be converted.
168 *
169 * @return The converted {@code ArrayList} object.
170 */
171 private static ArrayList<ASN1OctetString>
172 convertValues(List<ByteString> values)
173 {
174 if (values == null)
175 {
176 return null;
177 }
178
179 ArrayList<ASN1OctetString> convertedList =
180 new ArrayList<ASN1OctetString>(values.size());
181 for (ByteString s : values)
182 {
183 convertedList.add(s.toASN1OctetString());
184 }
185
186 return convertedList;
187 }
188
189
190
191 /**
192 * Retrieves the attribute type for this attribute.
193 *
194 * @return The attribute type for this attribute.
195 */
196 public abstract String getAttributeType();
197
198
199
200 /**
201 * Specifies the attribute type for this attribute.
202 *
203 * @param attributeType The attribute type for this attribute.
204 */
205 public abstract void setAttributeType(String attributeType);
206
207
208
209 /**
210 * Retrieves the set of values for this attribute. The returned
211 * list may be modified by the caller.
212 *
213 * @return The set of values for this attribute.
214 */
215 public abstract ArrayList<ASN1OctetString> getValues();
216
217
218
219 /**
220 * Retrieves a core attribute containing the information for this
221 * raw attribute.
222 *
223 * @return A core attribute containing the information for this raw
224 * attribute.
225 *
226 * @throws LDAPException If the provided value is invalid
227 * according to the attribute syntax.
228 */
229 public abstract Attribute toAttribute()
230 throws LDAPException;
231
232
233
234 /**
235 * Encodes this attribute to an ASN.1 element.
236 *
237 * @return The ASN.1 element containing the encoded attribute.
238 */
239 public final ASN1Element encode()
240 {
241 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
242 elements.add(new ASN1OctetString(getAttributeType()));
243
244 ArrayList<ASN1OctetString> values = getValues();
245 if ((values == null) || values.isEmpty())
246 {
247 elements.add(new ASN1Set());
248 }
249 else
250 {
251 elements.add(new ASN1Set(new ArrayList<ASN1Element>(values)));
252 }
253
254 return new ASN1Sequence(elements);
255 }
256
257
258
259 /**
260 * Decodes the provided ASN.1 element as an LDAP attribute.
261 *
262 * @param element The ASN.1 element to decode.
263 *
264 * @return The decoded LDAP attribute.
265 *
266 * @throws LDAPException If a problem occurs while trying to
267 * decode the provided ASN.1 element as a
268 * raw attribute.
269 */
270 public static LDAPAttribute decode(ASN1Element element)
271 throws LDAPException
272 {
273 ArrayList<ASN1Element> elements;
274 try
275 {
276 elements = element.decodeAsSequence().elements();
277 }
278 catch (Exception e)
279 {
280 if (debugEnabled())
281 {
282 TRACER.debugCaught(DebugLogLevel.ERROR, e);
283 }
284
285 Message message =
286 ERR_LDAP_ATTRIBUTE_DECODE_SEQUENCE.get(String.valueOf(e));
287 throw new LDAPException(PROTOCOL_ERROR, message, e);
288 }
289
290
291 int numElements = elements.size();
292 if (numElements != 2)
293 {
294 Message message =
295 ERR_LDAP_ATTRIBUTE_DECODE_INVALID_ELEMENT_COUNT.
296 get(numElements);
297 throw new LDAPException(PROTOCOL_ERROR, message);
298 }
299
300
301 String attributeType;
302 try
303 {
304 attributeType =
305 elements.get(0).decodeAsOctetString().stringValue();
306 }
307 catch (Exception e)
308 {
309 if (debugEnabled())
310 {
311 TRACER.debugCaught(DebugLogLevel.ERROR, e);
312 }
313
314 Message message =
315 ERR_LDAP_ATTRIBUTE_DECODE_TYPE.get(String.valueOf(e));
316 throw new LDAPException(PROTOCOL_ERROR, message, e);
317 }
318
319
320 ArrayList<ASN1OctetString> values;
321 try
322 {
323 ArrayList<ASN1Element> valueElements =
324 elements.get(1).decodeAsSet().elements();
325 values = new ArrayList<ASN1OctetString>(valueElements.size());
326 for (ASN1Element e : valueElements)
327 {
328 values.add(e.decodeAsOctetString());
329 }
330 }
331 catch (Exception e)
332 {
333 if (debugEnabled())
334 {
335 TRACER.debugCaught(DebugLogLevel.ERROR, e);
336 }
337
338 Message message =
339 ERR_LDAP_ATTRIBUTE_DECODE_VALUES.get(String.valueOf(e));
340 throw new LDAPException(PROTOCOL_ERROR, message, e);
341 }
342
343 return new LDAPAttribute(attributeType, values);
344 }
345
346
347
348 /**
349 * Retrieves a string representation of this attribute.
350 *
351 * @return A string representation of this attribute.
352 */
353 public String toString()
354 {
355 StringBuilder buffer = new StringBuilder();
356 toString(buffer);
357 return buffer.toString();
358 }
359
360
361
362 /**
363 * Appends a string representation of this attribute to the provided
364 * buffer.
365 *
366 * @param buffer The buffer to which the information should be
367 * appended.
368 */
369 public abstract void toString(StringBuilder buffer);
370
371
372
373 /**
374 * Appends a multi-line string representation of this LDAP attribute
375 * to the provided buffer.
376 *
377 * @param buffer The buffer to which the information should be
378 * appended.
379 * @param indent The number of spaces from the margin that the
380 * lines should be indented.
381 */
382 public abstract void toString(StringBuilder buffer, int indent);
383 }
384