001/*
002 * Copyright 2018-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2018-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) 2018-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.unboundidds.tasks;
037
038
039
040import com.unboundid.util.NotNull;
041import com.unboundid.util.Nullable;
042import com.unboundid.util.StaticUtils;
043import com.unboundid.util.ThreadSafety;
044import com.unboundid.util.ThreadSafetyLevel;
045
046
047
048/**
049 * This enum defines the set of allowed timestamp formats for use in conjunction
050 * with the file retention task.
051 * <BR>
052 * <BLOCKQUOTE>
053 *   <B>NOTE:</B>  This class, and other classes within the
054 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
055 *   supported for use against Ping Identity, UnboundID, and
056 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
057 *   for proprietary functionality or for external specifications that are not
058 *   considered stable or mature enough to be guaranteed to work in an
059 *   interoperable way with other types of LDAP servers.
060 * </BLOCKQUOTE>
061 */
062@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
063public enum FileRetentionTaskTimestampFormat
064{
065  /**
066   * The timestamp format that uses the generalized time format in the UTC time
067   * zone (with the 'Z' time zone indicator) with millisecond-level precision
068   * (e.g., "20180102123456.789Z").
069   */
070  GENERALIZED_TIME_UTC_WITH_MILLISECONDS(true, "yyyyMMddHHmmss.SSS'Z'",
071       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_BEGIN_CAPTURE_GROUP +
072       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_YEAR +
073       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MONTH +
074       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_DAY +
075       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_HOUR +
076       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MINUTE +
077       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_SECOND +
078       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MILLISECOND +
079       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_LITERAL_Z +
080       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_END_CAPTURE_GROUP),
081
082
083
084  /**
085   * The timestamp format that uses the generalized time format in the UTC time
086   * zone (with the 'Z' time zone indicator) with second-level precision (e.g.,
087   * "20180102123456Z").
088   */
089  GENERALIZED_TIME_UTC_WITH_SECONDS(true, "yyyyMMddHHmmss'Z'",
090       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_BEGIN_CAPTURE_GROUP +
091       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_YEAR +
092       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MONTH +
093       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_DAY +
094       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_HOUR +
095       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MINUTE +
096       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_SECOND +
097       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_LITERAL_Z +
098       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_END_CAPTURE_GROUP),
099
100
101
102  /**
103   * The timestamp format that uses the generalized time format in the UTC time
104   * zone (with the 'Z' time zone indicator) with minute-level precision (e.g.,
105   * "201801021234Z").
106   */
107  GENERALIZED_TIME_UTC_WITH_MINUTES(true, "yyyyMMddHHmm'Z'",
108       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_BEGIN_CAPTURE_GROUP +
109       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_YEAR +
110       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MONTH +
111       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_DAY +
112       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_HOUR +
113       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MINUTE +
114       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_LITERAL_Z +
115       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_END_CAPTURE_GROUP),
116
117
118
119  /**
120   * The timestamp format that uses a numeric form at in the local time zone
121   * (with no time zone indicator) with millisecond-level precision (e.g.,
122   * "20180102123456.789").
123   */
124  LOCAL_TIME_WITH_MILLISECONDS(false, "yyyyMMddHHmmss.SSS",
125       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_BEGIN_CAPTURE_GROUP +
126       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_YEAR +
127       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MONTH +
128       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_DAY +
129       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_HOUR +
130       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MINUTE +
131       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_SECOND +
132       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MILLISECOND +
133       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_END_CAPTURE_GROUP),
134
135
136
137  /**
138   * The timestamp format that uses a numeric form at in the local time zone
139   * (with no time zone indicator) with second-level precision (e.g.,
140   * "20180102123456").
141   */
142  LOCAL_TIME_WITH_SECONDS(false, "yyyyMMddHHmmss",
143       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_BEGIN_CAPTURE_GROUP +
144       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_YEAR +
145       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MONTH +
146       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_DAY +
147       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_HOUR +
148       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MINUTE +
149       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_SECOND +
150       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_END_CAPTURE_GROUP),
151
152
153
154  /**
155   * The timestamp format that uses a numeric form at in the local time zone
156   * (with no time zone indicator) with minute-level precision (e.g.,
157   * "201801021234").
158   */
159  LOCAL_TIME_WITH_MINUTES(false, "yyyyMMddHHmm",
160       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_BEGIN_CAPTURE_GROUP +
161       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_YEAR +
162       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MONTH +
163       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_DAY +
164       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_HOUR +
165       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MINUTE +
166       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_END_CAPTURE_GROUP),
167
168
169
170  /**
171   * The timestamp format that uses a numeric form at in the local time zone
172   * (with no time zone indicator) with day-level precision (e.g., "20180102").
173   */
174  LOCAL_DATE(false, "yyyyMMdd",
175       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_BEGIN_CAPTURE_GROUP +
176       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_YEAR +
177       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_MONTH +
178       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_DAY +
179       FileRetentionTaskTimestampFormat.REGEX_FRAGMENT_END_CAPTURE_GROUP);
180
181
182
183  /**
184   * A regular expression fragment that begins a capture group.
185   */
186  @NotNull private static final String REGEX_FRAGMENT_BEGIN_CAPTURE_GROUP = "(";
187
188
189
190  /**
191   * A regular expression fragment that matches a year between 1900 and 2199.
192   */
193  @NotNull private static final String REGEX_FRAGMENT_YEAR =
194       "(19|20|21)[0-9][0-9]";
195
196
197
198  /**
199   * A regular expression fragment that matches a month between 01 and 12.
200   */
201  @NotNull private static final String REGEX_FRAGMENT_MONTH = "(0[1-9]|1[0-2])";
202
203
204
205  /**
206   * A regular expression fragment that matches a day between 01 and 31.
207   */
208  @NotNull private static final String REGEX_FRAGMENT_DAY =
209       "(0[1-9]|[1-2][0-9]|3[0-1])";
210
211
212
213  /**
214   * A regular expression fragment that matches an hour between 00 and 23.
215   */
216  @NotNull private static final String REGEX_FRAGMENT_HOUR =
217       "([0-1][0-9]|2[0-3])";
218
219
220
221  /**
222   * A regular expression fragment that matches a minute between 00 and 59.
223   */
224  @NotNull private static final String REGEX_FRAGMENT_MINUTE = "[0-5][0-9]";
225
226
227
228  /**
229   * A regular expression fragment that matches a second between 00 and 59.
230   */
231  @NotNull private static final String REGEX_FRAGMENT_SECOND = "[0-5][0-9]";
232
233
234
235  /**
236   * A regular expression fragment that matches a millisecond between 000 and
237   * 999, preceded by a literal period character.
238   */
239  @NotNull private static final String REGEX_FRAGMENT_MILLISECOND =
240       "\\.[0-9][0-9][0-9]";
241
242
243
244  /**
245   * A regular expression fragment that matches a literal 'Z' character (to
246   * serve as a time zone indicator).
247   */
248  @NotNull private static final String REGEX_FRAGMENT_LITERAL_Z = "Z";
249
250
251
252  /**
253   * A regular expression fragment that ends a capture group.
254   */
255  @NotNull private static final String REGEX_FRAGMENT_END_CAPTURE_GROUP = ")";
256
257
258
259  // Indicates whether this timestamp format should use the UTC time zone rather
260  // than the JVM's default time zone.
261  private final boolean isInUTCTimeZone;
262
263  // A format string that can be used to create a SimpleDateFormat object
264  // capable of parsing timestamps in this format.
265  @NotNull private final String simpleDateFormatString;
266
267  // A regular expression string that can be used to match timestamps in this
268  // format.
269  @NotNull private final String regexString;
270
271
272
273  /**
274   * Creates a new timestamp format value with the provided information.
275   *
276   * @param  isInUTCTimeZone         Indicates whether the timestamp format
277   *                                 should use the UTC time zone rather than
278   *                                 the JVM's default time zone.
279   * @param  simpleDateFormatString  A format string that can be used to create
280   *                                 a {@code SimpleDateFormat] object capable
281   *                                 of parsing timestamps in this format.  It
282   *                                 must not be {@code null}.
283   * @param  regexString             A regular expression string that can be
284   *                                 used to match timestamps in this format.
285   *                                 It must not be {@code null}.
286   */
287  FileRetentionTaskTimestampFormat(final boolean isInUTCTimeZone,
288                                   @NotNull final String simpleDateFormatString,
289                                   @NotNull final String regexString)
290  {
291    this.isInUTCTimeZone = isInUTCTimeZone;
292    this.simpleDateFormatString = simpleDateFormatString;
293    this.regexString = regexString;
294  }
295
296
297
298  /**
299   * Indicates whether the timestamp format should use the UTC time zone rather
300   * than the JVM's default time zone.
301   *
302   * @return  {@code true} if the timestamp format should use the UTC time zone,
303   *          or {@code false} if it should use the JVM's default time zone
304   *          (which itself may or may not be the UTC time zone).
305   */
306  public boolean isInUTCTimeZone()
307  {
308    return isInUTCTimeZone;
309  }
310
311
312
313  /**
314   * Retrieves a format string that can be used to create a
315   * {@code SimpleDateFormat} object capable of parsing timestamps in this
316   * format.
317   *
318   * @return  A format string that can be used to create a
319   *          {@code SimpleDateFormat} object capable of parsing timestamps in
320   *          this format.
321   */
322  @NotNull()
323  public String getSimpleDateFormatString()
324  {
325    return simpleDateFormatString;
326  }
327
328
329
330  /**
331   * Retrieves a regular expression string that can be used to match timestamps
332   * in this format.  The returned string will be surrounded by parentheses so
333   * that it can act as a capture group.
334   *
335   * @return  A regular expression string that can be used to match timestamps
336   *          in this format.
337   */
338  @NotNull()
339  public String getRegexString()
340  {
341    return regexString;
342  }
343
344
345
346  /**
347   * Retrieves the timestamp format value with the specified name.
348   *
349   * @param  name  The name of the timestamp format value to retrieve.
350   *
351   * @return  The timestamp format value with the specified name, or
352   *          {@code null} if there is no value with that name.
353   */
354  @Nullable()
355  public static FileRetentionTaskTimestampFormat forName(
356                     @NotNull final String name)
357  {
358    final String upperName = StaticUtils.toUpperCase(name).replace('-', '_');
359    for (final FileRetentionTaskTimestampFormat f : values())
360    {
361      if (f.name().equals(upperName))
362      {
363        return f;
364      }
365    }
366
367    return null;
368  }
369}