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 Database 030{ 031 // ******************************************************************************************** 032 // ******************************************************************************************** 033 // Class Header Stuff 034 // ******************************************************************************************** 035 // ******************************************************************************************** 036 037 038 // No Pubic Constructors 039 private Database () { } 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 : Database.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 parameterNames.put("disable", EMPTY_VEC_STR); 078 079 parameterNames.put("enable", EMPTY_VEC_STR); 080 081 v = new Vector<String>(2); 082 parameterNames.put("executeSQL", v); 083 Collections.addAll(v, new String[] 084 { "databaseId", "query", }); 085 086 v = new Vector<String>(1); 087 parameterNames.put("getDatabaseTableNames", v); 088 Collections.addAll(v, new String[] 089 { "databaseId", }); 090 } 091 092 093 // ******************************************************************************************** 094 // ******************************************************************************************** 095 // Types - Static Inner Classes 096 // ******************************************************************************************** 097 // ******************************************************************************************** 098 099 // public static class DatabaseId => String 100 101 /** Database object. */ 102 public static class _Database 103 extends BaseType 104 implements java.io.Serializable 105 { 106 /** For Object Serialization. java.io.Serializable */ 107 protected static final long serialVersionUID = 1; 108 109 public boolean[] optionals() 110 { return new boolean[] { false, false, false, false, }; } 111 112 /** Database ID. */ 113 public final String id; 114 115 /** Database domain. */ 116 public final String domain; 117 118 /** Database name. */ 119 public final String name; 120 121 /** Database version. */ 122 public final String version; 123 124 /** 125 * Constructor 126 * 127 * @param id Database ID. 128 * 129 * @param domain Database domain. 130 * 131 * @param name Database name. 132 * 133 * @param version Database version. 134 */ 135 public _Database(String id, String domain, String name, String version) 136 { 137 // Exception-Check(s) to ensure that if any parameters which are not declared as 138 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 139 140 if (id == null) THROWS.throwNPE("id"); 141 if (domain == null) THROWS.throwNPE("domain"); 142 if (name == null) THROWS.throwNPE("name"); 143 if (version == null) THROWS.throwNPE("version"); 144 145 this.id = id; 146 this.domain = domain; 147 this.name = name; 148 this.version = version; 149 } 150 151 /** 152 * JSON Object Constructor 153 * @param jo A Json-Object having data about an instance of {@code 'Database'}. 154 */ 155 public _Database (JsonObject jo) 156 { 157 this.id = ReadJSON.getString(jo, "id", false, true); 158 this.domain = ReadJSON.getString(jo, "domain", false, true); 159 this.name = ReadJSON.getString(jo, "name", false, true); 160 this.version = ReadJSON.getString(jo, "version", false, true); 161 } 162 163 164 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 165 public boolean equals(Object other) 166 { 167 if (this == other) return true; 168 if (other == null) return false; 169 if (other.getClass() != this.getClass()) return false; 170 171 _Database o = (_Database) other; 172 173 return 174 Objects.equals(this.id, o.id) 175 && Objects.equals(this.domain, o.domain) 176 && Objects.equals(this.name, o.name) 177 && Objects.equals(this.version, o.version); 178 } 179 180 /** Generates a Hash-Code for {@code 'this'} instance */ 181 public int hashCode() 182 { 183 return 184 Objects.hashCode(this.id) 185 + Objects.hashCode(this.domain) 186 + Objects.hashCode(this.name) 187 + Objects.hashCode(this.version); 188 } 189 } 190 191 /** Database error. */ 192 public static class Error 193 extends BaseType 194 implements java.io.Serializable 195 { 196 /** For Object Serialization. java.io.Serializable */ 197 protected static final long serialVersionUID = 1; 198 199 public boolean[] optionals() 200 { return new boolean[] { false, false, }; } 201 202 /** Error message. */ 203 public final String message; 204 205 /** Error code. */ 206 public final int code; 207 208 /** 209 * Constructor 210 * 211 * @param message Error message. 212 * 213 * @param code Error code. 214 */ 215 public Error(String message, int code) 216 { 217 // Exception-Check(s) to ensure that if any parameters which are not declared as 218 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 219 220 if (message == null) THROWS.throwNPE("message"); 221 222 this.message = message; 223 this.code = code; 224 } 225 226 /** 227 * JSON Object Constructor 228 * @param jo A Json-Object having data about an instance of {@code 'Error'}. 229 */ 230 public Error (JsonObject jo) 231 { 232 this.message = ReadJSON.getString(jo, "message", false, true); 233 this.code = ReadPrimJSON.getInt(jo, "code"); 234 } 235 236 237 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 238 public boolean equals(Object other) 239 { 240 if (this == other) return true; 241 if (other == null) return false; 242 if (other.getClass() != this.getClass()) return false; 243 244 Error o = (Error) other; 245 246 return 247 Objects.equals(this.message, o.message) 248 && (this.code == o.code); 249 } 250 251 /** Generates a Hash-Code for {@code 'this'} instance */ 252 public int hashCode() 253 { 254 return 255 Objects.hashCode(this.message) 256 + this.code; 257 } 258 } 259 260 /** <CODE>[No Description Provided by Google]</CODE> */ 261 public static class addDatabase 262 extends BrowserEvent 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, }; } 270 271 /** <CODE>[No Description Provided by Google]</CODE> */ 272 public final Database._Database database; 273 274 /** 275 * Constructor 276 * 277 * @param database - 278 */ 279 public addDatabase(Database._Database database) 280 { 281 super("Database", "addDatabase", 1); 282 283 // Exception-Check(s) to ensure that if any parameters which are not declared as 284 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 285 286 if (database == null) THROWS.throwNPE("database"); 287 288 this.database = database; 289 } 290 291 /** 292 * JSON Object Constructor 293 * @param jo A Json-Object having data about an instance of {@code 'addDatabase'}. 294 */ 295 public addDatabase (JsonObject jo) 296 { 297 super("Database", "addDatabase", 1); 298 299 this.database = ReadJSON.getObject(jo, "database", Database._Database.class, false, true); 300 } 301 302 303 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 304 public boolean equals(Object other) 305 { 306 if (this == other) return true; 307 if (other == null) return false; 308 if (other.getClass() != this.getClass()) return false; 309 310 addDatabase o = (addDatabase) other; 311 312 return 313 Objects.equals(this.database, o.database); 314 } 315 316 /** Generates a Hash-Code for {@code 'this'} instance */ 317 public int hashCode() 318 { 319 return 320 this.database.hashCode(); 321 } 322 } 323 324 325 // Counter for keeping the WebSocket Request ID's distinct. 326 private static int counter = 1; 327 328 /** 329 * Disables database tracking, prevents database events from being sent to the client. 330 * 331 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 332 * {@link Ret0}></CODE> 333 * 334 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 335 * browser receives the invocation-request. 336 * 337 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 338 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 339 * {@code >} to ensure the Browser Function has run to completion. 340 */ 341 public static Script<String, JsonObject, Ret0> disable() 342 { 343 final int webSocketID = 19000000 + counter++; 344 final boolean[] optionals = new boolean[0]; 345 346 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 347 String requestJSON = WriteJSON.get( 348 parameterTypes.get("disable"), 349 parameterNames.get("disable"), 350 optionals, webSocketID, 351 "Database.disable" 352 ); 353 354 // This Remote Command does not have a Return-Value. 355 return new Script<> 356 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 357 } 358 359 /** 360 * Enables database tracking, database events will now be delivered to the client. 361 * 362 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 363 * {@link Ret0}></CODE> 364 * 365 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 366 * browser receives the invocation-request. 367 * 368 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 369 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 370 * {@code >} to ensure the Browser Function has run to completion. 371 */ 372 public static Script<String, JsonObject, Ret0> enable() 373 { 374 final int webSocketID = 19001000 + counter++; 375 final boolean[] optionals = new boolean[0]; 376 377 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 378 String requestJSON = WriteJSON.get( 379 parameterTypes.get("enable"), 380 parameterNames.get("enable"), 381 optionals, webSocketID, 382 "Database.enable" 383 ); 384 385 // This Remote Command does not have a Return-Value. 386 return new Script<> 387 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 388 } 389 390 /** 391 * <CODE>[No Description Provided by Google]</CODE> 392 * 393 * @param databaseId - 394 * 395 * @param query - 396 * 397 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 398 * {@link Ret3}></CODE> 399 * 400 * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 401 * {@link Script#exec()}), and a {@link Promise} returned. 402 * 403 * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B> 404 * (using {@link Promise#await()}), the {@code Ret3} will subsequently 405 * be returned from that call. 406 * 407 * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated 408 * in an instance of <B>{@link Ret3}</B> 409 * 410 * <BR /><BR /><UL CLASS=JDUL> 411 * <LI><CODE><B>Ret3.a:</B> String[] (<B>columnNames</B>)</CODE> 412 * <BR />- 413 * <BR /><BR /></LI> 414 * <LI><CODE><B>Ret3.b:</B> JsonArray (<B>values</B>)</CODE> 415 * <BR />- 416 * <BR /><BR /></LI> 417 * <LI><CODE><B>Ret3.c:</B> {@link Database.Error} (<B>sqlError</B>)</CODE> 418 * <BR />- 419 * </LI> 420 * </UL> 421 */ 422 public static Script<String, JsonObject, Ret3<String[], JsonArray, Database.Error>> executeSQL 423 (String databaseId, String query) 424 { 425 // Exception-Check(s) to ensure that if any parameters which are not declared as 426 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 427 428 if (databaseId == null) THROWS.throwNPE("databaseId"); 429 if (query == null) THROWS.throwNPE("query"); 430 431 final int webSocketID = 19002000 + counter++; 432 final boolean[] optionals = { false, false, }; 433 434 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 435 String requestJSON = WriteJSON.get( 436 parameterTypes.get("executeSQL"), 437 parameterNames.get("executeSQL"), 438 optionals, webSocketID, 439 "Database.executeSQL", 440 databaseId, query 441 ); 442 443 // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret3' 444 Function<JsonObject, Ret3<String[], JsonArray, Database.Error>> 445 responseProcessor = (JsonObject jo) -> new Ret3<>( 446 (jo.getJsonArray("columnNames") == null) 447 ? null 448 : RJArrIntoStream.strArr(jo.getJsonArray("columnNames"), null, 0).toArray(String[]::new), 449 jo.getJsonArray("values"), 450 ReadJSON.getObject(jo, "sqlError", Database.Error.class, true, false) 451 ); 452 453 return new Script<>(webSocketID, requestJSON, responseProcessor); 454 } 455 456 /** 457 * <CODE>[No Description Provided by Google]</CODE> 458 * 459 * @param databaseId - 460 * 461 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 462 * String[]></CODE> 463 * 464 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 465 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 466 * String[]></CODE> will be returned. 467 * 468 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 469 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 470 * may be retrieved.</I> 471 * 472 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 473 * <BR /><BR /><UL CLASS=JDUL> 474 * <LI><CODE>String[] (<B>tableNames</B></CODE>) 475 * <BR />- 476 * </LI> 477 * </UL> */ 478 public static Script<String, JsonObject, String[]> getDatabaseTableNames(String databaseId) 479 { 480 // Exception-Check(s) to ensure that if any parameters which are not declared as 481 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 482 483 if (databaseId == null) THROWS.throwNPE("databaseId"); 484 485 final int webSocketID = 19003000 + counter++; 486 final boolean[] optionals = { false, }; 487 488 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 489 String requestJSON = WriteJSON.get( 490 parameterTypes.get("getDatabaseTableNames"), 491 parameterNames.get("getDatabaseTableNames"), 492 optionals, webSocketID, 493 "Database.getDatabaseTableNames", 494 databaseId 495 ); 496 497 // 'JSON Binding' ... Converts Browser Response-JSON to 'String[]' 498 Function<JsonObject, String[]> responseProcessor = (JsonObject jo) -> 499 (jo.getJsonArray("tableNames") == null) 500 ? null 501 : RJArrIntoStream.strArr(jo.getJsonArray("tableNames"), null, 0).toArray(String[]::new); 502 503 return new Script<>(webSocketID, requestJSON, responseProcessor); 504 } 505 506}