Class BeanMap<T>

java.lang.Object
java.util.AbstractMap<String,Object>
org.apache.juneau.commons.bean.BeanMap<T>
Type Parameters:
T - Specifies the type of object that this map encapsulates.
All Implemented Interfaces:
Map<String,Object>, Delegate<T>
Direct Known Subclasses:
DelegateBeanMap

public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T>
Java bean wrapper class.
Description
A wrapper that wraps Java bean instances inside of a Map interface that allows properties on the wrapped object can be accessed using the get() and put() methods.

Create instances through the bean API. For the bean-modeling-only path use of(Object) or of(Object, BeanMeta); the marshalling layer's MarshallingSession#toBeanMap(Object) additionally wires a BeanSession into the resulting map for session-aware behavior.

Bean property order
The order of the properties returned by the keySet() and entrySet() methods is as follows:
POJO swaps
If ObjectSwap transforms are defined on the class types of the properties of this bean or the bean properties themselves, the get(Object) and put(String, Object) methods will automatically transform the property value to and from the serialized form.
Thread safety
Instances are not thread-safe. This type is mutable (wrapped bean reference, property caches, and optional session pointer) and does not perform internal synchronization.
  • Field Details

    • bean

      protected T bean
      The wrapped object.
    • propertyCache

      Temporary holding cache for beans with read-only properties. Normally null.
    • arrayPropertyCache

      Temporary holding cache for bean properties of array types when the add() method is being used.
    • meta

      protected BeanMeta<T> meta
      The BeanMeta associated with the class of the object.
  • Constructor Details

    • BeanMap

      public BeanMap(T bean, BeanMeta<T> meta)
      Constructor.

      Bean-modeling-only constructor. Does not carry a BeanSession reference. The marshalling layer wires the session in via setBeanSession(BeanSession) immediately after construction.

      Parameters:
      bean - The bean to wrap inside this map. Can be null for a read-only bean whose properties are supplied later and instantiated via getBean().
      meta - The metadata associated with the bean class. Must not be null.
  • Method Details

    • of

      public static <T> BeanMap<T> of(T bean)
      Convenience method for wrapping a bean inside a BeanMap.
      Type Parameters:
      T - The bean type.
      Parameters:
      bean - The bean being wrapped. Must not be null (its runtime class is used to build the metadata).
      Returns:
      A new BeanMap instance wrapping the bean.
    • of

      public static <T> BeanMap<T> of(T bean, BeanMeta<T> meta)
      Convenience method for wrapping a bean inside a BeanMap using a pre-built BeanMeta.

      This is the bean-modeling entry point — it builds a BeanMap without going through a marshalling session, paired with a BeanMeta typically produced by BeanMeta.of(Class, BeanConfigContext). No marshalling session is attached.

      Type Parameters:
      T - The bean type.
      Parameters:
      bean - The bean being wrapped. Can be null for a read-only bean whose properties are supplied later and instantiated via getBean().
      meta - The bean metadata. Must not be null.
      Returns:
      A new BeanMap instance wrapping the bean.
    • getMissingRequiredProperties

      Returns the @BeanProp(required=true) properties that have not been written to this map.

      A property counts as written once put(String, Object) (or a collection add) has been called for it, even with a null value. Parsers call this once per bean, before the bean is constructed.

      Example:

      // MyBean has @BeanProp(required=true) on 'name' and 'zip'. BeanMap<MyBean> m = session.newBeanMap(MyBean.class); m.put("name", null); // [zip] List<String> missing = m.getMissingRequiredProperties();

      Returns:
      The missing required property names, in property order. Empty (never null) if none.
    • setBeanSession

      public void setBeanSession(BeanSession value)
      Wires this bean map to a BeanSession.

      Called by marshalling-side construction paths (for example, MarshallingSession#toBeanMap(Object)) to wire in the session used by session-aware operations (type conversion, child collection construction, and parser/serializer-backed conversions) after bean-modeling construction.

      Parameters:
      value - The bean session that produced this bean map. Typically a marshalling-session implementation. Can be null to detach the session.
    • add

      public void add(String property, Object value)
      Add a value to a collection or array property.

      As a general rule, adding to arrays is not recommended since the array must be recreate each time this method is called.

      Parameters:
      property - Property name or child-element name (if @Xml(childName) is specified).
      value - The value to add to the collection or array. Can be null.
    • containsKey

      public boolean containsKey(Object property)
      Specified by:
      containsKey in interface Map<String,Object>
      Overrides:
      containsKey in class AbstractMap<String,Object>
    • entrySet

      Returns all the properties associated with the bean.
      Specified by:
      entrySet in interface Map<String,Object>
      Specified by:
      entrySet in class AbstractMap<String,Object>
      Returns:
      A new set.
    • forEachProperty

      Performs an action on each property in this bean map.

      If a BeanSession is attached and has an active view, only properties that are visible under that view (as determined by BeanSession.isPropertyInActiveView(BeanPropertyMeta)) are visited.

      Parameters:
      filter - The filter to apply to properties.
      action - The action.
      Returns:
      This object.
    • isInActiveView

      protected boolean isInActiveView(BeanPropertyMeta pMeta)
      Returns true if the property is visible under the active view on this bean map's session.

      When no session is attached, or no active view is set, all properties are visible.

      Parameters:
      pMeta - The property to test.
      Returns:
      true if the property is in-view.
    • forEachValue

      public BeanMap<T> forEachValue(Predicate<Object> valueFilter, BeanPropertyConsumer action)
      Invokes all the getters on this bean and consumes the results.
      Parameters:
      valueFilter - Filter to apply to value before applying action.
      action - The action to perform.
      Returns:
      The list of all bean property values.
    • get

      public Object get(Object property)
      Gets a property on the bean.

      If an ObjectSwap-style transform is associated with this bean property or bean property type class, then this method will return the transformed value. For example, if the bean property type class is a Date and the bean property has the DateFormat.ISO_INSTANT setting associated with it through the @Swap(value) annotation, this method will return a String containing an ISO8601 date-time string value.

      Example:

      // Construct a bean with a 'birthDate' Date field Person person = new Person(); person.setBirthDate(new Date(1, 2, 3, 4, 5, 6)); // Create a marshalling context and add the ISO8601 date-time swap MarshallingContext marshallingContext = MarshallingContext.create().dateFormat(DateFormat.ISO_INSTANT).build(); // Wrap our bean in a bean map BeanMap<Person> beanMap = marshallingContext.toBeanMap(person); // Get the field as a string (i.e. "'1901-03-03T04:05:06-5000'") String birthDate = beanMap.get("birthDate");

      Specified by:
      get in interface Map<String,Object>
      Overrides:
      get in class AbstractMap<String,Object>
      Parameters:
      property - The name of the property to get.
      Returns:
      The property value.
      Throws:
      RuntimeException - if any of the following occur.
      1. BeanMapEntry does not exist on the underlying object.
      2. Security settings prevent access to the underlying object getter method.
      3. An exception occurred inside the getter method.
    • get

      public <T2> T2 get(String property, Class<T2> c)
      Same as get(Object) but casts the value to the specific type.
      Type Parameters:
      T2 - The type to cast to.
      Parameters:
      property - The name of the property to get.
      c - The type to cast to.
      Returns:
      The property value.
      Throws:
      RuntimeException - if any of the following occur.
      1. BeanMapEntry does not exist on the underlying object.
      2. Security settings prevent access to the underlying object getter method.
      3. An exception occurred inside the getter method.
      ClassCastException - if property is not the specified type.
    • getBean

      public T getBean()
      Returns the wrapped bean object.

      Triggers bean creation if bean has read-only properties set through a constructor defined by the @BeanCtor annotation.

      The post-creation Optional<X> initialization step (which seeds null Optional properties with BeanInfo.getOptionalDefault()) is skipped for properties built via the bean-modeling-only path (BeanMeta.of(Class, BeanConfigContext)) because per-property type metadata is unavailable; those properties are left untouched and any Optional-typed field stays at its constructor-assigned value.

      Returns:
      The inner bean object.
    • getBean

      public T getBean(boolean create)
      Returns the wrapped bean object.

      If create is false, then this method may return null if the bean has read-only properties set through a constructor defined by the @BeanCtor annotation.

      This method does NOT always return the bean in it's final state. Array properties temporary stored as ArrayLists are not finalized until the getBean() method is called.

      Parameters:
      create - If bean hasn't been instantiated yet, then instantiate it.
      Returns:
      The inner bean object.
    • getBeanSession

      public final BeanSession getBeanSession()
      Returns the bean session that created this bean map.

      The returned value is the bean-modeling SPI seam. Marshalling-side callers needing the concrete marshalling-session implementation can cast — every session wired in via setBeanSession(BeanSession) on the marshalling-side path is currently a MarshallingSession.

      Returns:
      The bean session that created this bean map.
    • getBeanInfo

      public BeanInfo<T> getBeanInfo()
      Returns the BeanInfo of the wrapped bean.
      Specified by:
      getBeanInfo in interface Delegate<T>
      Returns:
      The class type of the wrapped bean.
    • getMeta

      public BeanMeta<T> getMeta()
      Returns the metadata associated with this bean map.
      Returns:
      The metadata associated with this bean map.
    • getProperties

      public Map<String,Object> getProperties(String... fields)
      Extracts the specified field values from this bean and returns it as a simple Map.

      The returned map is a live view over this bean map: each entry's getValue reads through to BeanMap.get and setValue writes through to BeanMap.put. Unknown fields (keys not present in this bean map) are silently skipped.

      Parameters:
      fields - The fields to extract.
      Returns:
      A new map with fields as key-value pairs.
      Note that modifying the values in this map will also modify the underlying bean.
    • getProperty

      public BeanMapEntry getProperty(String propertyName)
      Returns the specified property on this bean map.

      Allows you to get and set an individual property on a bean without having a handle to the bean itself by using the BeanMapEntry.getValue() and BeanMapEntry.setValue(Object) methods.

      This method can also be used to get metadata on a property by calling the BeanMapEntry.getMeta() method.

      Parameters:
      propertyName - The name of the property to look up.
      Returns:
      The bean property, or null if the bean has no such property.
    • getPropertyMeta

      public BeanPropertyMeta getPropertyMeta(String propertyName)
      Returns the metadata on the specified property.

      Returns null if the property does not exist on the bean or if the property exists but is excluded by the current active view. The latter allows the caller (e.g. put(String, Object)) to route out-of-view input through the existing unknown/ignored-property path governed by BeanConfigContext.isIgnoreUnknownBeanProperties().

      Parameters:
      propertyName - The name of the bean property.
      Returns:
      Metadata on the specified property, or null if that property does not exist or is out of view.
    • getRaw

      public Object getRaw(Object property)
      Same as get(Object) except bypasses any ObjectSwap associated with the bean property or BeanFilter associated with the bean class.
      Parameters:
      property - The name of the property to get.
      Returns:
      The raw property value.
    • keySet

      public Set<String> keySet()
      Returns the names of all properties associated with the bean.

      The returned set is unmodifiable.

      Specified by:
      keySet in interface Map<String,Object>
      Overrides:
      keySet in class AbstractMap<String,Object>
    • load

      public BeanMap<T> load(Map entries)
      Convenience method for loading this map with the contents of the specified map.

      Identical to AbstractMap.putAll(Map) except as a fluent-style method.

      Parameters:
      entries - The map containing the entries to add to this map.
      Returns:
      This object.
    • put

      public Object put(String property, Object value)
      Sets a property on the bean.

      If there is a ObjectSwap associated with this bean property or bean property type class, then you must pass in a transformed value. For example, if the bean property type class is a Date and the bean property has the DateFormat.ISO_INSTANT setting associated with it through the @Swap(value) annotation, the value being passed in must be a String containing an ISO8601 date-time string value.

      Example:

      // Construct a bean with a 'birthDate' Date field Person person = new Person(); // Create a marshalling context and add the ISO8601 date-time swap MarshallingContext marshallingContext = MarshallingContext.create().dateFormat(DateFormat.ISO_INSTANT).build(); // Wrap our bean in a bean map BeanMap<Person> beanMap = marshallingContext.toBeanMap(person); // Set the field beanMap.put("birthDate", "'1901-03-03T04:05:06-5000'");

      Specified by:
      put in interface Map<String,Object>
      Overrides:
      put in class AbstractMap<String,Object>
      Parameters:
      property - The name of the property to set.
      value - The value to set the property to. Can be null to set the property to null.
      Returns:
      If the beanMapPutReturnsOldValue setting is true on the session's bean configuration, then the old value of the property is returned. Otherwise, this method always returns null.
      Throws:
      RuntimeException - if any of the following occur.
      • BeanMapEntry does not exist on the underlying object.
      • Security settings prevent access to the underlying object setter method.
      • An exception occurred inside the setter method.
    • resolveVars

      Given a string containing variables of the form "{property}", replaces those variables with property values in this bean.
      Parameters:
      s - The string containing variables.
      Returns:
      A new string with variables replaced, or the same string if no variables were found.
    • getProperties

      Returns a simple collection of properties for this bean map.
      Returns:
      A simple collection of properties for this bean map.
    • equals

      public boolean equals(Object o)
      Compares the specified object with this map for equality.

      Returns true if the given object is also a map and the two maps represent the same mappings. More formally, two maps m1 and m2 represent the same mappings if m1.entrySet().equals(m2.entrySet()).

      This implementation compares the entry sets of the two maps.

      Specified by:
      equals in interface Map<String,Object>
      Overrides:
      equals in class AbstractMap<String,Object>
      Parameters:
      o - Object to be compared for equality with this map.
      Returns:
      true if the specified object is equal to this map.
    • hashCode

      public int hashCode()
      Returns the hash code value for this map.

      The hash code of a map is defined to be the sum of the hash codes of each entry in the map's entrySet() view. This ensures that m1.equals(m2) implies that m1.hashCode()==m2.hashCode() for any two maps m1 and m2, as required by the general contract of Object.hashCode().

      This implementation computes the hash code from the entry set.

      Specified by:
      hashCode in interface Map<String,Object>
      Overrides:
      hashCode in class AbstractMap<String,Object>
      Returns:
      The hash code value for this map.