001package Torello.Browser.JavaScriptAPI;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Browser.BrowserEvent;
013import Torello.Browser.BrowserAPI.*;
014import Torello.Browser.helper.*;
015
016import Torello.Java.Additional.*;
017import Torello.Java.JSON.*;
018
019import static Torello.Java.JSON.JFlag.*;
020
021import Torello.Java.StrCmpr;
022import Torello.JavaDoc.StaticFunctional;
023import Torello.JavaDoc.JDHeaderBackgroundImg;
024import Torello.JavaDoc.Excuse;
025
026/**
027 * <SPAN CLASS=COPIEDJDK><B>This domain is deprecated.</B></SPAN>
028 * 
029 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
030 */
031@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
032@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
033public class Schema
034{
035    // ********************************************************************************************
036    // ********************************************************************************************
037    // Class Header Stuff
038    // ********************************************************************************************
039    // ********************************************************************************************
040
041
042    // No Pubic Constructors
043    private Schema () { }
044
045    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
046    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
047    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
048    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
049
050    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
051    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
052    // offically, two empty-vectors.  One for String's, and the other for Classes.
053
054    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
055    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
056
057    static
058    {
059        for (Method m : Schema.class.getMethods())
060        {
061            // This doesn't work!  The parameter names are all "arg0" ... "argN"
062            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
063            //
064            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
065
066            Vector<Class<?>> parameterTypesList = new Vector<>();
067        
068            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
069
070            parameterTypes.put(
071                m.getName(),
072                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
073            );
074        }
075    }
076
077    static
078    {
079        Vector<String> v = null;
080
081        parameterNames.put("getDomains", EMPTY_VEC_STR);
082    }
083
084
085    // ********************************************************************************************
086    // ********************************************************************************************
087    // Types - Static Inner Classes
088    // ********************************************************************************************
089    // ********************************************************************************************
090
091    /** Description of the protocol domain. */
092    public static class Domain
093        extends BaseType
094        implements java.io.Serializable
095    {
096        /** For Object Serialization.  java.io.Serializable */
097        protected static final long serialVersionUID = 1;
098        
099        public boolean[] optionals()
100        { return new boolean[] { false, false, }; }
101        
102        /** Domain name. */
103        public final String name;
104        
105        /** Domain version. */
106        public final String version;
107        
108        /**
109         * Constructor
110         *
111         * @param name Domain name.
112         * 
113         * @param version Domain version.
114         */
115        public Domain(String name, String version)
116        {
117            // Exception-Check(s) to ensure that if any parameters which are not declared as
118            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
119            
120            if (name == null)    THROWS.throwNPE("name");
121            if (version == null) THROWS.throwNPE("version");
122            
123            this.name     = name;
124            this.version  = version;
125        }
126        
127        /**
128         * JSON Object Constructor
129         * @param jo A Json-Object having data about an instance of {@code 'Domain'}.
130         */
131        public Domain (JsonObject jo)
132        {
133            this.name     = ReadJSON.getString(jo, "name", false, true);
134            this.version  = ReadJSON.getString(jo, "version", false, true);
135        }
136        
137        
138        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
139        public boolean equals(Object other)
140        {
141            if (this == other)                       return true;
142            if (other == null)                       return false;
143            if (other.getClass() != this.getClass()) return false;
144        
145            Domain o = (Domain) other;
146        
147            return
148                    Objects.equals(this.name, o.name)
149                &&  Objects.equals(this.version, o.version);
150        }
151        
152        /** Generates a Hash-Code for {@code 'this'} instance */
153        public int hashCode()
154        {
155            return
156                    Objects.hashCode(this.name)
157                +   Objects.hashCode(this.version);
158        }
159    }
160    
161    
162    // Counter for keeping the WebSocket Request ID's distinct.
163    private static int counter = 1;
164    
165    /**
166     * Returns supported domains.
167     * 
168     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
169     * {@link Schema.Domain}[]&gt;</CODE>
170     * 
171     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
172     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
173     * {@link Schema.Domain}[]&gt;</CODE> will be returned.
174     *
175     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
176     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
177      * may be retrieved.</I>
178     *
179     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
180     * <BR /><BR /><UL CLASS=JDUL>
181     * <LI><CODE>{@link Schema.Domain}[] (<B>domains</B></CODE>)
182     *     <BR />List of supported domains.
183     * </LI>
184     * </UL> */
185    public static Script<String, JsonObject, Schema.Domain[]> getDomains()
186    {
187        final int          webSocketID = 6000000 + counter++;
188        final boolean[]    optionals   = new boolean[0];
189        
190        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
191        String requestJSON = WriteJSON.get(
192            parameterTypes.get("getDomains"),
193            parameterNames.get("getDomains"),
194            optionals, webSocketID,
195            "Schema.getDomains"
196        );
197        
198        // 'JSON Binding' ... Converts Browser Response-JSON to 'Schema.Domain[]'
199        Function<JsonObject, Schema.Domain[]> responseProcessor = (JsonObject jo) ->
200            (jo.getJsonArray("domains") == null)
201                ? null
202                : RJArrIntoStream.objArr(jo.getJsonArray("domains"), null, 0, Schema.Domain.class).toArray(Schema.Domain[]::new);
203        
204        return new Script<>(webSocketID, requestJSON, responseProcessor);
205    }
206    
207}