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}<String, {@link JsonObject}, 367 * {@link FileSystem.Directory}></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><JsonObject, 371 * {@link FileSystem.Directory}></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}