001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.commons.bean;
018
019import java.util.*;
020/**
021 * Minimum runtime surface that the bean-modeling layer needs from a marshalling session.
022 *
023 * <p>
024 * {@code BeanSession} is an SPI seam between the bean-modeling runtime (in {@code commons.bean}) and the
025 * marshalling stack (in {@code juneau-marshall}).  The marshalling layer's {@code MarshallingSession}
026 * implements this interface so the bean-modeling types (notably {@code BeanMap} and {@code BeanPropertyMeta})
027 * can request session-aware operations — type conversion, bean-map wrapping — without referencing any
028 * marshalling-aware concrete types.
029 *
030 * <p>
031 * On the commons-side construction path ({@code BeanMeta.of(Class, BeanConfigContext)}) the session is
032 * <jk>null</jk> and these operations are skipped; the bean-modeling code runs in raw-reflection mode.
033 *
034 * <h5 class='section'>Method parameter typing:</h5>
035 * <p>
036 * The {@code targetType} parameters are typed as {@link Object} because the marshalling layer expresses them
037 * as {@code ClassMeta<?>} — a marshalling-side type that {@code commons.bean} cannot reference.  Callers in
038 * the bean-modeling layer pass through whatever opaque type-metadata handle they received; the
039 * {@code MarshallingSession} implementation interprets it as a {@code ClassMeta}.
040 *
041 * <h5 class='topic'>Thread safety</h5>
042 * Thread safety depends on implementation.
043 *
044 * <h5 class='section'>See Also:</h5><ul>
045 *    <li class='ja'>{@link BeanConfigContext} — bean-modeling configuration counterpart.
046 * </ul>
047 */
048@SuppressWarnings({
049   "java:S1452" // parseToList() returns Collection<?> because the element type is not known to the caller.
050})
051public interface BeanSession {
052
053   /**
054    * Converts the specified value to the specified target type.
055    *
056    * <p>
057    * Implementations apply any registered conversions, swaps, or coercions necessary to produce a value
058    * compatible with {@code targetType}.  On the marshalling-side, this routes through
059    * {@code MarshallingSession.convertToType(Object, ClassMeta)}.
060    *
061    * @param value The value to convert.  May be <jk>null</jk>.
062    * @param targetType
063    *    The target type — typically a marshalling-side {@code ClassMeta<?>} handle passed through from
064    *    a {@code BeanPropertyMeta} or {@code BeanMap}.  Must not be <jk>null</jk>.
065    * @return The converted value.
066    */
067   Object convertToType(Object value, Object targetType);
068
069   /**
070    * Converts the specified value to the specified target type, instantiating non-static inner classes against
071    * an outer instance.
072    *
073    * @param outer The outer-class instance for non-static inner classes.  May be <jk>null</jk>.
074    * @param value The value to convert.  May be <jk>null</jk>.
075    * @param targetType The target type — typically a marshalling-side {@code ClassMeta<?>}.  Must not be <jk>null</jk>.
076    * @return The converted value.
077    */
078   Object convertToMemberType(Object outer, Object value, Object targetType);
079
080   /**
081    * Parses the specified JSON-formatted character sequence into a {@link Map}.
082    *
083    * <p>
084    * Used by {@code BeanPropertyMeta.setPropertyValue} when a {@link CharSequence} value is supplied for a
085    * {@code Map}-typed property — the bean-modeling layer cannot reference the marshalling-side JSON parser
086    * directly, so the parse is delegated to the session via this SPI.
087    *
088    * <p>
089    * Implementations typically route through {@code JsonMap.ofString(value).session(this)}.
090    *
091    * @param value The JSON-formatted character sequence to parse.  Must not be <jk>null</jk>.
092    * @return The parsed map.
093    */
094   Map<?,?> parseToMap(CharSequence value);
095
096   /**
097    * Parses the specified JSON-formatted character sequence into a {@link Collection}.
098    *
099    * <p>
100    * Used by {@code BeanPropertyMeta.setPropertyValue} when a {@link CharSequence} value is supplied for a
101    * {@code Collection}-typed property — the bean-modeling layer cannot reference the marshalling-side JSON
102    * parser directly, so the parse is delegated to the session via this SPI.
103    *
104    * <p>
105    * Implementations typically route through {@code new JsonList(value).setBeanSession(this)}.
106    *
107    * @param value The JSON-formatted character sequence to parse.  Must not be <jk>null</jk>.
108    * @return The parsed collection.
109    */
110   Collection<?> parseToList(CharSequence value);
111
112   /**
113    * Wraps the specified bean in a {@code BeanMap}.
114    *
115    * <p>
116    * Equivalent to {@code MarshallingSession.toBeanMap(Object)} on the marshalling-side.  The return type is
117    * typed as {@link Object} (rather than {@code BeanMap}) because the bean-modeling {@code BeanMap} runtime
118    * type currently lives in {@code juneau-marshall}; callers in {@code commons.bean} treat the returned value
119    * opaquely and pass it through to other {@code BeanSession} / bean-modeling APIs that re-narrow it.
120    *
121    * <p>
122    * The signature is generic to allow implementations (notably {@code MarshallingSession}) to satisfy this
123    * method with their existing covariant {@code <T> BeanMap<T> toBeanMap(T)} declaration without an
124    * additional bridge method.
125    *
126    * @param <T> The bean type.
127    * @param bean The bean to wrap.  Must not be <jk>null</jk>.
128    * @return A new bean map (typically a {@code BeanMap}) wrapping the supplied bean.
129    */
130   <T> Object toBeanMap(T bean);
131
132   /**
133    * Returns <jk>true</jk> if the specified bean property is visible under the current active view.
134    *
135    * <p>
136    * When no active view is set on the session, this method always returns <jk>true</jk> (all properties visible).
137    * The marshalling-side {@code MarshallingSession} overrides this to implement the actual view-membership check
138    * using the property's declared view set and the active view name.
139    *
140    * <p>
141    * Default-view-inclusion policy (configurable): an untagged property — one whose view set is empty — is
142    * considered in-view under every active view unless the
143    * {@code MarshallingContext.Builder.disableDefaultViewInclusion()} flag is set.
144    *
145    * @param pMeta The property metadata. Must not be <jk>null</jk>.
146    * @return <jk>true</jk> if the property should be included under the current active view.
147    */
148   default boolean isPropertyInActiveView(BeanPropertyMeta pMeta) {
149      return true; // HTT — default SPI method; MarshallingSession always overrides, so this body is unreachable in practice.
150   }
151}