001package Torello.Browser; 002 003import static Torello.Java.StrPrint.I4; 004 005import Torello.Java.ReadOnly.ReadOnlyList; 006 007import java.util.Objects; 008import java.util.TreeMap; 009 010import javax.json.JsonObject; 011 012/** 013 * Reflected information / data which has been extracted from one of the nested CDP types declared 014 * inside a generated domain class. 015 * 016 * <BR /><BR /> 017 * A "Nested Type" is any CDP data-class, event-class, or command-return class that is generated as 018 * an inner class of one of the primary browser domain classes. For example: 019 * 020 * <BR /><BR /> 021 * <B><CODE>{@link Torello.Browser.BrowserAPI.Animation.AnimationEffect}</CODE></B> 022 * 023 * <BR /><BR /> 024 * is a nested type declared inside the {@code Animation} domain class. Its corresponding 025 * {@code NestedDescriptor} singleton is created and stored inside that type's generated helper 026 * class: 027 * 028 * <BR /><BR /> 029 * <B><CODE><A HREF='BrowserAPI/hilite-files/Animation$$AnimationEffect$$.java.html'> 030 * Animation$$AnimationEffect$$</A></CODE></B> 031 * 032 * <BR /><BR /> 033 * The descriptor stores the field names, CDP type constants, optional-field flags, 034 * experimental-field flags, and the concrete Java {@link Class} represented by the nested type. 035 * This metadata is used by reflection-based tools such as {@link TypeBuilder}, JSON parsers, and 036 * generated helper classes. 037 * 038 * @param <DOMAIN_NESTED> The concrete nested CDP type described by this descriptor. 039 */ 040public class NestedDescriptor<DOMAIN_NESTED extends BaseType<DOMAIN_NESTED>> 041 extends AbstractDescriptor 042 implements java.io.Serializable 043{ 044 // ******************************************************************************************** 045 // ******************************************************************************************** 046 // Fields 047 // ******************************************************************************************** 048 // ******************************************************************************************** 049 050 051 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 052 protected static final long serialVersionUID = 1L; 053 054 /** 055 * This just keeps a pointer / reference back to the actual {@code java.lang.Class} which is 056 * described by this "Nested Descriptor." 057 * 058 * <BR /><BR /><DIV CLASS=JDHint> 059 * In the JDK, it is sometimes stated that "reifying generic types" could conceivably have 060 * a value to the end user. The only purpose of this field is to do just that, "reify" the 061 * Type Parameter represented by {@code 'DOMAIN_NESTED'}. 062 * </DIV> 063 */ 064 public final Class<DOMAIN_NESTED> baseTypeClass; 065 066 // This package-private field is used by the "TypeBuilder" class's "build()" method 067 transient java.lang.reflect.Constructor<DOMAIN_NESTED> ctor = null; 068 069 070 // ******************************************************************************************** 071 // ******************************************************************************************** 072 // Constructor & toString 073 // ******************************************************************************************** 074 // ******************************************************************************************** 075 076 077 /** 078 * This is a public constructor, but it's primarily intended for internal use. 079 * 080 * <!-- NOTE: Chat-GPT wrote these "Single Line Summaries!" Pretty nifty... --> 081 * 082 * @param name The name of the CDP type described by this descriptor. 083 * @param domain The Browser Domain containing the described CDP type. 084 * @param names Parallel list of CDP property names. 085 * @param types Parallel list of {@link CDPTypes CDP Type Constants}. 086 * @param optionals Parallel list indicating which properties are {@code optional}. 087 * @param experimentals Parallel list indicating which properties are {@code experimental}. 088 * @param baseTypeClass The concrete Java {@code Class} represented by this descriptor. 089 */ 090 public NestedDescriptor( 091 final Domains domain, 092 final String name, 093 final ReadOnlyList<String> names, 094 final ReadOnlyList<Byte> types, 095 final ReadOnlyList<Boolean> optionals, 096 final ReadOnlyList<Boolean> experimentals, 097 final Class<DOMAIN_NESTED> baseTypeClass 098 ) 099 { 100 super(name, domain, names, types, optionals, experimentals); 101 Objects.requireNonNull(baseTypeClass, "Constructor parameter 'baseTypeClass' is null"); 102 this.baseTypeClass = baseTypeClass; 103 } 104 105 /** 106 * Generates a reasonable {@code String} representation of {@code 'this'} instance. 107 * @return A Java {@code String} 108 */ 109 @Override 110 public String toString() 111 { 112 return 113 "NestedDescriptor:\n" + 114 "{\n" + 115 super.toString() + 116 '\n' + 117 I4 + "baseTypeClass: " + this.baseTypeClass.getCanonicalName() + '\n' + 118 "}\n"; 119 } 120 121 122 // ******************************************************************************************** 123 // ******************************************************************************************** 124 // Package-Private Reflection Methods 125 // ******************************************************************************************** 126 // ******************************************************************************************** 127 128 129 // Allows the TypeBuilder to verify if a user has passed a valid class 130 Class<?> getClass(final String name, final int index) 131 { 132 final java.lang.reflect.Field field; 133 134 try 135 { field = baseTypeClass.getField(name); } 136 137 catch (NoSuchFieldException | SecurityException e) 138 { throw new Error("Exception retrieving field [" + name + ']', e); } 139 140 if (field == null) throw new Error( 141 "Class " + baseTypeClass.getCanonicalName() + " did not contain a field " + 142 "named: " + name 143 ); 144 145 return field.getType(); 146 } 147}