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 legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2009 Sun Microsystems, Inc. 025 * Portions Copyright 2013-2015 ForgeRock AS 026 */ 027package org.opends.server.types; 028 029import org.forgerock.opendj.ldap.ByteString; 030import static org.opends.messages.ProtocolMessages.*; 031import static org.opends.server.protocols.ldap.LDAPResultCode.*; 032import static org.forgerock.util.Reject.*; 033 034import java.io.IOException; 035import java.util.ArrayList; 036import java.util.List; 037 038import org.forgerock.i18n.LocalizableMessage; 039import org.forgerock.i18n.slf4j.LocalizedLogger; 040import org.forgerock.opendj.io.ASN1Reader; 041import org.forgerock.opendj.io.ASN1Writer; 042import org.opends.server.protocols.ldap.LDAPAttribute; 043 044/** 045 * This class defines a raw attribute, which has a type (which may 046 * include zero or more options), and zero or more values. It is an 047 * unprocessed element, so it will not have undergone any syntax or 048 * other forms of validity checking. 049 */ 050@org.opends.server.types.PublicAPI( 051 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED, 052 mayInstantiate=true, 053 mayExtend=false, 054 mayInvoke=true) 055public abstract class RawAttribute 056{ 057 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 058 059 060 061 /** 062 * Creates a new raw attribute with the provided type and no values. 063 * 064 * @param attributeType The attribute type for this attribute. It 065 * must not be {@code null}. 066 * 067 * @return The created raw attribute. 068 */ 069 public static RawAttribute create(String attributeType) 070 { 071 ifNull(attributeType); 072 073 return new LDAPAttribute(attributeType); 074 } 075 076 077 078 /** 079 * Creates a new raw attribute with the provided type value. 080 * 081 * @param attributeType The attribute type for this attribute. It 082 * must not be {@code null}. 083 * @param value The value to use for this attribute. It 084 * must not be {@code null}. 085 * 086 * @return The created raw attribute. 087 */ 088 public static RawAttribute create(String attributeType, 089 String value) 090 { 091 ifNull(attributeType, value); 092 093 return new LDAPAttribute(attributeType, value); 094 } 095 096 097 098 /** 099 * Creates a new raw attribute with the provided type value. 100 * 101 * @param attributeType The attribute type for this attribute. It 102 * must not be {@code null}. 103 * @param value The value to use for this attribute. It 104 * must not be {@code null}. 105 * 106 * @return The created raw attribute. 107 */ 108 public static RawAttribute create(String attributeType, 109 ByteString value) 110 { 111 ifNull(attributeType); 112 113 return new LDAPAttribute(attributeType, value); 114 } 115 116 117 118 /** 119 * Creates a new raw attribute with the provided type and values. 120 * 121 * @param attributeType The attribute type for this attribute. It 122 * must not be {@code null}. 123 * @param values The set of values for this attribute. 124 * 125 * @return The created raw attribute. 126 */ 127 public static RawAttribute create(String attributeType, 128 ArrayList<ByteString> values) 129 { 130 ifNull(attributeType); 131 132 return new LDAPAttribute(attributeType, values); 133 } 134 135 136 137 /** 138 * Creates a new raw attribute from the provided attribute. 139 * 140 * @param attribute The attribute to use to create this raw 141 * attribute. It must not be {@code null}. 142 * 143 * @return The created raw attribute. 144 */ 145 public static RawAttribute create(Attribute attribute) 146 { 147 ifNull(attribute); 148 149 return new LDAPAttribute(attribute); 150 } 151 152 153 154 /** 155 * Retrieves the attribute type for this attribute. 156 * 157 * @return The attribute type for this attribute. 158 */ 159 public abstract String getAttributeType(); 160 161 162 163 /** 164 * Specifies the attribute type for this attribute. 165 * 166 * @param attributeType The attribute type for this attribute. 167 */ 168 public abstract void setAttributeType(String attributeType); 169 170 171 172 /** 173 * Retrieves the set of values for this attribute. The returned 174 * list may be modified by the caller. 175 * 176 * @return The set of values for this attribute. 177 */ 178 public abstract List<ByteString> getValues(); 179 180 181 182 /** 183 * Retrieves a core attribute containing the information for this 184 * raw attribute. 185 * 186 * @return A core attribute containing the information for this raw 187 * attribute. 188 * 189 * @throws LDAPException If the provided value is invalid 190 * according to the attribute syntax. 191 */ 192 public abstract Attribute toAttribute() 193 throws LDAPException; 194 195 /** 196 * Writes this attribute to an ASN.1 output stream. 197 * 198 * @param stream The ASN.1 output stream to write to. 199 * @throws IOException If a problem occurs while writing to the 200 * stream. 201 */ 202 public void write(ASN1Writer stream) throws IOException 203 { 204 stream.writeStartSequence(); 205 stream.writeOctetString(getAttributeType()); 206 207 stream.writeStartSet(); 208 List<ByteString> values = getValues(); 209 if (values != null) 210 { 211 for(ByteString value : values) 212 { 213 stream.writeOctetString(value); 214 } 215 } 216 217 stream.writeEndSet(); 218 stream.writeEndSequence(); 219 } 220 221 /** 222 * Decodes the elements from the provided ASN.1 reader as an 223 * LDAP attribute. 224 * 225 * @param reader The ASN.1 reader. 226 * 227 * @return The decoded LDAP attribute. 228 * 229 * @throws LDAPException If a problem occurs while trying to 230 * decode the provided ASN.1 element as a 231 * raw attribute. 232 */ 233 public static LDAPAttribute decode(ASN1Reader reader) 234 throws LDAPException 235 { 236 try 237 { 238 reader.readStartSequence(); 239 } 240 catch (Exception e) 241 { 242 logger.traceException(e); 243 244 LocalizableMessage message = ERR_LDAP_ATTRIBUTE_DECODE_SEQUENCE.get(e); 245 throw new LDAPException(PROTOCOL_ERROR, message, e); 246 } 247 248 249 String attributeType; 250 try 251 { 252 attributeType = reader.readOctetStringAsString(); 253 } 254 catch (Exception e) 255 { 256 logger.traceException(e); 257 258 LocalizableMessage message = ERR_LDAP_ATTRIBUTE_DECODE_TYPE.get(e); 259 throw new LDAPException(PROTOCOL_ERROR, message, e); 260 } 261 262 263 ArrayList<ByteString> values; 264 try 265 { 266 reader.readStartSequence(); 267 values = new ArrayList<>(); 268 while(reader.hasNextElement()) 269 { 270 values.add(reader.readOctetString()); 271 } 272 reader.readEndSequence(); 273 } 274 catch (Exception e) 275 { 276 logger.traceException(e); 277 278 LocalizableMessage message = ERR_LDAP_ATTRIBUTE_DECODE_VALUES.get(e); 279 throw new LDAPException(PROTOCOL_ERROR, message, e); 280 } 281 282 try 283 { 284 reader.readEndSequence(); 285 } 286 catch (Exception e) 287 { 288 logger.traceException(e); 289 290 LocalizableMessage message = ERR_LDAP_ATTRIBUTE_DECODE_SEQUENCE.get(e); 291 throw new LDAPException(PROTOCOL_ERROR, message, e); 292 } 293 294 return new LDAPAttribute(attributeType, values); 295 } 296 297 298 299 /** 300 * Retrieves a string representation of this attribute. 301 * 302 * @return A string representation of this attribute. 303 */ 304 @Override 305 public String toString() 306 { 307 StringBuilder buffer = new StringBuilder(); 308 toString(buffer); 309 return buffer.toString(); 310 } 311 312 313 314 /** 315 * Appends a string representation of this attribute to the provided 316 * buffer. 317 * 318 * @param buffer The buffer to which the information should be 319 * appended. 320 */ 321 public abstract void toString(StringBuilder buffer); 322 323 324 325 /** 326 * Appends a multi-line string representation of this LDAP attribute 327 * to the provided buffer. 328 * 329 * @param buffer The buffer to which the information should be 330 * appended. 331 * @param indent The number of spaces from the margin that the 332 * lines should be indented. 333 */ 334 public abstract void toString(StringBuilder buffer, int indent); 335} 336