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)         THROWS.throwNPE("requestURL");
180            if (requestMethod == null)      THROWS.throwNPE("requestMethod");
181            if (requestHeaders == null)     THROWS.throwNPE("requestHeaders");
182            if (responseTime == null)       THROWS.throwNPE("responseTime");
183            if (responseStatusText == null) THROWS.throwNPE("responseStatusText");
184            if (responseType == null)       THROWS.throwNPE("responseType");
185            if (responseHeaders == null)    THROWS.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            THROWS.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                : RJArrIntoStream.objArr(jo.getJsonArray("requestHeaders"), null, 0, CacheStorage.Header.class).toArray(CacheStorage.Header[]::new);
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                : RJArrIntoStream.objArr(jo.getJsonArray("responseHeaders"), null, 0, CacheStorage.Header.class).toArray(CacheStorage.Header[]::new);
221        
222        }
223        
224        
225        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
226        public boolean equals(Object other)
227        {
228            if (this == other)                       return true;
229            if (other == null)                       return false;
230            if (other.getClass() != this.getClass()) return false;
231        
232            DataEntry o = (DataEntry) other;
233        
234            return
235                    Objects.equals(this.requestURL, o.requestURL)
236                &&  Objects.equals(this.requestMethod, o.requestMethod)
237                &&  Arrays.deepEquals(this.requestHeaders, o.requestHeaders)
238                &&  Objects.equals(this.responseTime, o.responseTime)
239                &&  (this.responseStatus == o.responseStatus)
240                &&  Objects.equals(this.responseStatusText, o.responseStatusText)
241                &&  Objects.equals(this.responseType, o.responseType)
242                &&  Arrays.deepEquals(this.responseHeaders, o.responseHeaders);
243        }
244        
245        /** Generates a Hash-Code for {@code 'this'} instance */
246        public int hashCode()
247        {
248            return
249                    Objects.hashCode(this.requestURL)
250                +   Objects.hashCode(this.requestMethod)
251                +   Arrays.deepHashCode(this.requestHeaders)
252                +   Objects.hashCode(this.responseTime)
253                +   this.responseStatus
254                +   Objects.hashCode(this.responseStatusText)
255                +   Objects.hashCode(this.responseType)
256                +   Arrays.deepHashCode(this.responseHeaders);
257        }
258    }
259    
260    /** Cache identifier. */
261    public static class Cache
262        extends BaseType
263        implements java.io.Serializable
264    {
265        /** For Object Serialization.  java.io.Serializable */
266        protected static final long serialVersionUID = 1;
267        
268        public boolean[] optionals()
269        { return new boolean[] { false, false, false, }; }
270        
271        /** An opaque unique id of the cache. */
272        public final String cacheId;
273        
274        /** Security origin of the cache. */
275        public final String securityOrigin;
276        
277        /** The name of the cache. */
278        public final String cacheName;
279        
280        /**
281         * Constructor
282         *
283         * @param cacheId An opaque unique id of the cache.
284         * 
285         * @param securityOrigin Security origin of the cache.
286         * 
287         * @param cacheName The name of the cache.
288         */
289        public Cache(String cacheId, String securityOrigin, String cacheName)
290        {
291            // Exception-Check(s) to ensure that if any parameters which are not declared as
292            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
293            
294            if (cacheId == null)        THROWS.throwNPE("cacheId");
295            if (securityOrigin == null) THROWS.throwNPE("securityOrigin");
296            if (cacheName == null)      THROWS.throwNPE("cacheName");
297            
298            this.cacheId         = cacheId;
299            this.securityOrigin  = securityOrigin;
300            this.cacheName       = cacheName;
301        }
302        
303        /**
304         * JSON Object Constructor
305         * @param jo A Json-Object having data about an instance of {@code 'Cache'}.
306         */
307        public Cache (JsonObject jo)
308        {
309            this.cacheId         = ReadJSON.getString(jo, "cacheId", false, true);
310            this.securityOrigin  = ReadJSON.getString(jo, "securityOrigin", false, true);
311            this.cacheName       = ReadJSON.getString(jo, "cacheName", false, true);
312        }
313        
314        
315        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
316        public boolean equals(Object other)
317        {
318            if (this == other)                       return true;
319            if (other == null)                       return false;
320            if (other.getClass() != this.getClass()) return false;
321        
322            Cache o = (Cache) other;
323        
324            return
325                    Objects.equals(this.cacheId, o.cacheId)
326                &&  Objects.equals(this.securityOrigin, o.securityOrigin)
327                &&  Objects.equals(this.cacheName, o.cacheName);
328        }
329        
330        /** Generates a Hash-Code for {@code 'this'} instance */
331        public int hashCode()
332        {
333            return
334                    Objects.hashCode(this.cacheId)
335                +   Objects.hashCode(this.securityOrigin)
336                +   Objects.hashCode(this.cacheName);
337        }
338    }
339    
340    /** <CODE>[No Description Provided by Google]</CODE> */
341    public static class Header
342        extends BaseType
343        implements java.io.Serializable
344    {
345        /** For Object Serialization.  java.io.Serializable */
346        protected static final long serialVersionUID = 1;
347        
348        public boolean[] optionals()
349        { return new boolean[] { false, false, }; }
350        
351        /** <CODE>[No Description Provided by Google]</CODE> */
352        public final String name;
353        
354        /** <CODE>[No Description Provided by Google]</CODE> */
355        public final String value;
356        
357        /**
358         * Constructor
359         *
360         * @param name -
361         * 
362         * @param value -
363         */
364        public Header(String name, String value)
365        {
366            // Exception-Check(s) to ensure that if any parameters which are not declared as
367            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
368            
369            if (name == null)  THROWS.throwNPE("name");
370            if (value == null) THROWS.throwNPE("value");
371            
372            this.name   = name;
373            this.value  = value;
374        }
375        
376        /**
377         * JSON Object Constructor
378         * @param jo A Json-Object having data about an instance of {@code 'Header'}.
379         */
380        public Header (JsonObject jo)
381        {
382            this.name   = ReadJSON.getString(jo, "name", false, true);
383            this.value  = ReadJSON.getString(jo, "value", false, true);
384        }
385        
386        
387        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
388        public boolean equals(Object other)
389        {
390            if (this == other)                       return true;
391            if (other == null)                       return false;
392            if (other.getClass() != this.getClass()) return false;
393        
394            Header o = (Header) other;
395        
396            return
397                    Objects.equals(this.name, o.name)
398                &&  Objects.equals(this.value, o.value);
399        }
400        
401        /** Generates a Hash-Code for {@code 'this'} instance */
402        public int hashCode()
403        {
404            return
405                    Objects.hashCode(this.name)
406                +   Objects.hashCode(this.value);
407        }
408    }
409    
410    /** Cached response */
411    public static class CachedResponse
412        extends BaseType
413        implements java.io.Serializable
414    {
415        /** For Object Serialization.  java.io.Serializable */
416        protected static final long serialVersionUID = 1;
417        
418        public boolean[] optionals()
419        { return new boolean[] { false, }; }
420        
421        /** Entry content, base64-encoded. (Encoded as a base64 string when passed over JSON) */
422        public final String body;
423        
424        /**
425         * Constructor
426         *
427         * @param body Entry content, base64-encoded. (Encoded as a base64 string when passed over JSON)
428         */
429        public CachedResponse(String body)
430        {
431            // Exception-Check(s) to ensure that if any parameters which are not declared as
432            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
433            
434            if (body == null) THROWS.throwNPE("body");
435            
436            this.body  = body;
437        }
438        
439        /**
440         * JSON Object Constructor
441         * @param jo A Json-Object having data about an instance of {@code 'CachedResponse'}.
442         */
443        public CachedResponse (JsonObject jo)
444        {
445            this.body  = ReadJSON.getString(jo, "body", false, true);
446        }
447        
448        
449        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
450        public boolean equals(Object other)
451        {
452            if (this == other)                       return true;
453            if (other == null)                       return false;
454            if (other.getClass() != this.getClass()) return false;
455        
456            CachedResponse o = (CachedResponse) other;
457        
458            return
459                    Objects.equals(this.body, o.body);
460        }
461        
462        /** Generates a Hash-Code for {@code 'this'} instance */
463        public int hashCode()
464        {
465            return
466                    Objects.hashCode(this.body);
467        }
468    }
469    
470    
471    // Counter for keeping the WebSocket Request ID's distinct.
472    private static int counter = 1;
473    
474    /**
475     * Deletes a cache.
476     * 
477     * @param cacheId Id of cache for deletion.
478     * 
479     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
480     * {@link Ret0}&gt;</CODE>
481     *
482     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
483     * browser receives the invocation-request.
484     *
485     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
486     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
487     * {@code >} to ensure the Browser Function has run to completion.
488     */
489    public static Script<String, JsonObject, Ret0> deleteCache(String cacheId)
490    {
491        // Exception-Check(s) to ensure that if any parameters which are not declared as
492        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
493        
494        if (cacheId == null) THROWS.throwNPE("cacheId");
495        
496        final int       webSocketID = 13000000 + counter++;
497        final boolean[] optionals   = { false, };
498        
499        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
500        String requestJSON = WriteJSON.get(
501            parameterTypes.get("deleteCache"),
502            parameterNames.get("deleteCache"),
503            optionals, webSocketID,
504            "CacheStorage.deleteCache",
505            cacheId
506        );
507        
508        // This Remote Command does not have a Return-Value.
509        return new Script<>
510            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
511    }
512    
513    /**
514     * Deletes a cache entry.
515     * 
516     * @param cacheId Id of cache where the entry will be deleted.
517     * 
518     * @param request URL spec of the request.
519     * 
520     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
521     * {@link Ret0}&gt;</CODE>
522     *
523     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
524     * browser receives the invocation-request.
525     *
526     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
527     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
528     * {@code >} to ensure the Browser Function has run to completion.
529     */
530    public static Script<String, JsonObject, Ret0> deleteEntry(String cacheId, String request)
531    {
532        // Exception-Check(s) to ensure that if any parameters which are not declared as
533        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
534        
535        if (cacheId == null) THROWS.throwNPE("cacheId");
536        if (request == null) THROWS.throwNPE("request");
537        
538        final int       webSocketID = 13001000 + counter++;
539        final boolean[] optionals   = { false, false, };
540        
541        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
542        String requestJSON = WriteJSON.get(
543            parameterTypes.get("deleteEntry"),
544            parameterNames.get("deleteEntry"),
545            optionals, webSocketID,
546            "CacheStorage.deleteEntry",
547            cacheId, request
548        );
549        
550        // This Remote Command does not have a Return-Value.
551        return new Script<>
552            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
553    }
554    
555    /**
556     * Requests cache names.
557     * 
558     * @param securityOrigin Security origin.
559     * 
560     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
561     * {@link CacheStorage.Cache}[]&gt;</CODE>
562     * 
563     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
564     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
565     * {@link CacheStorage.Cache}[]&gt;</CODE> will be returned.
566     *
567     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
568     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
569      * may be retrieved.</I>
570     *
571     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
572     * <BR /><BR /><UL CLASS=JDUL>
573     * <LI><CODE>{@link CacheStorage.Cache}[] (<B>caches</B></CODE>)
574     *     <BR />Caches for the security origin.
575     * </LI>
576     * </UL> */
577    public static Script<String, JsonObject, CacheStorage.Cache[]> requestCacheNames
578        (String securityOrigin)
579    {
580        // Exception-Check(s) to ensure that if any parameters which are not declared as
581        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
582        
583        if (securityOrigin == null) THROWS.throwNPE("securityOrigin");
584        
585        final int       webSocketID = 13002000 + counter++;
586        final boolean[] optionals   = { false, };
587        
588        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
589        String requestJSON = WriteJSON.get(
590            parameterTypes.get("requestCacheNames"),
591            parameterNames.get("requestCacheNames"),
592            optionals, webSocketID,
593            "CacheStorage.requestCacheNames",
594            securityOrigin
595        );
596        
597        // 'JSON Binding' ... Converts Browser Response-JSON to 'CacheStorage.Cache[]'
598        Function<JsonObject, CacheStorage.Cache[]> responseProcessor = (JsonObject jo) ->
599            (jo.getJsonArray("caches") == null)
600                ? null
601                : RJArrIntoStream.objArr(jo.getJsonArray("caches"), null, 0, CacheStorage.Cache.class).toArray(CacheStorage.Cache[]::new);
602        
603        return new Script<>(webSocketID, requestJSON, responseProcessor);
604    }
605    
606    /**
607     * Fetches cache entry.
608     * 
609     * @param cacheId Id of cache that contains the entry.
610     * 
611     * @param requestURL URL spec of the request.
612     * 
613     * @param requestHeaders headers of the request.
614     * 
615     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
616     * {@link CacheStorage.CachedResponse}&gt;</CODE>
617     * 
618     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
619     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
620     * {@link CacheStorage.CachedResponse}&gt;</CODE> will be returned.
621     *
622     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
623     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
624      * may be retrieved.</I>
625     *
626     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
627     * <BR /><BR /><UL CLASS=JDUL>
628     * <LI><CODE>{@link CacheStorage.CachedResponse} (<B>response</B></CODE>)
629     *     <BR />Response read from the cache.
630     * </LI>
631     * </UL> */
632    public static Script<String, JsonObject, CacheStorage.CachedResponse> requestCachedResponse
633        (String cacheId, String requestURL, CacheStorage.Header[] requestHeaders)
634    {
635        // Exception-Check(s) to ensure that if any parameters which are not declared as
636        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
637        
638        if (cacheId == null)        THROWS.throwNPE("cacheId");
639        if (requestURL == null)     THROWS.throwNPE("requestURL");
640        if (requestHeaders == null) THROWS.throwNPE("requestHeaders");
641        
642        final int       webSocketID = 13003000 + counter++;
643        final boolean[] optionals   = { false, false, false, };
644        
645        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
646        String requestJSON = WriteJSON.get(
647            parameterTypes.get("requestCachedResponse"),
648            parameterNames.get("requestCachedResponse"),
649            optionals, webSocketID,
650            "CacheStorage.requestCachedResponse",
651            cacheId, requestURL, requestHeaders
652        );
653        
654        // 'JSON Binding' ... Converts Browser Response-JSON to 'CacheStorage.CachedResponse'
655        Function<JsonObject, CacheStorage.CachedResponse> responseProcessor = (JsonObject jo) ->
656            ReadJSON.getObject(jo, "response", CacheStorage.CachedResponse.class, false, true);
657        
658        return new Script<>(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) THROWS.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                    : RJArrIntoStream.objArr(jo.getJsonArray("cacheDataEntries"), null, 0, CacheStorage.DataEntry.class).toArray(CacheStorage.DataEntry[]::new),
724                ReadNumberJSON.get(jo, "returnCount", false, true)
725            );
726        
727        return new Script<>(webSocketID, requestJSON, responseProcessor);
728    }
729    
730}