001/*
002 * Copyright 2007-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2008-2014 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk;
022
023
024
025import java.io.Serializable;
026import java.util.HashMap;
027
028import com.unboundid.util.NotMutable;
029import com.unboundid.util.ThreadSafety;
030import com.unboundid.util.ThreadSafetyLevel;
031
032
033
034/**
035 * This class defines a data type for modification type values.  Clients should
036 * generally use one of the {@code ADD}, {@code DELETE}, {@code REPLACE}, or
037 * {@code INCREMENT} values, although it is possible to create a new
038 * modification type with a specified integer value if necessary using the
039 * {@link #valueOf(int)} method.  The following modification types are defined:
040 * <UL>
041 *   <LI>{@code ADD} -- Indicates that the provided value(s) should be added to
042 *       the specified attribute in the target entry.  If the attribute does not
043 *       already exist, it will be created.  If it does exist, then the new
044 *       values will be merged added to the existing values.  At least one value
045 *       must be provided with the {@code ADD} modification type, and none of
046 *       those values will be allowed to exist in the entry.</LI>
047 *   <LI>{@code DELETE} -- Indicates that the specified attribute or attribute
048 *       values should be removed from the entry.  If no values are provided,
049 *       then the entire attribute will be removed.  If one or more values are
050 *       given, then only those values will be removed.  If any values are
051 *       provided, then all of those values must exist in the target entry.</LI>
052 *   <LI>{@code REPLACE} -- Indicates that the set of values for the specified
053 *       attribute should be replaced with the provided value(s).  If no values
054 *       are given, then the specified attribute will be removed from the entry
055 *       if it exists, or no change will be made.  If one or more values are
056 *       provided, then those values will replace the existing values if the
057 *       attribute already exists, or a new attribute will be added with those
058 *       values if there was previously no such attribute in the entry.</LI>
059 *   <LI>{@code INCREMENT} -- Indicates that the value of the specified
060 *       attribute should be incremented.  The target entry must have exactly
061 *       one value for the specified attribute and it must be an integer.  The
062 *       modification must include exactly one value, and it must be an integer
063 *       which specifies the amount by which the existing value is to be
064 *       incremented (or decremented, if the provided value is negative).</LI>
065 * </UL>
066 */
067@NotMutable()
068@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
069public final class ModificationType
070       implements Serializable
071{
072  /**
073   * The integer value for the "add" modification type.
074   */
075  public static final int ADD_INT_VALUE = 0;
076
077
078
079  /**
080   * A predefined add modification type, which indicates that the associated
081   * value(s) should be added to the specified attribute in the target entry.
082   * If the attribute does not already exist, it will be created.  If it does
083   * exist, then the new values will be merged added to the existing values.  At
084   * least one value must be provided with the {@code ADD} modification type,
085   * and none of those values will be allowed to exist in the entry.
086   */
087  public static final ModificationType ADD =
088       new ModificationType("ADD", ADD_INT_VALUE);
089
090
091
092  /**
093   * The integer value for the "delete" modification type.
094   */
095  public static final int DELETE_INT_VALUE = 1;
096
097
098
099  /**
100   * A predefined delete modification type, which indicates that the specified
101   * attribute or attribute values should be removed from the entry.  If no
102   * values are provided, then the entire attribute will be removed.  If one or
103   * more values are given, then only those values will be removed.  If any
104   * values are provided, then all of those values must exist in the target
105   * entry.
106   */
107  public static final ModificationType DELETE =
108       new ModificationType("DELETE", DELETE_INT_VALUE);
109
110
111
112  /**
113   * The integer value for the "replace" modification type.
114   */
115  public static final int REPLACE_INT_VALUE = 2;
116
117
118
119  /**
120   * A predefined replace modification type, which indicates that the set of
121   * values for the specified attribute should be replaced with the provided
122   * value(s).  If no values are given, then the specified attribute will be
123   * removed from the entry if it exists, or no change will be made.  If one or
124   * more values are provided, then those values will replace the existing
125   * values if the attribute already exists, or a new attribute will be added
126   * with those values if there was previously no such attribute in the entry.
127   */
128  public static final ModificationType REPLACE =
129       new ModificationType("REPLACE", REPLACE_INT_VALUE);
130
131
132
133  /**
134   * The integer value for the "increment" modification type.
135   */
136  public static final int INCREMENT_INT_VALUE = 3;
137
138
139
140  /**
141   * A predefined increment modification type, which indicates that the value of
142   * the specified attribute should be incremented.  The target entry must have
143   * exactly one value for the specified attribute and it must be an integer.
144   * The modification must include exactly one value, and it must be an integer
145   * which specifies the amount by which the existing value is to be incremented
146   * (or decremented, if the provided value is negative).
147   */
148  public static final ModificationType INCREMENT =
149       new ModificationType("INCREMENT", INCREMENT_INT_VALUE);
150
151
152
153  /**
154   * The set of result code objects created with undefined int result code
155   * values.
156   */
157  private static final HashMap<Integer,ModificationType> UNDEFINED_MOD_TYPES =
158       new HashMap<Integer,ModificationType>();
159
160
161
162  /**
163   * The serial version UID for this serializable class.
164   */
165  private static final long serialVersionUID = -7863114394728980308L;
166
167
168
169  // The integer value for this modification type.
170  private final int intValue;
171
172  // The name to use for this modification type.
173  private final String name;
174
175
176
177  /**
178   * Creates a new modification type with the specified integer value.
179   *
180   * @param  intValue  The integer value to use for this modification type.
181   */
182  private ModificationType(final int intValue)
183  {
184    this.intValue = intValue;
185
186    name = String.valueOf(intValue);
187  }
188
189
190
191  /**
192   * Creates a new modification type with the specified name and integer value.
193   *
194   * @param  name      The name to use for this modification type.
195   * @param  intValue  The integer value to use for this modification type.
196   */
197  private ModificationType(final String name, final int intValue)
198  {
199    this.name     = name;
200    this.intValue = intValue;
201  }
202
203
204
205  /**
206   * Retrieves the name for this modification type.
207   *
208   * @return  The name for this modification type.
209   */
210  public String getName()
211  {
212    return name;
213  }
214
215
216
217  /**
218   * Retrieves the integer value for this modification type.
219   *
220   * @return  The integer value for this modification type.
221   */
222  public int intValue()
223  {
224    return intValue;
225  }
226
227
228
229  /**
230   * Retrieves the modification type with the specified integer value.
231   *
232   * @param  intValue  The integer value for which to retrieve the corresponding
233   *                   modification type.
234   *
235   * @return  The modification type with the specified integer value, or a new
236   *          modification type if the provided value does not match any of the
237   *          predefined modification types.
238   */
239  public static ModificationType valueOf(final int intValue)
240  {
241    switch (intValue)
242    {
243      case 0:
244        return ADD;
245      case 1:
246        return DELETE;
247      case 2:
248        return REPLACE;
249      case 3:
250        return INCREMENT;
251      default:
252        synchronized (UNDEFINED_MOD_TYPES)
253        {
254          ModificationType t = UNDEFINED_MOD_TYPES.get(intValue);
255          if (t == null)
256          {
257            t = new ModificationType(intValue);
258            UNDEFINED_MOD_TYPES.put(intValue, t);
259          }
260
261          return t;
262        }
263    }
264  }
265
266
267
268  /**
269   * Retrieves the predefined modification type with the specified integer
270   * value.
271   *
272   * @param  intValue  The integer value for which to retrieve the corresponding
273   *                   modification type.
274   *
275   * @return  The modification type with the specified integer value, or
276   *          {@code null} if the provided integer value does not represent a
277   *          defined modification type.
278   */
279  public static ModificationType definedValueOf(final int intValue)
280  {
281    switch (intValue)
282    {
283      case 0:
284        return ADD;
285      case 1:
286        return DELETE;
287      case 2:
288        return REPLACE;
289      case 3:
290        return INCREMENT;
291      default:
292        return null;
293    }
294  }
295
296
297
298  /**
299   * Retrieves an array of all modification types defined in the LDAP SDK.
300   *
301   * @return  An array of all modification types defined in the LDAP SDK.
302   */
303  public static ModificationType[] values()
304  {
305    return new ModificationType[]
306    {
307      ADD,
308      DELETE,
309      REPLACE,
310      INCREMENT
311    };
312  }
313
314
315
316  /**
317   * The hash code for this modification type.
318   *
319   * @return  The hash code for this modification type.
320   */
321  @Override()
322  public int hashCode()
323  {
324    return intValue;
325  }
326
327
328
329  /**
330   * Indicates whether the provided object is equal to this modification type.
331   *
332   * @param  o  The object for which to make the determination.
333   *
334   * @return  {@code true} if the provided object is a modification type that is
335   *          equal to this modification type, or {@code false} if not.
336   */
337  @Override()
338  public boolean equals(final Object o)
339  {
340    if (o == null)
341    {
342      return false;
343    }
344    else if (o == this)
345    {
346      return true;
347    }
348    else if (o instanceof ModificationType)
349    {
350      return (intValue == ((ModificationType) o).intValue);
351    }
352    else
353    {
354      return false;
355    }
356  }
357
358
359
360  /**
361   * Retrieves a string representation of this modification type.
362   *
363   * @return  A string representation of this modification type.
364   */
365  @Override()
366  public String toString()
367  {
368    return name;
369  }
370}