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.ASN1Enumerated;
037 import org.opends.server.protocols.asn1.ASN1Sequence;
038 import org.opends.server.protocols.ldap.LDAPModification;
039
040 import static org.opends.server.loggers.debug.DebugLogger.*;
041 import org.opends.server.loggers.debug.DebugTracer;
042 import static org.opends.messages.ProtocolMessages.*;
043 import static org.opends.server.protocols.ldap.LDAPConstants.*;
044 import static org.opends.server.protocols.ldap.LDAPResultCode.*;
045 import static org.opends.server.util.ServerConstants.*;
046
047
048
049 /**
050 * This class defines the data structures and methods to use when
051 * interacting with a raw modification, which describes a change that
052 * should be made to an attribute.
053 */
054 @org.opends.server.types.PublicAPI(
055 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
056 mayInstantiate=true,
057 mayExtend=false,
058 mayInvoke=true)
059 public abstract class RawModification
060 {
061 /**
062 * The tracer object for the debug logger.
063 */
064 private static final DebugTracer TRACER = getTracer();
065
066 /**
067 * Creates a new raw modification with the provided type and
068 * attribute.
069 *
070 * @param modificationType The modification type for this
071 * modification.
072 * @param attribute The attribute for this modification.
073 *
074 * @return The constructed raw modification.
075 */
076 public static RawModification
077 create(ModificationType modificationType,
078 RawAttribute attribute)
079 {
080 return new LDAPModification(modificationType, attribute);
081 }
082
083
084
085 /**
086 * Creates a new raw modification with the provided type and
087 * attribute.
088 *
089 * @param modificationType The modification type for this
090 * modification.
091 * @param attributeType The name of the attribute type for this
092 * modification.
093 *
094 * @return The constructed raw modification.
095 */
096 public static RawModification
097 create(ModificationType modificationType,
098 String attributeType)
099 {
100 RawAttribute rawAttribute = RawAttribute.create(attributeType);
101
102 return new LDAPModification(modificationType, rawAttribute);
103 }
104
105
106
107 /**
108 * Creates a new raw modification with the provided type and
109 * attribute.
110 *
111 * @param modificationType The modification type for this
112 * modification.
113 * @param attributeType The name of the attribute type for this
114 * modification.
115 * @param attributeValue The attribute value for this
116 * modification.
117 *
118 * @return The constructed raw modification.
119 */
120 public static RawModification
121 create(ModificationType modificationType,
122 String attributeType,
123 String attributeValue)
124 {
125 RawAttribute rawAttribute =
126 RawAttribute.create(attributeType, attributeValue);
127
128 return new LDAPModification(modificationType, rawAttribute);
129 }
130
131
132
133 /**
134 * Creates a new raw modification with the provided type and
135 * attribute.
136 *
137 * @param modificationType The modification type for this
138 * modification.
139 * @param attributeType The name of the attribute type for this
140 * modification.
141 * @param attributeValue The attribute value for this
142 * modification.
143 *
144 * @return The constructed raw modification.
145 */
146 public static RawModification
147 create(ModificationType modificationType,
148 String attributeType,
149 ByteString attributeValue)
150 {
151 RawAttribute rawAttribute =
152 RawAttribute.create(attributeType, attributeValue);
153
154 return new LDAPModification(modificationType, rawAttribute);
155 }
156
157
158
159 /**
160 * Creates a new raw modification with the provided type and
161 * attribute.
162 *
163 * @param modificationType The modification type for this
164 * modification.
165 * @param attributeType The name of the attribute type for this
166 * modification.
167 * @param attributeValues The set of attribute values for this
168 * modification.
169 *
170 * @return The constructed raw modification.
171 */
172 public static RawModification
173 create(ModificationType modificationType,
174 String attributeType,
175 List<ByteString> attributeValues)
176 {
177 RawAttribute rawAttribute =
178 RawAttribute.create(attributeType, attributeValues);
179
180 return new LDAPModification(modificationType, rawAttribute);
181 }
182
183
184
185 /**
186 * Retrieves the modification type for this modification.
187 *
188 * @return The modification type for this modification.
189 */
190 public abstract ModificationType getModificationType();
191
192
193
194 /**
195 * Specifies the modification type for this modification.
196 *
197 * @param modificationType The modification type for this
198 * modification.
199 */
200 public abstract void setModificationType(
201 ModificationType modificationType);
202
203
204
205 /**
206 * Retrieves the attribute for this modification.
207 *
208 * @return The attribute for this modification.
209 */
210 public abstract RawAttribute getAttribute();
211
212
213
214 /**
215 * Specifies the attribute for this modification.
216 *
217 * @param attribute The attribute for this modification.
218 */
219 public abstract void setAttribute(RawAttribute attribute);
220
221
222
223 /**
224 * Encodes this modification to an ASN.1 element.
225 *
226 * @return The ASN.1 element containing the encoded modification.
227 */
228 public final ASN1Element encode()
229 {
230 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
231 elements.add(new ASN1Enumerated(
232 getModificationType().intValue()));
233 elements.add(getAttribute().encode());
234
235 return new ASN1Sequence(elements);
236 }
237
238
239
240 /**
241 * Decodes the provided ASN.1 element as an LDAP modification.
242 *
243 * @param element The ASN.1 element to decode.
244 *
245 * @return The decoded LDAP modification.
246 *
247 * @throws LDAPException If a problem occurs while attempting to
248 * decode the provided ASN.1 element as a
249 * raw modification.
250 */
251 public static LDAPModification decode(ASN1Element element)
252 throws LDAPException
253 {
254 ArrayList<ASN1Element> elements;
255 try
256 {
257 elements = element.decodeAsSequence().elements();
258 }
259 catch (Exception e)
260 {
261 if (debugEnabled())
262 {
263 TRACER.debugCaught(DebugLogLevel.ERROR, e);
264 }
265
266 Message message = ERR_LDAP_MODIFICATION_DECODE_SEQUENCE.get(
267 String.valueOf(e));
268 throw new LDAPException(PROTOCOL_ERROR, message, e);
269 }
270
271
272 int numElements = elements.size();
273 if (numElements != 2)
274 {
275 Message message =
276 ERR_LDAP_MODIFICATION_DECODE_INVALID_ELEMENT_COUNT.
277 get(numElements);
278 throw new LDAPException(PROTOCOL_ERROR, message);
279 }
280
281
282 ModificationType modificationType;
283 try
284 {
285 switch (elements.get(0).decodeAsEnumerated().intValue())
286 {
287 case MOD_TYPE_ADD:
288 modificationType = ModificationType.ADD;
289 break;
290 case MOD_TYPE_DELETE:
291 modificationType = ModificationType.DELETE;
292 break;
293 case MOD_TYPE_REPLACE:
294 modificationType = ModificationType.REPLACE;
295 break;
296 case MOD_TYPE_INCREMENT:
297 modificationType = ModificationType.INCREMENT;
298 break;
299 default:
300 int intValue =
301 elements.get(0).decodeAsEnumerated().intValue();
302 Message message =
303 ERR_LDAP_MODIFICATION_DECODE_INVALID_MOD_TYPE.
304 get(intValue);
305 throw new LDAPException(PROTOCOL_ERROR, message);
306 }
307 }
308 catch (LDAPException le)
309 {
310 throw le;
311 }
312 catch (Exception e)
313 {
314 if (debugEnabled())
315 {
316 TRACER.debugCaught(DebugLogLevel.ERROR, e);
317 }
318
319 Message message = ERR_LDAP_MODIFICATION_DECODE_MOD_TYPE.get(
320 String.valueOf(e));
321 throw new LDAPException(PROTOCOL_ERROR, message, e);
322 }
323
324
325 RawAttribute attribute;
326 try
327 {
328 attribute = RawAttribute.decode(elements.get(1));
329 }
330 catch (Exception e)
331 {
332 if (debugEnabled())
333 {
334 TRACER.debugCaught(DebugLogLevel.ERROR, e);
335 }
336
337 Message message =
338 ERR_LDAP_MODIFICATION_DECODE_ATTR.get(String.valueOf(e));
339 throw new LDAPException(PROTOCOL_ERROR, message, e);
340 }
341
342
343 return new LDAPModification(modificationType, attribute);
344 }
345
346
347
348 /**
349 * Creates a new core {@code Modification} object from this raw
350 * modification.
351 *
352 * @return The decoded modification.
353 *
354 * @throws LDAPException If a problem occurs while trying to
355 * convert the raw modification to a core
356 * {@code Modification}.
357 */
358 public abstract Modification toModification()
359 throws LDAPException;
360
361
362
363 /**
364 * Retrieves a string representation of this modification.
365 *
366 * @return A string representation of this modification.
367 */
368 public String toString()
369 {
370 StringBuilder buffer = new StringBuilder();
371 toString(buffer);
372 return buffer.toString();
373 }
374
375
376
377 /**
378 * Appends a string representation of this modification to the
379 * provided buffer.
380 *
381 * @param buffer The buffer to which the information should be
382 * appended.
383 */
384 public abstract void toString(StringBuilder buffer);
385
386
387
388 /**
389 * Appends a multi-line string representation of this LDAP
390 * modification to the provided buffer.
391 *
392 * @param buffer The buffer to which the information should be
393 * appended.
394 * @param indent The number of spaces from the margin that the
395 * lines should be indented.
396 */
397 public abstract void toString(StringBuilder buffer, int indent);
398 }
399