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