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