All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.BeanTraverseContext Maven / Gradle / Ivy

There is a newer version: 9.0.1
Show newest version
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau;


import org.apache.juneau.parser.*;

/**
 * Parent class for all classes that traverse POJOs.
 *
 * 
Description
* * Base class that serves as the parent class for all serializers and other classes that traverse POJOs. */ public abstract class BeanTraverseContext extends BeanContext { //------------------------------------------------------------------------------------------------------------------- // Configurable properties //------------------------------------------------------------------------------------------------------------------- private static final String PREFIX = "BeanTraverseContext."; /** * Configuration property: Automatically detect POJO recursions. * *
Property:
*
    *
  • Name: "BeanTraverseContext.detectRecursions.b" *
  • Data type: Boolean *
  • Default: false *
  • Session property: false *
  • Methods: *
      *
    • {@link BeanTraverseBuilder#detectRecursions(boolean)} *
    • {@link BeanTraverseBuilder#detectRecursions()} *
    *
* *
Description:
*

* Specifies that recursions should be checked for during traversal. * *

* Recursions can occur when traversing models that aren't true trees but rather contain loops. *
In general, unchecked recursions cause stack-overflow-errors. *
These show up as {@link ParseException ParseExceptions} with the message "Depth too deep. Stack overflow occurred.". * *

* The behavior when recursions are detected depends on the value for {@link #BEANTRAVERSE_ignoreRecursions}. * *

* For example, if a model contains the links A->B->C->A, then the JSON generated will look like * the following when BEANTRAVERSE_ignoreRecursions is true... * *

* {A:{B:{C:null}}} *

* *
Notes:
*
    *
  • * Checking for recursion can cause a small performance penalty. *
* *
Example:
*

* // Create a serializer that never adds _type to nodes. * WriterSerializer s = JsonSerializer * .create() * .detectRecursions() * .ignoreRecursions() * .build(); * * // Same, but use property. * WriterSerializer s = JsonSerializer * .create() * .set(BEANTRAVERSE_detectRecursions, true) * .set(BEANTRAVERSE_ignoreRecursions, true) * .build(); * * // Create a POJO model with a recursive loop. * public class A { * public Object f; * } * A a = new A(); * a.f = a; * * // Produces "{f:null}" * String json = s.serialize(a); *

*/ public static final String BEANTRAVERSE_detectRecursions = PREFIX + "detectRecursions.b"; /** * Configuration property: Ignore recursion errors. * *
Property:
*
    *
  • Name: "BeanTraverseContext.ignoreRecursions.b" *
  • Data type: Boolean *
  • Default: false *
  • Session property: false *
  • Methods: *
      *
    • {@link BeanTraverseBuilder#ignoreRecursions(boolean)} *
    • {@link BeanTraverseBuilder#ignoreRecursions()} *
    *
* *
Description:
*

* Used in conjunction with {@link #BEANTRAVERSE_detectRecursions}. *
Setting is ignored if BEANTRAVERSE_detectRecursions is false. * *

* If true, when we encounter the same object when traversing a tree, we set the value to null. *
Otherwise, a {@link BeanRecursionException} is thrown with the message "Recursion occurred, stack=...". */ public static final String BEANTRAVERSE_ignoreRecursions = PREFIX + "ignoreRecursions.b"; /** * Configuration property: Initial depth. * *

Property:
*
    *
  • Name: "BeanTraverseContext.initialDepth.i" *
  • Data type: Integer *
  • Default: 0 *
  • Session property: false *
  • Methods: *
      *
    • {@link BeanTraverseBuilder#initialDepth(int)} *
    *
* *
Description:
*

* The initial indentation level at the root. *
Useful when constructing document fragments that need to be indented at a certain level. * *

Example:
*

* // Create a serializer with whitespace enabled and an initial depth of 2. * WriterSerializer s = JsonSerializer * .create() * .ws() * .initialDepth(2) * .build(); * * // Same, but use property. * WriterSerializer s = JsonSerializer * .create() * .set(BEANTRAVERSE_useWhitespace, true) * .set(BEANTRAVERSE_initialDepth, 2) * .build(); * * // Produces "\t\t{\n\t\t\t'foo':'bar'\n\t\t}\n" * String json = s.serialize(new MyBean()); *

*/ public static final String BEANTRAVERSE_initialDepth = PREFIX + "initialDepth.i"; /** * Configuration property: Max traversal depth. * *
Property:
*
    *
  • Name: "BeanTraverseContext.maxDepth.i" *
  • Data type: Integer *
  • Default: 100 *
  • Session property: false *
  • Methods: *
      *
    • {@link BeanTraverseBuilder#maxDepth(int)} *
    *
* *
Description:
*

* Abort traversal if specified depth is reached in the POJO tree. *
If this depth is exceeded, an exception is thrown. * *

Example:
*

* // Create a serializer that throws an exception if the depth is greater than 20. * WriterSerializer s = JsonSerializer * .create() * .maxDepth(20) * .build(); * * // Same, but use property. * WriterSerializer s = JsonSerializer * .create() * .set(BEANTRAVERSE_maxDepth, 20) * .build(); *

*/ public static final String BEANTRAVERSE_maxDepth = PREFIX + "maxDepth.i"; //------------------------------------------------------------------------------------------------------------------- // Instance //------------------------------------------------------------------------------------------------------------------- private final int initialDepth, maxDepth; private final boolean detectRecursions, ignoreRecursions; /** * Constructor * * @param ps * The property store containing all the settings for this object. */ protected BeanTraverseContext(PropertyStore ps) { super(ps); maxDepth = getIntegerProperty(BEANTRAVERSE_maxDepth, 100); initialDepth = getIntegerProperty(BEANTRAVERSE_initialDepth, 0); detectRecursions = getBooleanProperty(BEANTRAVERSE_detectRecursions, false); ignoreRecursions = getBooleanProperty(BEANTRAVERSE_ignoreRecursions, false); } @Override /* Context */ public BeanTraverseBuilder builder() { return null; } @Override /* Context */ public BeanTraverseSession createSession(BeanSessionArgs args) { return new BeanTraverseSession(this, args); } //----------------------------------------------------------------------------------------------------------------- // Properties //----------------------------------------------------------------------------------------------------------------- /** * Configuration property: Initial depth. * * @see #BEANTRAVERSE_initialDepth * @return * The initial indentation level at the root. */ protected final int getInitialDepth() { return initialDepth; } /** * Configuration property: Max traversal depth. * * @see #BEANTRAVERSE_maxDepth * @return * The depth at which traversal is aborted if depth is reached in the POJO tree. *
If this depth is exceeded, an exception is thrown. */ protected final int getMaxDepth() { return maxDepth; } /** * Configuration property: Automatically detect POJO recursions. * @see #BEANTRAVERSE_detectRecursions * @return * true if recursions should be checked for during traversal. */ protected final boolean isDetectRecursions() { return detectRecursions; } /** * Configuration property: Ignore recursion errors. * * @see #BEANTRAVERSE_ignoreRecursions * @return * true if when we encounter the same object when traversing a tree, we set the value to null. *
Otherwise, an exception is thrown with the message "Recursion occurred, stack=...". */ protected final boolean isIgnoreRecursions() { return ignoreRecursions; } @Override /* Context */ public ObjectMap asMap() { return super.asMap() .append("BeanTraverseContext", new ObjectMap() .append("maxDepth", maxDepth) .append("initialDepth", initialDepth) .append("detectRecursions", detectRecursions) .append("ignoreRecursions", ignoreRecursions) ); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy