001/*
002 * Copyright 2022-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2022-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) 2022-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.controls;
037
038
039
040import java.io.Serializable;
041
042import com.unboundid.util.Mutable;
043import com.unboundid.util.NotNull;
044import com.unboundid.util.ThreadSafety;
045import com.unboundid.util.ThreadSafetyLevel;
046
047
048
049/**
050 * This enum defines options for the behaviors that should be used when trying
051 * to decode JSON objects embedded in a {@link JSONFormattedRequestControl} or
052 * {@link JSONFormattedResponseControl} as
053 * {@link com.unboundid.ldap.sdk.Control} objects.
054 * <BR>
055 * <BLOCKQUOTE>
056 *   <B>NOTE:</B>  This class, and other classes within the
057 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
058 *   supported for use against Ping Identity, UnboundID, and
059 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
060 *   for proprietary functionality or for external specifications that are not
061 *   considered stable or mature enough to be guaranteed to work in an
062 *   interoperable way with other types of LDAP servers.
063 * </BLOCKQUOTE>
064 */
065@Mutable()
066@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
067public final class JSONFormattedControlDecodeBehavior
068       implements Serializable
069{
070  /**
071   * The serial verison UID for this serizlizable class.
072   */
073  private static final long serialVersionUID = -1035196310465374381L;
074
075
076
077  // Indicates whether to allow embedded JSON-formatted request or response
078  // controls.
079  private boolean allowEmbeddedJSONFormattedControl;
080
081  // Indicates whether to use strict mode when decoding controls.
082  private boolean strict;
083
084  // Indicates whether to throw an exception when encountering an object that
085  // has the proper basic formatting for a JSON control with a criticality of
086  // true, but that cannot actually be decoded as a valid control.
087  private boolean throwOnInvalidCriticalControl;
088
089  // Indicates whether to throw an exception when encountering an object that
090  // has the proper basic formatting for a JSON control with a criticality of
091  // false, but that cannot actually be decoded as a valid control.
092  private boolean throwOnInvalidNonCriticalControl;
093
094  // Indicates whether to throw an exception when encountering an object that
095  // does not meet the basic requirements for a JSON-formatted control.
096  private boolean throwOnUnparsableObject;
097
098
099
100  /**
101   * Creates a new instance of this behavior with the default configuration.
102   * The default configuration is as follows:
103   * <UL>
104   *   <LI>{@code throwOnUnparsableObject} is set to {@code true}</LI>
105   *   <LI>{@code throwOnInvalidCriticalControl} is set to {@code true}</LI>
106   *   <LI>{@code throwOnInvalidNonCriticalControl} is set to {@code true}</LI>
107   *   <LI>{@code allowEmbeddedJSONFormattedControl} is set to
108   *       {@code false}</LI>
109   *   <LI>{@code strict} is set to {@code false}</LI>
110   * </UL>
111   */
112  public JSONFormattedControlDecodeBehavior()
113  {
114    throwOnUnparsableObject = true;
115    throwOnInvalidCriticalControl = true;
116    throwOnInvalidNonCriticalControl = true;
117    allowEmbeddedJSONFormattedControl = false;
118    strict = false;
119  }
120
121
122
123  /**
124   * Indicates whether to throw an exception if the JSON-formatted request or
125   * response control includes a JSON object that does not meet the basic
126   * requirements for representing a valid JSON-formatted control, including
127   * controls without the required {@code oid} and {@code criticality} fields,
128   * and controls with both {@code value-base64} and {@code value-json} fields.
129   * If strict mode is enabled, then this also includes unrecognized top-level
130   * fields.
131   *
132   * @return  {@code true} if an exception should be thrown if a JSON-formatted
133   *          request or response control includes a JSON object that does not
134   *          meet the basic requirements for representing a valid
135   *          JSON-formatted control, or {@code false} if any such JSON objects
136   *          should simply be ignored.
137   */
138  public boolean throwOnUnparsableObject()
139  {
140    return throwOnUnparsableObject;
141  }
142
143
144
145  /**
146   * Specifies whether to throw an exception if the JSON-formatted request or
147   * response control includes a JSON object that does not meet the basic
148   * requirements for representing a valid JSON-formatted control, including
149   * controls without the required {@code oid} and {@code criticality} fields,
150   * and controls with both {@code value-base64} and {@code value-json} fields.
151   * If strict mode is enabled, then this also includes unrecognized top-level
152   * fields.
153   *
154   * @param  throwOnUnparsableObject  Indicates whether to throw an exception
155   *                                  for any JSON object that does not meet
156   *                                  the basic requirements for a
157   *                                  JSON-formatted control.  If this is
158   *                                  {@code true}, then an exception will be
159   *                                  thrown if any such JSON object is
160   *                                  encountered.  If this is {@code false},
161   *                                  any such JSON objects will be ignored.
162   */
163  public void setThrowOnUnparsableObject(final boolean throwOnUnparsableObject)
164  {
165    this.throwOnUnparsableObject = throwOnUnparsableObject;
166  }
167
168
169
170  /**
171   * Indicates whether to throw an exception if the JSON-formatted request or
172   * response control includes a JSON object that at least meets the basic
173   * requirements for a JSON-formatted control with a criticality of
174   * {@code true}, but that cannot be parsed as a valid {@code Control} instance
175   * for some reason.  This may include a control with an OID for which
176   * specific decoding support has been implemented but a problem is encountered
177   * while trying to decode the JSON object as a control of that type, or a
178   * control with an OID for which no specific decoding has been implemented but
179   * includes a value specified using the {@code value-json} format.
180   *
181   * @return  {@code true} if an exception should be thrown if a critical
182   *          control cannot be decoded as a valid control instance, or
183   *          {@code false} if any such controls should be ignored.
184   */
185  public boolean throwOnInvalidCriticalControl()
186  {
187    return throwOnInvalidCriticalControl;
188  }
189
190
191
192  /**
193   * Specifies whether to throw an exception if the JSON-formatted request or
194   * response control includes a JSON object that at least meets the basic
195   * requirements for a JSON-formatted control with a criticality of
196   * {@code true}, but that cannot be parsed as a valid {@code Control} instance
197   * for some reason.  This may include a control with an OID for which
198   * specific decoding support has been implemented but a problem is encountered
199   * while trying to decode the JSON object as a control of that type, or a
200   * control with an OID for which no specific decoding has been implemented but
201   * includes a value specified using the {@code value-json} format.
202   *
203   * @param  throwOnInvalidCriticalControl  Indicates whether to throw an
204   *                                        exception for any well-formed JSON
205   *                                        object with a criticality of
206   *                                        {@code true} that cannot be parsed
207   *                                        as a {@code Control}.  If this is
208   *                                        {@code true}, then an exception will
209   *                                        be thrown if any such object is
210   *                                        encountered.  If this is
211   *                                        {@code false}, then any such JSON
212   *                                        objects will be ignored.
213   */
214  public void setThrowOnInvalidCriticalControl(
215                   final boolean throwOnInvalidCriticalControl)
216  {
217    this.throwOnInvalidCriticalControl = throwOnInvalidCriticalControl;
218  }
219
220
221
222  /**
223   * Indicates whether to throw an exception if the JSON-formatted request or
224   * response control includes a JSON object that at least meets the basic
225   * requirements for a JSON-formatted control with a criticality of
226   * {@code false}, but that cannot be parsed as a valid {@code Control}
227   * instance for some reason.  This may include a control with an OID for which
228   * specific decoding support has been implemented but a problem is encountered
229   * while trying to decode the JSON object as a control of that type, or a
230   * control with an OID for which no specific decoding has been implemented but
231   * includes a value specified using the {@code value-json} format.
232   *
233   * @return  {@code true} if an exception should be thrown if a non-critical
234   *          control cannot be decoded as a valid control instance, or
235   *          {@code false} if any such controls should be ignored.
236   */
237  public boolean throwOnInvalidNonCriticalControl()
238  {
239    return throwOnInvalidNonCriticalControl;
240  }
241
242
243
244  /**
245   * Specifies whether to throw an exception if the JSON-formatted request or
246   * response control includes a JSON object that at least meets the basic
247   * requirements for a JSON-formatted control with a criticality of
248   * {@code false}, but that cannot be parsed as a valid {@code Control}
249   * instance for some reason.  This may include a control with an OID for which
250   * specific decoding support has been implemented but a problem is encountered
251   * while trying to decode the JSON object as a control of that type, or a
252   * control with an OID for which no specific decoding has been implemented but
253   * includes a value specified using the {@code value-json} format.
254   *
255   * @param  throwOnInvalidNonCriticalControl  Indicates whether to throw an
256   *                                           exception for any well-formed
257   *                                           JSON object with a criticality of
258   *                                           {@code false} that cannot be
259   *                                           parsed as a {@code Control}.  If
260   *                                           this is {@code true}, then an
261   *                                           exception will be thrown if any
262   *                                           such object is encountered.  If
263   *                                           this is {@code false}, then any
264   *                                           such JSON objects will be
265   *                                           ignored.
266   */
267  public void setThrowOnInvalidNonCriticalControl(
268                   final boolean throwOnInvalidNonCriticalControl)
269  {
270    this.throwOnInvalidNonCriticalControl = throwOnInvalidNonCriticalControl;
271  }
272
273
274
275  /**
276   * Indicates whether to allow a JSON-formatted request or response control to
277   * include another JSON-formatted request or response control in the set of
278   * embedded controls.  If embedded JSON-formatted controls are not allowed,
279   * then the attempt to decode will throw an exception if the control is
280   * critical, or it will be ignored with a non-fatal error message if the
281   * control is non-critical.
282   *
283   * @return  {@code true} if embedded JSON-formatted request or response
284   *          controls should be allowed, or {@code false} if not.
285   */
286  public boolean allowEmbeddedJSONFormattedControl()
287  {
288    return allowEmbeddedJSONFormattedControl;
289  }
290
291
292
293  /**
294   * Specifies whether to allow a JSON-formatted request or response control to
295   * include another JSON-formatted request or response control in the set of
296   * embedded controls.  If embedded JSON-formatted controls are not allowed,
297   * then the attempt to decode will throw an exception if the control is
298   * critical, or it will be ignored with a non-fatal error message if the
299   * control is non-critical.
300   *
301   * @param  allowEmbeddedJSONFormattedControl  Indicates whether to allow a
302   *                                            JSON-formatted request or
303   *                                            response control.  If this is
304   *                                            {@code true}, then an embedded
305   *                                            JSON-formatted control will
306   *                                            either result in an exception
307   *                                            (if the embedded control is
308   *                                            critical) or cause it to be
309   *                                            ignored with a non-fatal error
310   *                                            message (if it is not critical).
311   *                                            If this is {@code false}, then
312   *                                            the JSON-formatted control will
313   *                                            be included directly in the list
314   *                                            of decoded controls that is
315   *                                            returned without attempting to
316   *                                            extract its embedded controls.
317   */
318  public void setAllowEmbeddedJSONFormattedControl(
319                   final boolean allowEmbeddedJSONFormattedControl)
320  {
321    this.allowEmbeddedJSONFormattedControl = allowEmbeddedJSONFormattedControl;
322  }
323
324
325
326  /**
327   * Indicates whether to use strict mode when parsing JSON objects as controls.
328   * This may include throwing an exception if a JSON object contains any
329   * unrecognized fields, or if the object violates any other control-specific
330   * constraints.
331   *
332   * @return  {@code true} if strict mode should be used when parsing JSON
333   *          objects as controls, or {@code false} if a lenient mode should be
334   *          used.
335   */
336  public boolean strict()
337  {
338    return strict;
339  }
340
341
342
343  /**
344   * Specifies whether to use strict mode when parsing JSON objects as controls.
345   * This may include throwing an exception if a JSON object contains any
346   * unrecognized fields, or if the object violates any other control-specific
347   * constraints.
348   *
349   * @param  strict  Indicates whether to use strict mode when parsing JSON
350   *                 objects as controls.  If this is {@code true}, then strict
351   *                 mode will be used.  If this is {@code false}, then a more
352   *                 lenient mode will be used.
353   */
354  public void setStrict(final boolean strict)
355  {
356    this.strict = strict;
357  }
358
359
360
361  /**
362   * Retrieves a string representation of this JSON-formatted control decode
363   * behavior.
364   *
365   * @return  A string representation of this JSON-formatted control decode
366   *          behavior.
367   */
368  @Override()
369  @NotNull()
370  public String toString()
371  {
372    final StringBuilder buffer = new StringBuilder();
373    toString(buffer);
374    return buffer.toString();
375  }
376
377
378
379  /**
380   * Appends a string representation of this JSON-formatted control decode
381   * behavior to the provided buffer.
382   *
383   * @param  buffer  The buffer to which the string representation should be
384   *                 appended.
385   */
386  public void toString(@NotNull final StringBuilder buffer)
387  {
388    buffer.append(
389         "JSONFormattedControlDecodeBehavior(throwOnUnparsableObject=");
390    buffer.append(throwOnUnparsableObject);
391    buffer.append(", throwOnInvalidCriticalControl=");
392    buffer.append(throwOnInvalidCriticalControl);
393    buffer.append(", throwOnInvalidNonCriticalControl=");
394    buffer.append(throwOnInvalidNonCriticalControl);
395    buffer.append(", allowEmbeddedJSONFormattedControl=");
396    buffer.append(allowEmbeddedJSONFormattedControl);
397    buffer.append(", strict=");
398    buffer.append(strict);
399    buffer.append(')');
400  }
401}