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<T>} 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}