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.*;
013import Torello.Java.JSON.*;
014
015import static Torello.Java.JSON.JFlag.*;
016
017import Torello.Java.StrCmpr;
018import Torello.JavaDoc.StaticFunctional;
019import Torello.JavaDoc.JDHeaderBackgroundImg;
020import Torello.JavaDoc.Excuse;
021
022/**
023 * <SPAN CLASS=COPIEDJDK><B><CODE>[No Description Provided by Google]</CODE></B></SPAN>
024 * 
025 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
026 */
027@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
028@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
029public class CacheStorage
030{
031    // ********************************************************************************************
032    // ********************************************************************************************
033    // Class Header Stuff
034    // ********************************************************************************************
035    // ********************************************************************************************
036
037
038    // No Pubic Constructors
039    private CacheStorage () { }
040
041    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
042    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
043    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
044    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
045
046    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
047    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
048    // offically, two empty-vectors.  One for String's, and the other for Classes.
049
050    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
051    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
052
053    static
054    {
055        for (Method m : CacheStorage.class.getMethods())
056        {
057            // This doesn't work!  The parameter names are all "arg0" ... "argN"
058            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
059            //
060            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
061
062            Vector<Class<?>> parameterTypesList = new Vector<>();
063        
064            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
065
066            parameterTypes.put(
067                m.getName(),
068                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
069            );
070        }
071    }
072
073    static
074    {
075        Vector<String> v = null;
076
077        v = new Vector<String>(1);
078        parameterNames.put("deleteCache", v);
079        Collections.addAll(v, new String[]
080        { "cacheId", });
081
082        v = new Vector<String>(2);
083        parameterNames.put("deleteEntry", v);
084        Collections.addAll(v, new String[]
085        { "cacheId", "request", });
086
087        v = new Vector<String>(1);
088        parameterNames.put("requestCacheNames", v);
089        Collections.addAll(v, new String[]
090        { "securityOrigin", });
091
092        v = new Vector<String>(3);
093        parameterNames.put("requestCachedResponse", v);
094        Collections.addAll(v, new String[]
095        { "cacheId", "requestURL", "requestHeaders", });
096
097        v = new Vector<String>(4);
098        parameterNames.put("requestEntries", v);
099        Collections.addAll(v, new String[]
100        { "cacheId", "skipCount", "pageSize", "pathFilter", });
101    }
102
103
104    // ********************************************************************************************
105    // ********************************************************************************************
106    // Types - Static Inner Classes
107    // ********************************************************************************************
108    // ********************************************************************************************
109
110    // public static class CacheId => String
111    
112    /** type of HTTP response cached */
113    public static final String[] CachedResponseType =
114    { "basic", "cors", "default", "error", "opaqueResponse", "opaqueRedirect", };
115    
116    /** Data entry. */
117    public static class DataEntry
118        extends BaseType
119        implements java.io.Serializable
120    {
121        /** For Object Serialization.  java.io.Serializable */
122        protected static final long serialVersionUID = 1;
123        
124        public boolean[] optionals()
125        { return new boolean[] { false, false, false, false, false, false, false, false, }; }
126        
127        /** Request URL. */
128        public final String requestURL;
129        
130        /** Request method. */
131        public final String requestMethod;
132        
133        /** Request headers */
134        public final CacheStorage.Header[] requestHeaders;
135        
136        /** Number of seconds since epoch. */
137        public final Number responseTime;
138        
139        /** HTTP response status code. */
140        public final int responseStatus;
141        
142        /** HTTP response status text. */
143        public final String responseStatusText;
144        
145        /** HTTP response type */
146        public final String responseType;
147        
148        /** Response headers */
149        public final CacheStorage.Header[] responseHeaders;
150        
151        /**
152         * Constructor
153         *
154         * @param requestURL Request URL.
155         * 
156         * @param requestMethod Request method.
157         * 
158         * @param requestHeaders Request headers
159         * 
160         * @param responseTime Number of seconds since epoch.
161         * 
162         * @param responseStatus HTTP response status code.
163         * 
164         * @param responseStatusText HTTP response status text.
165         * 
166         * @param responseType HTTP response type
167         * 
168         * @param responseHeaders Response headers
169         */
170        public DataEntry(
171                String requestURL, String requestMethod, CacheStorage.Header[] requestHeaders, 
172                Number responseTime, int responseStatus, String responseStatusText, 
173                String responseType, CacheStorage.Header[] responseHeaders
174            )
175        {
176            // Exception-Check(s) to ensure that if any parameters which are not declared as
177            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
178            
179            if (requestURL == null)         BRDPC.throwNPE("requestURL");
180            if (requestMethod == null)      BRDPC.throwNPE("requestMethod");
181            if (requestHeaders == null)     BRDPC.throwNPE("requestHeaders");
182            if (responseTime == null)       BRDPC.throwNPE("responseTime");
183            if (responseStatusText == null) BRDPC.throwNPE("responseStatusText");
184            if (responseType == null)       BRDPC.throwNPE("responseType");
185            if (responseHeaders == null)    BRDPC.throwNPE("responseHeaders");
186            
187            // Exception-Check(s) to ensure that if any parameters which must adhere to a
188            // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
189            
190            BRDPC.checkIAE("responseType", responseType, "CacheStorage.CachedResponseType", CacheStorage.CachedResponseType);
191            
192            this.requestURL          = requestURL;
193            this.requestMethod       = requestMethod;
194            this.requestHeaders      = requestHeaders;
195            this.responseTime        = responseTime;
196            this.responseStatus      = responseStatus;
197            this.responseStatusText  = responseStatusText;
198            this.responseType        = responseType;
199            this.responseHeaders     = responseHeaders;
200        }
201        
202        /**
203         * JSON Object Constructor
204         * @param jo A Json-Object having data about an instance of {@code 'DataEntry'}.
205         */
206        public DataEntry (JsonObject jo)
207        {
208            this.requestURL          = ReadJSON.getString(jo, "requestURL", false, true);
209            this.requestMethod       = ReadJSON.getString(jo, "requestMethod", false, true);
210            this.requestHeaders = (jo.getJsonArray("requestHeaders") == null)
211                ? null
212                : ReadArrJSON.DimN.objArr(jo.getJsonArray("requestHeaders"), null, 0, CacheStorage.Header[].class);
213        
214            this.responseTime        = ReadNumberJSON.get(jo, "responseTime", false, true);
215            this.responseStatus      = ReadPrimJSON.getInt(jo, "responseStatus");
216            this.responseStatusText  = ReadJSON.getString(jo, "responseStatusText", false, true);
217            this.responseType        = ReadJSON.getString(jo, "responseType", false, true);
218            this.responseHeaders = (jo.getJsonArray("responseHeaders") == null)
219                ? null
220                : ReadArrJSON.DimN.objArr(jo.getJsonArray("responseHeaders"), null, 0, CacheStorage.Header[].class);
221        
222        }
223        
224        
225        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
226        public boolean equals(Object other)
227        {
228            if (other == null)                       return false;
229            if (other.getClass() != this.getClass()) return false;
230        
231            DataEntry o = (DataEntry) other;
232        
233            return
234                    Objects.equals(this.requestURL, o.requestURL)
235                &&  Objects.equals(this.requestMethod, o.requestMethod)
236                &&  Arrays.deepEquals(this.requestHeaders, o.requestHeaders)
237                &&  Objects.equals(this.responseTime, o.responseTime)
238                &&  (this.responseStatus == o.responseStatus)
239                &&  Objects.equals(this.responseStatusText, o.responseStatusText)
240                &&  Objects.equals(this.responseType, o.responseType)
241                &&  Arrays.deepEquals(this.responseHeaders, o.responseHeaders);
242        }
243        
244        /** Generates a Hash-Code for {@code 'this'} instance */
245        public int hashCode()
246        {
247            return
248                    Objects.hashCode(this.requestURL)
249                +   Objects.hashCode(this.requestMethod)
250                +   Arrays.deepHashCode(this.requestHeaders)
251                +   Objects.hashCode(this.responseTime)
252                +   this.responseStatus
253                +   Objects.hashCode(this.responseStatusText)
254                +   Objects.hashCode(this.responseType)
255                +   Arrays.deepHashCode(this.responseHeaders);
256        }
257    }
258    
259    /** Cache identifier. */
260    public static class Cache
261        extends BaseType
262        implements java.io.Serializable
263    {
264        /** For Object Serialization.  java.io.Serializable */
265        protected static final long serialVersionUID = 1;
266        
267        public boolean[] optionals()
268        { return new boolean[] { false, false, false, }; }
269        
270        /** An opaque unique id of the cache. */
271        public final String cacheId;
272        
273        /** Security origin of the cache. */
274        public final String securityOrigin;
275        
276        /** The name of the cache. */
277        public final String cacheName;
278        
279        /**
280         * Constructor
281         *
282         * @param cacheId An opaque unique id of the cache.
283         * 
284         * @param securityOrigin Security origin of the cache.
285         * 
286         * @param cacheName The name of the cache.
287         */
288        public Cache(String cacheId, String securityOrigin, String cacheName)
289        {
290            // Exception-Check(s) to ensure that if any parameters which are not declared as
291            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
292            
293            if (cacheId == null)        BRDPC.throwNPE("cacheId");
294            if (securityOrigin == null) BRDPC.throwNPE("securityOrigin");
295            if (cacheName == null)      BRDPC.throwNPE("cacheName");
296            
297            this.cacheId         = cacheId;
298            this.securityOrigin  = securityOrigin;
299            this.cacheName       = cacheName;
300        }
301        
302        /**
303         * JSON Object Constructor
304         * @param jo A Json-Object having data about an instance of {@code 'Cache'}.
305         */
306        public Cache (JsonObject jo)
307        {
308            this.cacheId         = ReadJSON.getString(jo, "cacheId", false, true);
309            this.securityOrigin  = ReadJSON.getString(jo, "securityOrigin", false, true);
310            this.cacheName       = ReadJSON.getString(jo, "cacheName", false, true);
311        }
312        
313        
314        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
315        public boolean equals(Object other)
316        {
317            if (other == null)                       return false;
318            if (other.getClass() != this.getClass()) return false;
319        
320            Cache o = (Cache) other;
321        
322            return
323                    Objects.equals(this.cacheId, o.cacheId)
324                &&  Objects.equals(this.securityOrigin, o.securityOrigin)
325                &&  Objects.equals(this.cacheName, o.cacheName);
326        }
327        
328        /** Generates a Hash-Code for {@code 'this'} instance */
329        public int hashCode()
330        {
331            return
332                    Objects.hashCode(this.cacheId)
333                +   Objects.hashCode(this.securityOrigin)
334                +   Objects.hashCode(this.cacheName);
335        }
336    }
337    
338    /** <CODE>[No Description Provided by Google]</CODE> */
339    public static class Header
340        extends BaseType
341        implements java.io.Serializable
342    {
343        /** For Object Serialization.  java.io.Serializable */
344        protected static final long serialVersionUID = 1;
345        
346        public boolean[] optionals()
347        { return new boolean[] { false, false, }; }
348        
349        /** <CODE>[No Description Provided by Google]</CODE> */
350        public final String name;
351        
352        /** <CODE>[No Description Provided by Google]</CODE> */
353        public final String value;
354        
355        /**
356         * Constructor
357         *
358         * @param name -
359         * 
360         * @param value -
361         */
362        public Header(String name, String value)
363        {
364            // Exception-Check(s) to ensure that if any parameters which are not declared as
365            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
366            
367            if (name == null)  BRDPC.throwNPE("name");
368            if (value == null) BRDPC.throwNPE("value");
369            
370            this.name   = name;
371            this.value  = value;
372        }
373        
374        /**
375         * JSON Object Constructor
376         * @param jo A Json-Object having data about an instance of {@code 'Header'}.
377         */
378        public Header (JsonObject jo)
379        {
380            this.name   = ReadJSON.getString(jo, "name", false, true);
381            this.value  = ReadJSON.getString(jo, "value", false, true);
382        }
383        
384        
385        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
386        public boolean equals(Object other)
387        {
388            if (other == null)                       return false;
389            if (other.getClass() != this.getClass()) return false;
390        
391            Header o = (Header) other;
392        
393            return
394                    Objects.equals(this.name, o.name)
395                &&  Objects.equals(this.value, o.value);
396        }
397        
398        /** Generates a Hash-Code for {@code 'this'} instance */
399        public int hashCode()
400        {
401            return
402                    Objects.hashCode(this.name)
403                +   Objects.hashCode(this.value);
404        }
405    }
406    
407    /** Cached response */
408    public static class CachedResponse
409        extends BaseType
410        implements java.io.Serializable
411    {
412        /** For Object Serialization.  java.io.Serializable */
413        protected static final long serialVersionUID = 1;
414        
415        public boolean[] optionals()
416        { return new boolean[] { false, }; }
417        
418        /** Entry content, base64-encoded. (Encoded as a base64 string when passed over JSON) */
419        public final String body;
420        
421        /**
422         * Constructor
423         *
424         * @param body Entry content, base64-encoded. (Encoded as a base64 string when passed over JSON)
425         */
426        public CachedResponse(String body)
427        {
428            // Exception-Check(s) to ensure that if any parameters which are not declared as
429            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
430            
431            if (body == null) BRDPC.throwNPE("body");
432            
433            this.body  = body;
434        }
435        
436        /**
437         * JSON Object Constructor
438         * @param jo A Json-Object having data about an instance of {@code 'CachedResponse'}.
439         */
440        public CachedResponse (JsonObject jo)
441        {
442            this.body  = ReadJSON.getString(jo, "body", false, true);
443        }
444        
445        
446        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
447        public boolean equals(Object other)
448        {
449            if (other == null)                       return false;
450            if (other.getClass() != this.getClass()) return false;
451        
452            CachedResponse o = (CachedResponse) other;
453        
454            return
455                    Objects.equals(this.body, o.body);
456        }
457        
458        /** Generates a Hash-Code for {@code 'this'} instance */
459        public int hashCode()
460        {
461            return
462                    Objects.hashCode(this.body);
463        }
464    }
465    
466    
467    // Counter for keeping the WebSocket Request ID's distinct.
468    private static int counter = 1;
469    
470    /**
471     * Deletes a cache.
472     * 
473     * @param cacheId Id of cache for deletion.
474     * 
475     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
476     * {@link Ret0}&gt;</CODE>
477     *
478     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
479     * browser receives the invocation-request.
480     *
481     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
482     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
483     * {@code >} to ensure the Browser Function has run to completion.
484     */
485    public static Script<String, JsonObject, Ret0> deleteCache(String cacheId)
486    {
487        // Exception-Check(s) to ensure that if any parameters which are not declared as
488        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
489        
490        if (cacheId == null) BRDPC.throwNPE("cacheId");
491        
492        final int       webSocketID = 13000000 + counter++;
493        final boolean[] optionals   = { false, };
494        
495        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
496        String requestJSON = WriteJSON.get(
497            parameterTypes.get("deleteCache"),
498            parameterNames.get("deleteCache"),
499            optionals, webSocketID,
500            "CacheStorage.deleteCache",
501            cacheId
502        );
503        
504        // This Remote Command does not have a Return-Value.
505        return new Script<>
506            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
507    }
508    
509    /**
510     * Deletes a cache entry.
511     * 
512     * @param cacheId Id of cache where the entry will be deleted.
513     * 
514     * @param request URL spec of the request.
515     * 
516     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
517     * {@link Ret0}&gt;</CODE>
518     *
519     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
520     * browser receives the invocation-request.
521     *
522     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
523     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
524     * {@code >} to ensure the Browser Function has run to completion.
525     */
526    public static Script<String, JsonObject, Ret0> deleteEntry(String cacheId, String request)
527    {
528        // Exception-Check(s) to ensure that if any parameters which are not declared as
529        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
530        
531        if (cacheId == null) BRDPC.throwNPE("cacheId");
532        if (request == null) BRDPC.throwNPE("request");
533        
534        final int       webSocketID = 13001000 + counter++;
535        final boolean[] optionals   = { false, false, };
536        
537        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
538        String requestJSON = WriteJSON.get(
539            parameterTypes.get("deleteEntry"),
540            parameterNames.get("deleteEntry"),
541            optionals, webSocketID,
542            "CacheStorage.deleteEntry",
543            cacheId, request
544        );
545        
546        // This Remote Command does not have a Return-Value.
547        return new Script<>
548            (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues);
549    }
550    
551    /**
552     * Requests cache names.
553     * 
554     * @param securityOrigin Security origin.
555     * 
556     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
557     * {@link CacheStorage.Cache}[]&gt;</CODE>
558     * 
559     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
560     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
561     * {@link CacheStorage.Cache}[]&gt;</CODE> will be returned.
562     *
563     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
564     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
565      * may be retrieved.</I>
566     *
567     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
568     * <BR /><BR /><UL CLASS=JDUL>
569     * <LI><CODE>{@link CacheStorage.Cache}[] (<B>caches</B></CODE>)
570     *     <BR />Caches for the security origin.
571     * </LI>
572     * </UL> */
573    public static Script<String, JsonObject, CacheStorage.Cache[]> requestCacheNames
574        (String securityOrigin)
575    {
576        // Exception-Check(s) to ensure that if any parameters which are not declared as
577        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
578        
579        if (securityOrigin == null) BRDPC.throwNPE("securityOrigin");
580        
581        final int       webSocketID = 13002000 + counter++;
582        final boolean[] optionals   = { false, };
583        
584        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
585        String requestJSON = WriteJSON.get(
586            parameterTypes.get("requestCacheNames"),
587            parameterNames.get("requestCacheNames"),
588            optionals, webSocketID,
589            "CacheStorage.requestCacheNames",
590            securityOrigin
591        );
592        
593        // 'JSON Binding' ... Converts Browser Response-JSON to 'CacheStorage.Cache[]'
594        Function<JsonObject, CacheStorage.Cache[]> responseProcessor = (JsonObject jo) ->
595            (jo.getJsonArray("caches") == null)
596                ? null
597                : ReadArrJSON.DimN.objArr(jo.getJsonArray("caches"), null, 0, CacheStorage.Cache[].class);
598        
599        // Pass the 'defaultSender' to Script-Constructor
600        // The sender that is used can be changed before executing script.
601        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
602    }
603    
604    /**
605     * Fetches cache entry.
606     * 
607     * @param cacheId Id of cache that contains the entry.
608     * 
609     * @param requestURL URL spec of the request.
610     * 
611     * @param requestHeaders headers of the request.
612     * 
613     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
614     * {@link CacheStorage.CachedResponse}&gt;</CODE>
615     * 
616     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
617     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
618     * {@link CacheStorage.CachedResponse}&gt;</CODE> will be returned.
619     *
620     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
621     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
622      * may be retrieved.</I>
623     *
624     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
625     * <BR /><BR /><UL CLASS=JDUL>
626     * <LI><CODE>{@link CacheStorage.CachedResponse} (<B>response</B></CODE>)
627     *     <BR />Response read from the cache.
628     * </LI>
629     * </UL> */
630    public static Script<String, JsonObject, CacheStorage.CachedResponse> requestCachedResponse
631        (String cacheId, String requestURL, CacheStorage.Header[] requestHeaders)
632    {
633        // Exception-Check(s) to ensure that if any parameters which are not declared as
634        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
635        
636        if (cacheId == null)        BRDPC.throwNPE("cacheId");
637        if (requestURL == null)     BRDPC.throwNPE("requestURL");
638        if (requestHeaders == null) BRDPC.throwNPE("requestHeaders");
639        
640        final int       webSocketID = 13003000 + counter++;
641        final boolean[] optionals   = { false, false, false, };
642        
643        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
644        String requestJSON = WriteJSON.get(
645            parameterTypes.get("requestCachedResponse"),
646            parameterNames.get("requestCachedResponse"),
647            optionals, webSocketID,
648            "CacheStorage.requestCachedResponse",
649            cacheId, requestURL, requestHeaders
650        );
651        
652        // 'JSON Binding' ... Converts Browser Response-JSON to 'CacheStorage.CachedResponse'
653        Function<JsonObject, CacheStorage.CachedResponse> responseProcessor = (JsonObject jo) ->
654            ReadJSON.getObject(jo, "response", CacheStorage.CachedResponse.class, false, true);
655        
656        // Pass the 'defaultSender' to Script-Constructor
657        // The sender that is used can be changed before executing script.
658        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
659    }
660    
661    /**
662     * Requests data from cache.
663     * 
664     * @param cacheId ID of cache to get entries from.
665     * 
666     * @param skipCount Number of records to skip.
667     * <BR /><B>OPTIONAL</B>
668     * 
669     * @param pageSize Number of records to fetch.
670     * <BR /><B>OPTIONAL</B>
671     * 
672     * @param pathFilter If present, only return the entries containing this substring in the path
673     * <BR /><B>OPTIONAL</B>
674     * 
675     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
676     * {@link Ret2}&gt;</CODE>
677     *
678     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
679     * {@link Script#exec()}), and a {@link Promise} returned.
680     *
681     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
682     * (using {@link Promise#await()}), the {@code Ret2} will subsequently
683     * be returned from that call.
684     * 
685     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
686     * in an instance of <B>{@link Ret2}</B>
687     *
688     * <BR /><BR /><UL CLASS=JDUL>
689     * <LI><CODE><B>Ret2.a:</B> {@link CacheStorage.DataEntry}[] (<B>cacheDataEntries</B>)</CODE>
690     *     <BR />Array of object store data entries.
691     *     <BR /><BR /></LI>
692     * <LI><CODE><B>Ret2.b:</B> Number (<B>returnCount</B>)</CODE>
693     *     <BR />Count of returned entries from this storage. If pathFilter is empty, it
694     *     is the count of all entries from this storage.
695     *     </LI>
696     * </UL>
697     */
698    public static Script<String, JsonObject, Ret2<CacheStorage.DataEntry[], Number>> requestEntries
699        (String cacheId, Integer skipCount, Integer pageSize, String pathFilter)
700    {
701        // Exception-Check(s) to ensure that if any parameters which are not declared as
702        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
703        
704        if (cacheId == null) BRDPC.throwNPE("cacheId");
705        
706        final int       webSocketID = 13004000 + counter++;
707        final boolean[] optionals   = { false, true, true, true, };
708        
709        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
710        String requestJSON = WriteJSON.get(
711            parameterTypes.get("requestEntries"),
712            parameterNames.get("requestEntries"),
713            optionals, webSocketID,
714            "CacheStorage.requestEntries",
715            cacheId, skipCount, pageSize, pathFilter
716        );
717        
718        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2'
719        Function<JsonObject, Ret2<CacheStorage.DataEntry[], Number>> 
720            responseProcessor = (JsonObject jo) -> new Ret2<>(
721                (jo.getJsonArray("cacheDataEntries") == null)
722                    ? null
723                    : ReadArrJSON.DimN.objArr(jo.getJsonArray("cacheDataEntries"), null, 0, CacheStorage.DataEntry[].class),
724                ReadNumberJSON.get(jo, "returnCount", false, true)
725            );
726        
727        // Pass the 'defaultSender' to Script-Constructor
728        // The sender that is used can be changed before executing script.
729        return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor);
730    }
731    
732}