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>Defines events for background web platform features.</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 BackgroundService
029{
030    // ********************************************************************************************
031    // ********************************************************************************************
032    // Class Header Stuff
033    // ********************************************************************************************
034    // ********************************************************************************************
035
036
037    // No Pubic Constructors
038    private BackgroundService () { }
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 : BackgroundService.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        v = new Vector<String>(1);
077        parameterNames.put("startObserving", v);
078        Collections.addAll(v, new String[]
079        { "service", });
080
081        v = new Vector<String>(1);
082        parameterNames.put("stopObserving", v);
083        Collections.addAll(v, new String[]
084        { "service", });
085
086        v = new Vector<String>(2);
087        parameterNames.put("setRecording", v);
088        Collections.addAll(v, new String[]
089        { "shouldRecord", "service", });
090
091        v = new Vector<String>(1);
092        parameterNames.put("clearEvents", v);
093        Collections.addAll(v, new String[]
094        { "service", });
095    }
096
097
098    // ********************************************************************************************
099    // ********************************************************************************************
100    // Types - Static Inner Classes
101    // ********************************************************************************************
102    // ********************************************************************************************
103
104    /**
105     * The Background Service that will be associated with the commands/events.
106     * Every Background Service operates independently, but they share the same
107     * API.
108     */
109    public static final String[] ServiceName =
110    { 
111        "backgroundFetch", "backgroundSync", "pushMessaging", "notifications", "paymentHandler", 
112        "periodicBackgroundSync", 
113    };
114    
115    /** A key-value pair for additional event information to pass along. */
116    public static class EventMetadata extends BaseType
117    {
118        /** For Object Serialization.  java.io.Serializable */
119        protected static final long serialVersionUID = 1;
120        
121        public boolean[] optionals()
122        { return new boolean[] { false, false, }; }
123        
124        /** <CODE>[No Description Provided by Google]</CODE> */
125        public final String key;
126        
127        /** <CODE>[No Description Provided by Google]</CODE> */
128        public final String value;
129        
130        /**
131         * Constructor
132         *
133         * @param key -
134         * 
135         * @param value -
136         */
137        public EventMetadata(String key, String value)
138        {
139            // Exception-Check(s) to ensure that if any parameters which are not declared as
140            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
141            
142            if (key == null)   BRDPC.throwNPE("key");
143            if (value == null) BRDPC.throwNPE("value");
144            
145            this.key    = key;
146            this.value  = value;
147        }
148        
149        /**
150         * JSON Object Constructor
151         * @param jo A Json-Object having data about an instance of {@code 'EventMetadata'}.
152         */
153        public EventMetadata (JsonObject jo)
154        {
155            this.key    = ReadJSON.getString(jo, "key", false, true);
156            this.value  = ReadJSON.getString(jo, "value", false, true);
157        }
158        
159    }
160    
161    /** <CODE>[No Description Provided by Google]</CODE> */
162    public static class BackgroundServiceEvent extends BaseType
163    {
164        /** For Object Serialization.  java.io.Serializable */
165        protected static final long serialVersionUID = 1;
166        
167        public boolean[] optionals()
168        { return new boolean[] { false, false, false, false, false, false, false, }; }
169        
170        /** Timestamp of the event (in seconds). */
171        public final Number timestamp;
172        
173        /** The origin this event belongs to. */
174        public final String origin;
175        
176        /** The Service Worker ID that initiated the event. */
177        public final String serviceWorkerRegistrationId;
178        
179        /** The Background Service this event belongs to. */
180        public final String service;
181        
182        /** A description of the event. */
183        public final String eventName;
184        
185        /** An identifier that groups related events together. */
186        public final String instanceId;
187        
188        /** A list of event-specific information. */
189        public final BackgroundService.EventMetadata[] eventMetadata;
190        
191        /**
192         * Constructor
193         *
194         * @param timestamp Timestamp of the event (in seconds).
195         * 
196         * @param origin The origin this event belongs to.
197         * 
198         * @param serviceWorkerRegistrationId The Service Worker ID that initiated the event.
199         * 
200         * @param service The Background Service this event belongs to.
201         * 
202         * @param eventName A description of the event.
203         * 
204         * @param instanceId An identifier that groups related events together.
205         * 
206         * @param eventMetadata A list of event-specific information.
207         */
208        public BackgroundServiceEvent(
209                Number timestamp, String origin, String serviceWorkerRegistrationId, String service, 
210                String eventName, String instanceId, BackgroundService.EventMetadata[] eventMetadata
211            )
212        {
213            // Exception-Check(s) to ensure that if any parameters which are not declared as
214            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
215            
216            if (timestamp == null)                   BRDPC.throwNPE("timestamp");
217            if (origin == null)                      BRDPC.throwNPE("origin");
218            if (serviceWorkerRegistrationId == null) BRDPC.throwNPE("serviceWorkerRegistrationId");
219            if (service == null)                     BRDPC.throwNPE("service");
220            if (eventName == null)                   BRDPC.throwNPE("eventName");
221            if (instanceId == null)                  BRDPC.throwNPE("instanceId");
222            if (eventMetadata == null)               BRDPC.throwNPE("eventMetadata");
223            
224            // Exception-Check(s) to ensure that if any parameters which must adhere to a
225            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
226            
227            BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName);
228            
229            this.timestamp                    = timestamp;
230            this.origin                       = origin;
231            this.serviceWorkerRegistrationId  = serviceWorkerRegistrationId;
232            this.service                      = service;
233            this.eventName                    = eventName;
234            this.instanceId                   = instanceId;
235            this.eventMetadata                = eventMetadata;
236        }
237        
238        /**
239         * JSON Object Constructor
240         * @param jo A Json-Object having data about an instance of {@code 'BackgroundServiceEvent'}.
241         */
242        public BackgroundServiceEvent (JsonObject jo)
243        {
244            this.timestamp                    = ReadJSON.getNUMBER(jo, "timestamp", false, true);
245            this.origin                       = ReadJSON.getString(jo, "origin", false, true);
246            this.serviceWorkerRegistrationId  = ReadJSON.getString(jo, "serviceWorkerRegistrationId", false, true);
247            this.service                      = ReadJSON.getString(jo, "service", false, true);
248            this.eventName                    = ReadJSON.getString(jo, "eventName", false, true);
249            this.instanceId                   = ReadJSON.getString(jo, "instanceId", false, true);
250            this.eventMetadata                = (jo.getJsonArray("eventMetadata") == null)
251            ? null
252            : ReadArrJSON.DimN.objArr(jo.getJsonArray("eventMetadata"), null, 0, BackgroundService.EventMetadata[].class);
253        }
254        
255    }
256    
257    /** Called when the recording state for the service has been updated. */
258    public static class recordingStateChanged extends BrowserEvent
259    {
260        /** For Object Serialization.  java.io.Serializable */
261        protected static final long serialVersionUID = 1;
262        
263        public boolean[] optionals()
264        { return new boolean[] { false, false, }; }
265        
266        /** <CODE>[No Description Provided by Google]</CODE> */
267        public final boolean isRecording;
268        
269        /** <CODE>[No Description Provided by Google]</CODE> */
270        public final String service;
271        
272        /**
273         * Constructor
274         *
275         * @param isRecording -
276         * 
277         * @param service -
278         */
279        public recordingStateChanged(boolean isRecording, String service)
280        {
281            super("BackgroundService", "recordingStateChanged", 2);
282            
283            // Exception-Check(s) to ensure that if any parameters which are not declared as
284            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
285            
286            if (service == null) BRDPC.throwNPE("service");
287            
288            // Exception-Check(s) to ensure that if any parameters which must adhere to a
289            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
290            
291            BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName);
292            
293            this.isRecording  = isRecording;
294            this.service      = service;
295        }
296        
297        /**
298         * JSON Object Constructor
299         * @param jo A Json-Object having data about an instance of {@code 'recordingStateChanged'}.
300         */
301        public recordingStateChanged (JsonObject jo)
302        {
303            super("BackgroundService", "recordingStateChanged", 2);
304        
305            this.isRecording  = ReadJSON.getBoolean(jo, "isRecording");
306            this.service      = ReadJSON.getString(jo, "service", false, true);
307        }
308        
309    }
310    
311    /**
312     * Called with all existing backgroundServiceEvents when enabled, and all new
313     * events afterwards if enabled and recording.
314     */
315    public static class backgroundServiceEventReceived extends BrowserEvent
316    {
317        /** For Object Serialization.  java.io.Serializable */
318        protected static final long serialVersionUID = 1;
319        
320        public boolean[] optionals()
321        { return new boolean[] { false, }; }
322        
323        /** <CODE>[No Description Provided by Google]</CODE> */
324        public final BackgroundService.BackgroundServiceEvent backgroundServiceEvent;
325        
326        /**
327         * Constructor
328         *
329         * @param backgroundServiceEvent -
330         */
331        public backgroundServiceEventReceived
332            (BackgroundService.BackgroundServiceEvent backgroundServiceEvent)
333        {
334            super("BackgroundService", "backgroundServiceEventReceived", 1);
335            
336            // Exception-Check(s) to ensure that if any parameters which are not declared as
337            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
338            
339            if (backgroundServiceEvent == null) BRDPC.throwNPE("backgroundServiceEvent");
340            
341            this.backgroundServiceEvent  = backgroundServiceEvent;
342        }
343        
344        /**
345         * JSON Object Constructor
346         * @param jo A Json-Object having data about an instance of {@code 'backgroundServiceEventReceived'}.
347         */
348        public backgroundServiceEventReceived (JsonObject jo)
349        {
350            super("BackgroundService", "backgroundServiceEventReceived", 1);
351        
352            this.backgroundServiceEvent  = ReadJSON.XL.getObject(jo, "backgroundServiceEvent", BackgroundService.BackgroundServiceEvent.class, false, true);
353        }
354        
355    }
356    
357    
358    // Counter for keeping the WebSocket Request ID's distinct.
359    private static int counter = 1;
360    
361    /**
362     * Enables event updates for the service.
363     * 
364     * @param service -
365     * 
366     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
367     * {@link Ret0}&gt;</CODE>
368     *
369     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
370     * browser receives the invocation-request.
371     *
372     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
373     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
374     * {@code >} to ensure the Browser Function has run to completion.
375     */
376    public static Script<String, JsonObject, Ret0> startObserving(String service)
377    {
378        // Exception-Check(s) to ensure that if any parameters which are not declared as
379        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
380        
381        if (service == null) BRDPC.throwNPE("service");
382        
383        // Exception-Check(s) to ensure that if any parameters which must adhere to a
384        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
385        
386        BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName);
387        
388        final int       webSocketID = 10000000 + counter++;
389        final boolean[] optionals   = { false, };
390        
391        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
392        String requestJSON = WriteJSON.get(
393            parameterTypes.get("startObserving"),
394            parameterNames.get("startObserving"),
395            optionals, webSocketID,
396            "BackgroundService.startObserving",
397            service
398        );
399        
400        // This Remote Command does not have a Return-Value.
401        return new Script<>
402            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
403    }
404    
405    /**
406     * Disables event updates for the service.
407     * 
408     * @param service -
409     * 
410     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
411     * {@link Ret0}&gt;</CODE>
412     *
413     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
414     * browser receives the invocation-request.
415     *
416     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
417     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
418     * {@code >} to ensure the Browser Function has run to completion.
419     */
420    public static Script<String, JsonObject, Ret0> stopObserving(String service)
421    {
422        // Exception-Check(s) to ensure that if any parameters which are not declared as
423        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
424        
425        if (service == null) BRDPC.throwNPE("service");
426        
427        // Exception-Check(s) to ensure that if any parameters which must adhere to a
428        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
429        
430        BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName);
431        
432        final int       webSocketID = 10001000 + counter++;
433        final boolean[] optionals   = { false, };
434        
435        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
436        String requestJSON = WriteJSON.get(
437            parameterTypes.get("stopObserving"),
438            parameterNames.get("stopObserving"),
439            optionals, webSocketID,
440            "BackgroundService.stopObserving",
441            service
442        );
443        
444        // This Remote Command does not have a Return-Value.
445        return new Script<>
446            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
447    }
448    
449    /**
450     * Set the recording state for the service.
451     * 
452     * @param shouldRecord -
453     * 
454     * @param service -
455     * 
456     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
457     * {@link Ret0}&gt;</CODE>
458     *
459     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
460     * browser receives the invocation-request.
461     *
462     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
463     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
464     * {@code >} to ensure the Browser Function has run to completion.
465     */
466    public static Script<String, JsonObject, Ret0> setRecording
467        (boolean shouldRecord, String service)
468    {
469        // Exception-Check(s) to ensure that if any parameters which are not declared as
470        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
471        
472        if (service == null) BRDPC.throwNPE("service");
473        
474        // Exception-Check(s) to ensure that if any parameters which must adhere to a
475        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
476        
477        BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName);
478        
479        final int       webSocketID = 10002000 + counter++;
480        final boolean[] optionals   = { false, false, };
481        
482        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
483        String requestJSON = WriteJSON.get(
484            parameterTypes.get("setRecording"),
485            parameterNames.get("setRecording"),
486            optionals, webSocketID,
487            "BackgroundService.setRecording",
488            shouldRecord, service
489        );
490        
491        // This Remote Command does not have a Return-Value.
492        return new Script<>
493            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
494    }
495    
496    /**
497     * Clears all stored data for the service.
498     * 
499     * @param service -
500     * 
501     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
502     * {@link Ret0}&gt;</CODE>
503     *
504     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
505     * browser receives the invocation-request.
506     *
507     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
508     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
509     * {@code >} to ensure the Browser Function has run to completion.
510     */
511    public static Script<String, JsonObject, Ret0> clearEvents(String service)
512    {
513        // Exception-Check(s) to ensure that if any parameters which are not declared as
514        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
515        
516        if (service == null) BRDPC.throwNPE("service");
517        
518        // Exception-Check(s) to ensure that if any parameters which must adhere to a
519        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
520        
521        BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName);
522        
523        final int       webSocketID = 10003000 + counter++;
524        final boolean[] optionals   = { false, };
525        
526        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
527        String requestJSON = WriteJSON.get(
528            parameterTypes.get("clearEvents"),
529            parameterNames.get("clearEvents"),
530            optionals, webSocketID,
531            "BackgroundService.clearEvents",
532            service
533        );
534        
535        // This Remote Command does not have a Return-Value.
536        return new Script<>
537            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
538    }
539    
540}