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