001package Torello.Browser;
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.Java.Additional.*;
013
014import static Torello.Java.Additional.JFlag.*;
015
016import Torello.Java.StrCmpr;
017import Torello.JavaDoc.StaticFunctional;
018import Torello.JavaDoc.JDHeaderBackgroundImg;
019import Torello.JavaDoc.Excuse;
020
021/**
022 * <SPAN CLASS=CopiedJDK><B>Provides access to log entries.</B></SPAN>
023 * 
024 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
025 */
026@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
027@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
028public class Log
029{
030    // ********************************************************************************************
031    // ********************************************************************************************
032    // Class Header Stuff
033    // ********************************************************************************************
034    // ********************************************************************************************
035
036
037    // No Pubic Constructors
038    private Log () { }
039
040    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
041    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
042    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
043    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
044
045    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
046    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
047    // offically, two empty-vectors.  One for String's, and the other for Classes.
048
049    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
050    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
051
052    static
053    {
054        for (Method m : Log.class.getMethods())
055        {
056            // This doesn't work!  The parameter names are all "arg0" ... "argN"
057            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
058            //
059            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
060
061            Vector<Class<?>> parameterTypesList = new Vector<>();
062        
063            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
064
065            parameterTypes.put(
066                m.getName(),
067                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
068            );
069        }
070    }
071
072    static
073    {
074        Vector<String> v = null;
075
076        parameterNames.put("clear", EMPTY_VEC_STR);
077
078        parameterNames.put("disable", EMPTY_VEC_STR);
079
080        parameterNames.put("enable", EMPTY_VEC_STR);
081
082        v = new Vector<String>(1);
083        parameterNames.put("startViolationsReport", v);
084        Collections.addAll(v, new String[]
085        { "config", });
086
087        parameterNames.put("stopViolationsReport", EMPTY_VEC_STR);
088    }
089
090
091    // ********************************************************************************************
092    // ********************************************************************************************
093    // Types - Static Inner Classes
094    // ********************************************************************************************
095    // ********************************************************************************************
096
097    /** Log entry. */
098    public static class LogEntry extends BaseType
099    {
100        /** For Object Serialization.  java.io.Serializable */
101        protected static final long serialVersionUID = 1;
102        
103        public boolean[] optionals()
104        { return new boolean[] { false, false, false, true, false, true, true, true, true, true, true, }; }
105        
106        /** Log entry source. */
107        public final String source;
108        
109        /** Log entry severity. */
110        public final String level;
111        
112        /** Logged text. */
113        public final String text;
114        
115        /**
116         * <CODE>[No Description Provided by Google]</CODE>
117         * <BR />
118         * <BR /><B>OPTIONAL</B>
119         */
120        public final String category;
121        
122        /** Timestamp when this entry was added. */
123        public final Number timestamp;
124        
125        /**
126         * URL of the resource if known.
127         * <BR />
128         * <BR /><B>OPTIONAL</B>
129         */
130        public final String url;
131        
132        /**
133         * Line number in the resource.
134         * <BR />
135         * <BR /><B>OPTIONAL</B>
136         */
137        public final Integer lineNumber;
138        
139        /**
140         * JavaScript stack trace.
141         * <BR />
142         * <BR /><B>OPTIONAL</B>
143         */
144        public final RunTime.StackTrace stackTrace;
145        
146        /**
147         * Identifier of the network request associated with this entry.
148         * <BR />
149         * <BR /><B>OPTIONAL</B>
150         */
151        public final String networkRequestId;
152        
153        /**
154         * Identifier of the worker associated with this entry.
155         * <BR />
156         * <BR /><B>OPTIONAL</B>
157         */
158        public final String workerId;
159        
160        /**
161         * Call arguments.
162         * <BR />
163         * <BR /><B>OPTIONAL</B>
164         */
165        public final RunTime.RemoteObject[] args;
166        
167        /**
168         * Constructor
169         *
170         * @param source Log entry source.
171         * <BR />Acceptable Values: ["xml", "javascript", "network", "storage", "appcache", "rendering", "security", "deprecation", "worker", "violation", "intervention", "recommendation", "other"]
172         * 
173         * @param level Log entry severity.
174         * <BR />Acceptable Values: ["verbose", "info", "warning", "error"]
175         * 
176         * @param text Logged text.
177         * 
178         * @param category -
179         * <BR />Acceptable Values: ["cors"]
180         * <BR /><B>OPTIONAL</B>
181         * 
182         * @param timestamp Timestamp when this entry was added.
183         * 
184         * @param url URL of the resource if known.
185         * <BR /><B>OPTIONAL</B>
186         * 
187         * @param lineNumber Line number in the resource.
188         * <BR /><B>OPTIONAL</B>
189         * 
190         * @param stackTrace JavaScript stack trace.
191         * <BR /><B>OPTIONAL</B>
192         * 
193         * @param networkRequestId Identifier of the network request associated with this entry.
194         * <BR /><B>OPTIONAL</B>
195         * 
196         * @param workerId Identifier of the worker associated with this entry.
197         * <BR /><B>OPTIONAL</B>
198         * 
199         * @param args Call arguments.
200         * <BR /><B>OPTIONAL</B>
201         */
202        public LogEntry(
203                String source, String level, String text, String category, Number timestamp, 
204                String url, Integer lineNumber, RunTime.StackTrace stackTrace, 
205                String networkRequestId, String workerId, RunTime.RemoteObject[] args
206            )
207        {
208            // Exception-Check(s) to ensure that if any parameters which are not declared as
209            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
210            
211            if (source == null)    BRDPC.throwNPE("source");
212            if (level == null)     BRDPC.throwNPE("level");
213            if (text == null)      BRDPC.throwNPE("text");
214            if (timestamp == null) BRDPC.throwNPE("timestamp");
215            
216            // Exception-Check(s) to ensure that if any parameters which must adhere to a
217            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
218            
219            BRDPC.checkIAE(
220                "source", source,
221                "xml", "javascript", "network", "storage", "appcache", "rendering", "security", "deprecation", "worker", "violation", "intervention", "recommendation", "other"
222            );
223            BRDPC.checkIAE(
224                "level", level,
225                "verbose", "info", "warning", "error"
226            );
227            BRDPC.checkIAE(
228                "category", category,
229                "cors"
230            );
231            
232            this.source            = source;
233            this.level             = level;
234            this.text              = text;
235            this.category          = category;
236            this.timestamp         = timestamp;
237            this.url               = url;
238            this.lineNumber        = lineNumber;
239            this.stackTrace        = stackTrace;
240            this.networkRequestId  = networkRequestId;
241            this.workerId          = workerId;
242            this.args              = args;
243        }
244        
245        /**
246         * JSON Object Constructor
247         * @param jo A Json-Object having data about an instance of {@code 'LogEntry'}.
248         */
249        public LogEntry (JsonObject jo)
250        {
251            this.source            = ReadJSON.getString(jo, "source", false, true);
252            this.level             = ReadJSON.getString(jo, "level", false, true);
253            this.text              = ReadJSON.getString(jo, "text", false, true);
254            this.category          = ReadJSON.getString(jo, "category", true, false);
255            this.timestamp         = ReadJSON.getNUMBER(jo, "timestamp", false, true);
256            this.url               = ReadJSON.getString(jo, "url", true, false);
257            this.lineNumber        = ReadJSON.getINTEGER(jo, "lineNumber", true);
258            this.stackTrace        = ReadJSON.XL.getObject(jo, "stackTrace", RunTime.StackTrace.class, true, false);
259            this.networkRequestId  = ReadJSON.getString(jo, "networkRequestId", true, false);
260            this.workerId          = ReadJSON.getString(jo, "workerId", true, false);
261            this.args              = (jo.getJsonArray("args") == null)
262            ? null
263            : ReadArrJSON.DimN.objArr(jo.getJsonArray("args"), null, 0, RunTime.RemoteObject[].class);
264        }
265        
266    }
267    
268    /** Violation configuration setting. */
269    public static class ViolationSetting extends BaseType
270    {
271        /** For Object Serialization.  java.io.Serializable */
272        protected static final long serialVersionUID = 1;
273        
274        public boolean[] optionals()
275        { return new boolean[] { false, false, }; }
276        
277        /** Violation type. */
278        public final String name;
279        
280        /** Time threshold to trigger upon. */
281        public final Number threshold;
282        
283        /**
284         * Constructor
285         *
286         * @param name Violation type.
287         * <BR />Acceptable Values: ["longTask", "longLayout", "blockedEvent", "blockedParser", "discouragedAPIUse", "handler", "recurringHandler"]
288         * 
289         * @param threshold Time threshold to trigger upon.
290         */
291        public ViolationSetting(String name, Number threshold)
292        {
293            // Exception-Check(s) to ensure that if any parameters which are not declared as
294            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
295            
296            if (name == null)      BRDPC.throwNPE("name");
297            if (threshold == null) BRDPC.throwNPE("threshold");
298            
299            // Exception-Check(s) to ensure that if any parameters which must adhere to a
300            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
301            
302            BRDPC.checkIAE(
303                "name", name,
304                "longTask", "longLayout", "blockedEvent", "blockedParser", "discouragedAPIUse", "handler", "recurringHandler"
305            );
306            
307            this.name       = name;
308            this.threshold  = threshold;
309        }
310        
311        /**
312         * JSON Object Constructor
313         * @param jo A Json-Object having data about an instance of {@code 'ViolationSetting'}.
314         */
315        public ViolationSetting (JsonObject jo)
316        {
317            this.name       = ReadJSON.getString(jo, "name", false, true);
318            this.threshold  = ReadJSON.getNUMBER(jo, "threshold", false, true);
319        }
320        
321    }
322    
323    /** Issued when new message was logged. */
324    public static class entryAdded extends BrowserEvent
325    {
326        /** For Object Serialization.  java.io.Serializable */
327        protected static final long serialVersionUID = 1;
328        
329        public boolean[] optionals()
330        { return new boolean[] { false, }; }
331        
332        /** The entry. */
333        public final Log.LogEntry entry;
334        
335        /**
336         * Constructor
337         *
338         * @param entry The entry.
339         */
340        public entryAdded(Log.LogEntry entry)
341        {
342            super("Log", "entryAdded", 1);
343            
344            // Exception-Check(s) to ensure that if any parameters which are not declared as
345            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
346            
347            if (entry == null) BRDPC.throwNPE("entry");
348            
349            this.entry  = entry;
350        }
351        
352        /**
353         * JSON Object Constructor
354         * @param jo A Json-Object having data about an instance of {@code 'entryAdded'}.
355         */
356        public entryAdded (JsonObject jo)
357        {
358            super("Log", "entryAdded", 1);
359        
360            this.entry  = ReadJSON.XL.getObject(jo, "entry", Log.LogEntry.class, false, true);
361        }
362        
363    }
364    
365    
366    // Counter for keeping the WebSocket Request ID's distinct.
367    private static int counter = 1;
368    
369    /**
370     * Clears the log.
371     * 
372     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
373     * {@link Ret0}&gt;</CODE>
374     *
375     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
376     * browser receives the invocation-request.
377     *
378     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
379     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
380     * {@code >} to ensure the Browser Function has run to completion.
381     */
382    public static Script<String, JsonObject, Ret0> clear()
383    {
384        final int          webSocketID = 28000000 + counter++;
385        final boolean[]    optionals   = new boolean[0];
386        
387        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
388        String requestJSON = WriteJSON.get(
389            parameterTypes.get("clear"),
390            parameterNames.get("clear"),
391            optionals, webSocketID,
392            "Log.clear"
393        );
394        
395        // This Remote Command does not have a Return-Value.
396        return new Script<>
397            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
398    }
399    
400    /**
401     * Disables log domain, prevents further log entries from being reported to the client.
402     * 
403     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
404     * {@link Ret0}&gt;</CODE>
405     *
406     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
407     * browser receives the invocation-request.
408     *
409     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
410     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
411     * {@code >} to ensure the Browser Function has run to completion.
412     */
413    public static Script<String, JsonObject, Ret0> disable()
414    {
415        final int          webSocketID = 28001000 + counter++;
416        final boolean[]    optionals   = new boolean[0];
417        
418        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
419        String requestJSON = WriteJSON.get(
420            parameterTypes.get("disable"),
421            parameterNames.get("disable"),
422            optionals, webSocketID,
423            "Log.disable"
424        );
425        
426        // This Remote Command does not have a Return-Value.
427        return new Script<>
428            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
429    }
430    
431    /**
432     * Enables log domain, sends the entries collected so far to the client by means of the
433     * <CODE>entryAdded</CODE> notification.
434     * 
435     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
436     * {@link Ret0}&gt;</CODE>
437     *
438     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
439     * browser receives the invocation-request.
440     *
441     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
442     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
443     * {@code >} to ensure the Browser Function has run to completion.
444     */
445    public static Script<String, JsonObject, Ret0> enable()
446    {
447        final int          webSocketID = 28002000 + counter++;
448        final boolean[]    optionals   = new boolean[0];
449        
450        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
451        String requestJSON = WriteJSON.get(
452            parameterTypes.get("enable"),
453            parameterNames.get("enable"),
454            optionals, webSocketID,
455            "Log.enable"
456        );
457        
458        // This Remote Command does not have a Return-Value.
459        return new Script<>
460            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
461    }
462    
463    /**
464     * start violation reporting.
465     * 
466     * @param config Configuration for violations.
467     * 
468     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
469     * {@link Ret0}&gt;</CODE>
470     *
471     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
472     * browser receives the invocation-request.
473     *
474     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
475     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
476     * {@code >} to ensure the Browser Function has run to completion.
477     */
478    public static Script<String, JsonObject, Ret0> startViolationsReport
479        (Log.ViolationSetting[] config)
480    {
481        // Exception-Check(s) to ensure that if any parameters which are not declared as
482        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
483        
484        if (config == null) BRDPC.throwNPE("config");
485        
486        final int       webSocketID = 28003000 + counter++;
487        final boolean[] optionals   = { false, };
488        
489        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
490        String requestJSON = WriteJSON.get(
491            parameterTypes.get("startViolationsReport"),
492            parameterNames.get("startViolationsReport"),
493            optionals, webSocketID,
494            "Log.startViolationsReport",
495            (Object) config
496        );
497        
498        // This Remote Command does not have a Return-Value.
499        return new Script<>
500            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
501    }
502    
503    /**
504     * Stop violation reporting.
505     * 
506     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
507     * {@link Ret0}&gt;</CODE>
508     *
509     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
510     * browser receives the invocation-request.
511     *
512     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
513     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
514     * {@code >} to ensure the Browser Function has run to completion.
515     */
516    public static Script<String, JsonObject, Ret0> stopViolationsReport()
517    {
518        final int          webSocketID = 28004000 + counter++;
519        final boolean[]    optionals   = new boolean[0];
520        
521        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
522        String requestJSON = WriteJSON.get(
523            parameterTypes.get("stopViolationsReport"),
524            parameterNames.get("stopViolationsReport"),
525            optionals, webSocketID,
526            "Log.stopViolationsReport"
527        );
528        
529        // This Remote Command does not have a Return-Value.
530        return new Script<>
531            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
532    }
533    
534}