001package Torello.Browser.JsonAST; 002 003import Torello.JavaDoc.Annotations.LinkJavaSource; 004import Torello.JavaDoc.Annotations.JDHeaderBackgroundImg; 005 006import Torello.Java.ReadOnly.ReadOnlyList; 007import Torello.Java.ReadOnly.ReadOnlySet; 008import Torello.Java.ReadOnly.ReadOnlyTreeSet; 009import Torello.JSON.ReadJSON; 010 011import javax.json.JsonObject; 012 013import java.util.Objects; 014 015// Class TCE is used to parse JSON Object Arrays of three varieties. The first, 'types' define 016// Java-Script Object-Classes that are returned from Java Script functions, and passed as 017// parameters to Java-Script functions. The second kind of 'TCE' (the letter 'C' in 'TCE' are 018// 'commands'. These specify the Java-Script functions themselves. The 'E' in this acronym means 019// 'events'. The events describe the parameters that are passed to Java Script Event Handlers. 020// 021/** 022 * An Java Object used within AST to symbolize or encapsulate the data present in any of the 023 * {@link JsonObject JsonObject's} found within a {@link Domain Domain's} {@code "commands"} array. 024 * <EMBED CLASS='external-html' DATA-FILE-ID=AST_TREES> 025 */ 026@JDHeaderBackgroundImg(EmbedTagFileID="AST_NODES_JDHBI") 027public class CommandNode extends TCE implements java.io.Serializable 028{ 029 // ******************************************************************************************** 030 // ******************************************************************************************** 031 // STATIC FINAL FIELDS 032 // ******************************************************************************************** 033 // ******************************************************************************************** 034 035 036 // Required by the Serializable interface 037 protected static final long serialVersionUID = 1; 038 039 /** 040 * The list of additional {@link JsonObject} properties that the parser should expect when 041 * parsing {@code CommandNode} objects from the JSON CDP specification files. 042 */ 043 protected static final ReadOnlySet<String> COMMAND_JSON_PROPERTIES_SET = 044 new ReadOnlyTreeSet<>(String::compareTo, "name", "parameters", "returns", "redirect"); 045 046 047 // ******************************************************************************************** 048 // ******************************************************************************************** 049 // Constant & Final Instance-Fields (Set by the Constructor) 050 // ******************************************************************************************** 051 // ******************************************************************************************** 052 053 054 /** 055 * This field contains the raw {@code String} value of the {@code "redirect"} Json Property. 056 * <EMBED CLASS='external-html' DATA-FILE-ID=CommandNode.redirect> 057 */ 058 public final String redirect; 059 060 /** 061 * Flag which indicates whether the CDP Command represented by this node returns multiple 062 * values, which therefore necessitates a dedicated inner type to represesnt those return 063 * values. 064 * 065 * <EMBED CLASS='external-html' DATA-FILE-ID=CommandNode.hasReifiedRetInnerClass> 066 */ 067 public final boolean hasReifiedRetInnerClass; 068 069 /** 070 * A {@link PPR} list which, during the Code Generator Phase, is translated into the input 071 * parameters for the Java Method which ultimately materializes and implements this CDP 072 * Command. 073 * 074 * <EMBED CLASS='external-html' DATA-FILE-ID=CommandNode.parameters> 075 */ 076 public final ReadOnlyList<PPR> parameters; 077 078 /** 079 * A {@link PPR} list which, during the Code Generator Phase, is translated into the output 080 * return values of the Java Method which ultimately materializes and implements this CDP 081 * Command. 082 * 083 * <EMBED CLASS='external-html' DATA-FILE-ID=CommandNode.returns> 084 */ 085 public final ReadOnlyList<PPR> returns; 086 087 088 // ******************************************************************************************** 089 // ******************************************************************************************** 090 // Non-Final Instance-Fields: These are initialized **LATE**, by the Linker 091 // ******************************************************************************************** 092 // ******************************************************************************************** 093 094 095 /** 096 * This method retrieves the value of a {@code private} field which isn't assigned inside of 097 * the constructor, but rather during the Linking Phase, and is therefore not declared 098 * {@code final}. 099 * 100 * <EMBED CLASS='external-html' DATA-FILE-ID=CommandNode.redirectDomain> 101 */ 102 public Domain redirectDomain() { return redirectDomain; } 103 private Domain redirectDomain = null; 104 105 // API-Invisible, Packge-Private Method: The Linker uses this, and sets the "Redirect Domain" 106 void setRedirectDomain(final Domain redirectDomain) 107 { this.redirectDomain = redirectDomain; } 108 109 110 // ******************************************************************************************** 111 // ******************************************************************************************** 112 // Constructor 113 // ******************************************************************************************** 114 // ******************************************************************************************** 115 116 117 // Constructs a class that represents a Java-Script 'type', 'command' or 'event' 118 CommandNode( 119 // The domain to which this 'type', 'command' or 'event' belongs 120 final Domain ownerDomain, 121 122 // The JSON Object representation of this 'TCE' 123 final JsonObject jo, 124 125 // The JSON Array index from which this JSON Object was retrieved. 126 final int index 127 ) 128 { 129 super( 130 ownerDomain, 131 jo, 132 WhichTCE.Command, 133 COMMAND_JSON_PROPERTIES_SET, 134 index 135 ); 136 137 // getString(JsonObject jo, String propertyName, boolean isOptional, boolean throwOnNull) 138 this.redirect = ReadJSON.getString(jo, "redirect", true, true); 139 140 this.parameters = Helper$GetPPRLists.get(this, jo, WhichPPR.Parameter); 141 this.returns = Helper$GetPPRLists.get(this, jo, WhichPPR.Return); 142 143 // This is the decision: multiple return values necessitates a dedicated inner class 144 this.hasReifiedRetInnerClass = (this.returns != null) && (this.returns.size() > 1); 145 146 147 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 148 // CommandNode → **MAY NOT** have a "type" JsonProperty ==> 100% pass / TRUE / invariant 149 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 150 151 if (this.typeProp != null) 152 verifyThrow("CommandNode TCE illegally declares a \"type\" Json property."); 153 154 // This check is IDENTICAL to (a subset of) the previous check. Just here to remind you 155 if (this.arrItemsTypeProp != null) 156 verifyThrow("This has an array field, but it is a CommandNode TCE"); 157 158 if (this.enumVals != null) 159 verifyThrow("CommandNode TCE illegally declares an \"enum\" Json property."); 160 } 161 162 163 // ******************************************************************************************** 164 // ******************************************************************************************** 165 // to string 166 // ******************************************************************************************** 167 // ******************************************************************************************** 168 169 170 /** Returns a {@code String} representation of {@code 'this'} instance. */ 171 @LinkJavaSource(handle="StringTCE") 172 public String toString() 173 { return StringTCE.get(this); } 174}