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