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