001    /*
002     * Copyright 2007-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2016 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     */
021    package com.unboundid.ldap.sdk;
022    
023    
024    
025    import java.io.Serializable;
026    import java.util.HashMap;
027    
028    import com.unboundid.util.NotMutable;
029    import com.unboundid.util.ThreadSafety;
030    import 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)
069    public 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    }