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}