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.lang.reflect.*;
020import java.util.*;
021
022import org.apache.juneau.commons.reflect.*;
023
024/**
025 * Bean-modeling SPI seam that exposes the type-classification surface the bean-runtime types
026 * ({@link BeanMeta}-equivalents, {@link BeanPropertyMeta}-equivalents, etc.) need without coupling
027 * the bean-modeling layer to the marshalling-side {@code ClassMeta}.
028 *
029 * <p>
030 * Marshalling-side {@code ClassMeta&lt;T&gt;} extends this class; bean-modeling-side code only sees
031 * {@link BeanInfo}.  The bean-modeling-side never instantiates this class directly — it always
032 * gets instances handed in by the marshalling layer (e.g. via builder calls like
033 * {@code BeanPropertyMeta.Builder#rawMetaType(ClassMeta)}).
034 *
035 * <p>
036 * All extra abstract methods declared here mirror methods that {@code ClassMeta} already implements,
037 * so {@code ClassMeta} satisfies this contract by virtue of its existing implementation.
038 *
039 * <h5 class='topic'>Thread safety</h5>
040 * Thread safety depends on implementation.
041 *
042 * @param <T> The raw class type this instance represents.
043 */
044@SuppressWarnings({
045   "java:S1452" // getElementType(), getKeyType() and getValueType() intentionally return BeanInfo<?> because the component types are unknown statically.
046})
047public abstract class BeanInfo<T> extends ClassInfoTyped<T> {
048
049   /**
050    * Constructor.
051    *
052    * @param inner The class type.
053    */
054   protected BeanInfo(Class<T> inner) {
055      super(inner);
056   }
057
058   /**
059    * Constructor.
060    *
061    * @param inner The class type.
062    * @param innerType The generic type (if parameterized type).
063    */
064   protected BeanInfo(Class<T> inner, Type innerType) {
065      super(inner, innerType);
066   }
067
068   /**
069    * Returns <jk>true</jk> if this class is a URI/URL or annotated with a URI marker.
070    *
071    * @return <jk>true</jk> if this class is a URI.
072    */
073   public abstract boolean isUri();
074
075   /**
076    * Returns <jk>true</jk> if this class is classified as a bean.
077    *
078    * @return <jk>true</jk> if this class is a bean.
079    */
080   public abstract boolean isBean();
081
082   /**
083    * For array and {@code Collection} types, returns the type info of the element type, or <jk>null</jk>
084    * if this is not an array/collection.
085    *
086    * @return The element type info, or <jk>null</jk>.
087    */
088   public abstract BeanInfo<?> getElementType();
089
090   /**
091    * For {@code Map} types, returns the type info of the key type, or <jk>null</jk> if this is not a map.
092    *
093    * @return The key type info, or <jk>null</jk>.
094    */
095   public abstract BeanInfo<?> getKeyType();
096
097   /**
098    * For {@code Map} types, returns the type info of the value type, or <jk>null</jk> if this is not a map.
099    *
100    * @return The value type info, or <jk>null</jk>.
101    */
102   public abstract BeanInfo<?> getValueType();
103
104   /**
105    * Returns <jk>true</jk> if this class can be instantiated using a no-arg constructor.
106    *
107    * @return <jk>true</jk> if a new instance can be created.
108    */
109   public abstract boolean canCreateNewInstance();
110
111   /**
112    * Returns <jk>true</jk> if this class can be instantiated, optionally with the specified outer object
113    * for non-static inner classes.
114    *
115    * @param outer The outer object instance, or <jk>null</jk> if not applicable.
116    * @return <jk>true</jk> if a new instance can be created.
117    */
118   public abstract boolean canCreateNewInstance(Object outer);
119
120   /**
121    * Creates a new instance of this class.
122    *
123    * @return A new instance of the class.
124    * @throws ExecutableException If the class could not be instantiated.
125    */
126   @Override /* Overridden from ClassInfo to narrow return type to T. */
127   public abstract T newInstance() throws ExecutableException;
128
129   /**
130    * For {@link Optional} types, returns an empty optional default value, or <jk>null</jk>
131    * if this isn't an Optional.
132    *
133    * <p>
134    * Returns {@link Object} rather than {@code T} because the marshalling-side {@code ClassMeta} returns
135    * a wildcard {@code Optional<?>} which is not assignable to {@code T} under Java's type system.
136    *
137    * @return The default empty Optional value, or <jk>null</jk>.
138    */
139   public abstract Object getOptionalDefault();
140
141   /**
142    * Returns the {@link BeanConfigContext} associated with this type-info.
143    *
144    * <p>
145    * On the marshalling-side this returns the bean-modeling subset of the {@code MarshallingContext} that
146    * carried this type-info; on commons-side {@link BeanInfo} construction paths (none exist in-tree currently;
147    * {@link BeanInfo} is currently always realized by marshalling-side {@code ClassMeta}),
148    * this should return the {@code BeanConfigContext} the type-info was built against.
149    *
150    * @return The bean-modeling configuration carried alongside this type-info.  Never <jk>null</jk>.
151    */
152   public abstract BeanConfigContext getBeanConfigContext();
153
154   /**
155    * Returns the marshalling-side context associated with this type-info, as an opaque {@link Object}.
156    *
157    * <p>
158    * On the marshalling-side this is the {@code MarshallingContext} that carried this type-info; the return
159    * type is widened to {@link Object} so callers in {@code commons.bean} do not need to import
160    * {@code MarshallingContext}.  Callers cast to the marshalling-side type at the use site.
161    *
162    * @return The marshalling context, or <jk>null</jk> if none is associated with this type-info.
163    */
164   public abstract Object getMarshallingContext();
165}