001package Torello.Browser.BrowserAPI;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Browser.BrowserEvent;
013import Torello.Browser.JavaScriptAPI.*;
014import Torello.Browser.helper.*;
015
016import Torello.Java.Additional.*;
017import Torello.Java.JSON.*;
018
019import static Torello.Java.JSON.JFlag.*;
020
021import Torello.Java.StrCmpr;
022import Torello.JavaDoc.StaticFunctional;
023import Torello.JavaDoc.JDHeaderBackgroundImg;
024import Torello.JavaDoc.Excuse;
025
026/**
027 * <SPAN CLASS=COPIEDJDK><B><CODE>[No Description Provided by Google]</CODE></B></SPAN>
028 * 
029 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
030 */
031@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
032@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
033public class FileSystem
034{
035    // ********************************************************************************************
036    // ********************************************************************************************
037    // Class Header Stuff
038    // ********************************************************************************************
039    // ********************************************************************************************
040
041
042    // No Pubic Constructors
043    private FileSystem () { }
044
045    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
046    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
047    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
048    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
049
050    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
051    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
052    // offically, two empty-vectors.  One for String's, and the other for Classes.
053
054    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
055    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
056
057    static
058    {
059        for (Method m : FileSystem.class.getMethods())
060        {
061            // This doesn't work!  The parameter names are all "arg0" ... "argN"
062            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
063            //
064            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
065
066            Vector<Class<?>> parameterTypesList = new Vector<>();
067        
068            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
069
070            parameterTypes.put(
071                m.getName(),
072                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
073            );
074        }
075    }
076
077    static
078    {
079        Vector<String> v = null;
080
081        v = new Vector<String>(1);
082        parameterNames.put("getDirectory", v);
083        Collections.addAll(v, new String[]
084        { "bucketFileSystemLocator", });
085    }
086
087
088    // ********************************************************************************************
089    // ********************************************************************************************
090    // Types - Static Inner Classes
091    // ********************************************************************************************
092    // ********************************************************************************************
093
094    /** <CODE>[No Description Provided by Google]</CODE> */
095    public static class File
096        extends BaseType
097        implements java.io.Serializable
098    {
099        /** For Object Serialization.  java.io.Serializable */
100        protected static final long serialVersionUID = 1;
101        
102        public boolean[] optionals()
103        { return new boolean[] { false, false, false, false, }; }
104        
105        /** <CODE>[No Description Provided by Google]</CODE> */
106        public final String name;
107        
108        /** Timestamp */
109        public final Number lastModified;
110        
111        /** Size in bytes */
112        public final Number size;
113        
114        /** <CODE>[No Description Provided by Google]</CODE> */
115        public final String type;
116        
117        /**
118         * Constructor
119         *
120         * @param name -
121         * 
122         * @param lastModified Timestamp
123         * 
124         * @param size Size in bytes
125         * 
126         * @param type -
127         */
128        public File(String name, Number lastModified, Number size, String type)
129        {
130            // Exception-Check(s) to ensure that if any parameters which are not declared as
131            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
132            
133            if (name == null)         THROWS.throwNPE("name");
134            if (lastModified == null) THROWS.throwNPE("lastModified");
135            if (size == null)         THROWS.throwNPE("size");
136            if (type == null)         THROWS.throwNPE("type");
137            
138            this.name          = name;
139            this.lastModified  = lastModified;
140            this.size          = size;
141            this.type          = type;
142        }
143        
144        /**
145         * JSON Object Constructor
146         * @param jo A Json-Object having data about an instance of {@code 'File'}.
147         */
148        public File (JsonObject jo)
149        {
150            this.name          = ReadJSON.getString(jo, "name", false, true);
151            this.lastModified  = ReadNumberJSON.get(jo, "lastModified", false, true);
152            this.size          = ReadNumberJSON.get(jo, "size", false, true);
153            this.type          = ReadJSON.getString(jo, "type", false, true);
154        }
155        
156        
157        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
158        public boolean equals(Object other)
159        {
160            if (this == other)                       return true;
161            if (other == null)                       return false;
162            if (other.getClass() != this.getClass()) return false;
163        
164            File o = (File) other;
165        
166            return
167                    Objects.equals(this.name, o.name)
168                &&  Objects.equals(this.lastModified, o.lastModified)
169                &&  Objects.equals(this.size, o.size)
170                &&  Objects.equals(this.type, o.type);
171        }
172        
173        /** Generates a Hash-Code for {@code 'this'} instance */
174        public int hashCode()
175        {
176            return
177                    Objects.hashCode(this.name)
178                +   Objects.hashCode(this.lastModified)
179                +   Objects.hashCode(this.size)
180                +   Objects.hashCode(this.type);
181        }
182    }
183    
184    /** <CODE>[No Description Provided by Google]</CODE> */
185    public static class Directory
186        extends BaseType
187        implements java.io.Serializable
188    {
189        /** For Object Serialization.  java.io.Serializable */
190        protected static final long serialVersionUID = 1;
191        
192        public boolean[] optionals()
193        { return new boolean[] { false, false, false, }; }
194        
195        /** <CODE>[No Description Provided by Google]</CODE> */
196        public final String name;
197        
198        /** <CODE>[No Description Provided by Google]</CODE> */
199        public final String[] nestedDirectories;
200        
201        /** Files that are directly nested under this directory. */
202        public final FileSystem.File[] nestedFiles;
203        
204        /**
205         * Constructor
206         *
207         * @param name -
208         * 
209         * @param nestedDirectories -
210         * 
211         * @param nestedFiles Files that are directly nested under this directory.
212         */
213        public Directory(String name, String[] nestedDirectories, FileSystem.File[] nestedFiles)
214        {
215            // Exception-Check(s) to ensure that if any parameters which are not declared as
216            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
217            
218            if (name == null)              THROWS.throwNPE("name");
219            if (nestedDirectories == null) THROWS.throwNPE("nestedDirectories");
220            if (nestedFiles == null)       THROWS.throwNPE("nestedFiles");
221            
222            this.name               = name;
223            this.nestedDirectories  = nestedDirectories;
224            this.nestedFiles        = nestedFiles;
225        }
226        
227        /**
228         * JSON Object Constructor
229         * @param jo A Json-Object having data about an instance of {@code 'Directory'}.
230         */
231        public Directory (JsonObject jo)
232        {
233            this.name               = ReadJSON.getString(jo, "name", false, true);
234            this.nestedDirectories = (jo.getJsonArray("nestedDirectories") == null)
235                ? null
236                : RJArrIntoStream.strArr(jo.getJsonArray("nestedDirectories"), null, 0).toArray(String[]::new);
237        
238            this.nestedFiles = (jo.getJsonArray("nestedFiles") == null)
239                ? null
240                : RJArrIntoStream.objArr(jo.getJsonArray("nestedFiles"), null, 0, FileSystem.File.class).toArray(FileSystem.File[]::new);
241        
242        }
243        
244        
245        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
246        public boolean equals(Object other)
247        {
248            if (this == other)                       return true;
249            if (other == null)                       return false;
250            if (other.getClass() != this.getClass()) return false;
251        
252            Directory o = (Directory) other;
253        
254            return
255                    Objects.equals(this.name, o.name)
256                &&  Arrays.deepEquals(this.nestedDirectories, o.nestedDirectories)
257                &&  Arrays.deepEquals(this.nestedFiles, o.nestedFiles);
258        }
259        
260        /** Generates a Hash-Code for {@code 'this'} instance */
261        public int hashCode()
262        {
263            return
264                    Objects.hashCode(this.name)
265                +   Arrays.deepHashCode(this.nestedDirectories)
266                +   Arrays.deepHashCode(this.nestedFiles);
267        }
268    }
269    
270    /** <CODE>[No Description Provided by Google]</CODE> */
271    public static class BucketFileSystemLocator
272        extends BaseType
273        implements java.io.Serializable
274    {
275        /** For Object Serialization.  java.io.Serializable */
276        protected static final long serialVersionUID = 1;
277        
278        public boolean[] optionals()
279        { return new boolean[] { false, true, false, }; }
280        
281        /** Storage key */
282        public final String storageKey;
283        
284        /**
285         * Bucket name. Not passing a {@code bucketName} will retrieve the default Bucket. (https://developer.mozilla.org/en-US/docs/Web/API/Storage_API#storage_buckets)
286         * <BR /><B CLASS=Opt>OPTIONAL</B>
287         */
288        public final String bucketName;
289        
290        /** Path to the directory using each path component as an array item. */
291        public final String[] pathComponents;
292        
293        /**
294         * Constructor
295         *
296         * @param storageKey Storage key
297         * 
298         * @param bucketName Bucket name. Not passing a {@code bucketName} will retrieve the default Bucket. (https://developer.mozilla.org/en-US/docs/Web/API/Storage_API#storage_buckets)
299         * <BR /><B CLASS=Opt>OPTIONAL</B>
300         * 
301         * @param pathComponents Path to the directory using each path component as an array item.
302         */
303        public BucketFileSystemLocator
304            (String storageKey, String bucketName, String[] pathComponents)
305        {
306            // Exception-Check(s) to ensure that if any parameters which are not declared as
307            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
308            
309            if (storageKey == null)     THROWS.throwNPE("storageKey");
310            if (pathComponents == null) THROWS.throwNPE("pathComponents");
311            
312            this.storageKey      = storageKey;
313            this.bucketName      = bucketName;
314            this.pathComponents  = pathComponents;
315        }
316        
317        /**
318         * JSON Object Constructor
319         * @param jo A Json-Object having data about an instance of {@code 'BucketFileSystemLocator'}.
320         */
321        public BucketFileSystemLocator (JsonObject jo)
322        {
323            this.storageKey      = ReadJSON.getString(jo, "storageKey", false, true);
324            this.bucketName      = ReadJSON.getString(jo, "bucketName", true, false);
325            this.pathComponents = (jo.getJsonArray("pathComponents") == null)
326                ? null
327                : RJArrIntoStream.strArr(jo.getJsonArray("pathComponents"), null, 0).toArray(String[]::new);
328        
329        }
330        
331        
332        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
333        public boolean equals(Object other)
334        {
335            if (this == other)                       return true;
336            if (other == null)                       return false;
337            if (other.getClass() != this.getClass()) return false;
338        
339            BucketFileSystemLocator o = (BucketFileSystemLocator) other;
340        
341            return
342                    Objects.equals(this.storageKey, o.storageKey)
343                &&  Objects.equals(this.bucketName, o.bucketName)
344                &&  Arrays.deepEquals(this.pathComponents, o.pathComponents);
345        }
346        
347        /** Generates a Hash-Code for {@code 'this'} instance */
348        public int hashCode()
349        {
350            return
351                    Objects.hashCode(this.storageKey)
352                +   Objects.hashCode(this.bucketName)
353                +   Arrays.deepHashCode(this.pathComponents);
354        }
355    }
356    
357    
358    // Counter for keeping the WebSocket Request ID's distinct.
359    private static int counter = 1;
360    
361    /**
362     * <CODE>[No Description Provided by Google]</CODE>
363     * 
364     * @param bucketFileSystemLocator -
365     * 
366     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
367     * {@link FileSystem.Directory}&gt;</CODE>
368     * 
369     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
370     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
371     * {@link FileSystem.Directory}&gt;</CODE> will be returned.
372     *
373     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
374     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
375      * may be retrieved.</I>
376     *
377     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
378     * <BR /><BR /><UL CLASS=JDUL>
379     * <LI><CODE>{@link FileSystem.Directory} (<B>directory</B></CODE>)
380     *     <BR />Returns the directory object at the path.
381     * </LI>
382     * </UL> */
383    public static Script<String, JsonObject, FileSystem.Directory> getDirectory
384        (FileSystem.BucketFileSystemLocator bucketFileSystemLocator)
385    {
386        // Exception-Check(s) to ensure that if any parameters which are not declared as
387        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
388        
389        if (bucketFileSystemLocator == null) THROWS.throwNPE("bucketFileSystemLocator");
390        
391        final int       webSocketID = 26000000 + counter++;
392        final boolean[] optionals   = { false, };
393        
394        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
395        String requestJSON = WriteJSON.get(
396            parameterTypes.get("getDirectory"),
397            parameterNames.get("getDirectory"),
398            optionals, webSocketID,
399            "FileSystem.getDirectory",
400            bucketFileSystemLocator
401        );
402        
403        // 'JSON Binding' ... Converts Browser Response-JSON to 'FileSystem.Directory'
404        Function<JsonObject, FileSystem.Directory> responseProcessor = (JsonObject jo) ->
405            ReadJSON.getObject(jo, "directory", FileSystem.Directory.class, false, true);
406        
407        return new Script<>(webSocketID, requestJSON, responseProcessor);
408    }
409    
410}