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>Defines events for background web platform features.</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 BackgroundService 030{ 031 // ******************************************************************************************** 032 // ******************************************************************************************** 033 // Class Header Stuff 034 // ******************************************************************************************** 035 // ******************************************************************************************** 036 037 038 // No Pubic Constructors 039 private BackgroundService () { } 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 : BackgroundService.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("startObserving", v); 079 Collections.addAll(v, new String[] 080 { "service", }); 081 082 v = new Vector<String>(1); 083 parameterNames.put("stopObserving", v); 084 Collections.addAll(v, new String[] 085 { "service", }); 086 087 v = new Vector<String>(2); 088 parameterNames.put("setRecording", v); 089 Collections.addAll(v, new String[] 090 { "shouldRecord", "service", }); 091 092 v = new Vector<String>(1); 093 parameterNames.put("clearEvents", v); 094 Collections.addAll(v, new String[] 095 { "service", }); 096 } 097 098 099 // ******************************************************************************************** 100 // ******************************************************************************************** 101 // Types - Static Inner Classes 102 // ******************************************************************************************** 103 // ******************************************************************************************** 104 105 /** 106 * The Background Service that will be associated with the commands/events. 107 * Every Background Service operates independently, but they share the same 108 * API. 109 */ 110 public static final String[] ServiceName = 111 { 112 "backgroundFetch", "backgroundSync", "pushMessaging", "notifications", "paymentHandler", 113 "periodicBackgroundSync", 114 }; 115 116 /** A key-value pair for additional event information to pass along. */ 117 public static class EventMetadata 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, }; } 126 127 /** <CODE>[No Description Provided by Google]</CODE> */ 128 public final String key; 129 130 /** <CODE>[No Description Provided by Google]</CODE> */ 131 public final String value; 132 133 /** 134 * Constructor 135 * 136 * @param key - 137 * 138 * @param value - 139 */ 140 public EventMetadata(String key, String value) 141 { 142 // Exception-Check(s) to ensure that if any parameters which are not declared as 143 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 144 145 if (key == null) BRDPC.throwNPE("key"); 146 if (value == null) BRDPC.throwNPE("value"); 147 148 this.key = key; 149 this.value = value; 150 } 151 152 /** 153 * JSON Object Constructor 154 * @param jo A Json-Object having data about an instance of {@code 'EventMetadata'}. 155 */ 156 public EventMetadata (JsonObject jo) 157 { 158 this.key = ReadJSON.getString(jo, "key", false, true); 159 this.value = ReadJSON.getString(jo, "value", false, true); 160 } 161 162 163 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 164 public boolean equals(Object other) 165 { 166 if (other == null) return false; 167 if (other.getClass() != this.getClass()) return false; 168 169 EventMetadata o = (EventMetadata) other; 170 171 return 172 Objects.equals(this.key, o.key) 173 && Objects.equals(this.value, o.value); 174 } 175 176 /** Generates a Hash-Code for {@code 'this'} instance */ 177 public int hashCode() 178 { 179 return 180 Objects.hashCode(this.key) 181 + Objects.hashCode(this.value); 182 } 183 } 184 185 /** <CODE>[No Description Provided by Google]</CODE> */ 186 public static class BackgroundServiceEvent 187 extends BaseType 188 implements java.io.Serializable 189 { 190 /** For Object Serialization. java.io.Serializable */ 191 protected static final long serialVersionUID = 1; 192 193 public boolean[] optionals() 194 { return new boolean[] { false, false, false, false, false, false, false, }; } 195 196 /** Timestamp of the event (in seconds). */ 197 public final Number timestamp; 198 199 /** The origin this event belongs to. */ 200 public final String origin; 201 202 /** The Service Worker ID that initiated the event. */ 203 public final String serviceWorkerRegistrationId; 204 205 /** The Background Service this event belongs to. */ 206 public final String service; 207 208 /** A description of the event. */ 209 public final String eventName; 210 211 /** An identifier that groups related events together. */ 212 public final String instanceId; 213 214 /** A list of event-specific information. */ 215 public final BackgroundService.EventMetadata[] eventMetadata; 216 217 /** 218 * Constructor 219 * 220 * @param timestamp Timestamp of the event (in seconds). 221 * 222 * @param origin The origin this event belongs to. 223 * 224 * @param serviceWorkerRegistrationId The Service Worker ID that initiated the event. 225 * 226 * @param service The Background Service this event belongs to. 227 * 228 * @param eventName A description of the event. 229 * 230 * @param instanceId An identifier that groups related events together. 231 * 232 * @param eventMetadata A list of event-specific information. 233 */ 234 public BackgroundServiceEvent( 235 Number timestamp, String origin, String serviceWorkerRegistrationId, String service, 236 String eventName, String instanceId, BackgroundService.EventMetadata[] eventMetadata 237 ) 238 { 239 // Exception-Check(s) to ensure that if any parameters which are not declared as 240 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 241 242 if (timestamp == null) BRDPC.throwNPE("timestamp"); 243 if (origin == null) BRDPC.throwNPE("origin"); 244 if (serviceWorkerRegistrationId == null) BRDPC.throwNPE("serviceWorkerRegistrationId"); 245 if (service == null) BRDPC.throwNPE("service"); 246 if (eventName == null) BRDPC.throwNPE("eventName"); 247 if (instanceId == null) BRDPC.throwNPE("instanceId"); 248 if (eventMetadata == null) BRDPC.throwNPE("eventMetadata"); 249 250 // Exception-Check(s) to ensure that if any parameters which must adhere to a 251 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 252 253 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 254 255 this.timestamp = timestamp; 256 this.origin = origin; 257 this.serviceWorkerRegistrationId = serviceWorkerRegistrationId; 258 this.service = service; 259 this.eventName = eventName; 260 this.instanceId = instanceId; 261 this.eventMetadata = eventMetadata; 262 } 263 264 /** 265 * JSON Object Constructor 266 * @param jo A Json-Object having data about an instance of {@code 'BackgroundServiceEvent'}. 267 */ 268 public BackgroundServiceEvent (JsonObject jo) 269 { 270 this.timestamp = ReadNumberJSON.get(jo, "timestamp", false, true); 271 this.origin = ReadJSON.getString(jo, "origin", false, true); 272 this.serviceWorkerRegistrationId = ReadJSON.getString(jo, "serviceWorkerRegistrationId", false, true); 273 this.service = ReadJSON.getString(jo, "service", false, true); 274 this.eventName = ReadJSON.getString(jo, "eventName", false, true); 275 this.instanceId = ReadJSON.getString(jo, "instanceId", false, true); 276 this.eventMetadata = (jo.getJsonArray("eventMetadata") == null) 277 ? null 278 : RJArrDimN.objArr(jo.getJsonArray("eventMetadata"), null, 0, BackgroundService.EventMetadata[].class); 279 280 } 281 282 283 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 284 public boolean equals(Object other) 285 { 286 if (other == null) return false; 287 if (other.getClass() != this.getClass()) return false; 288 289 BackgroundServiceEvent o = (BackgroundServiceEvent) other; 290 291 return 292 Objects.equals(this.timestamp, o.timestamp) 293 && Objects.equals(this.origin, o.origin) 294 && Objects.equals(this.serviceWorkerRegistrationId, o.serviceWorkerRegistrationId) 295 && Objects.equals(this.service, o.service) 296 && Objects.equals(this.eventName, o.eventName) 297 && Objects.equals(this.instanceId, o.instanceId) 298 && Arrays.deepEquals(this.eventMetadata, o.eventMetadata); 299 } 300 301 /** Generates a Hash-Code for {@code 'this'} instance */ 302 public int hashCode() 303 { 304 return 305 Objects.hashCode(this.timestamp) 306 + Objects.hashCode(this.origin) 307 + Objects.hashCode(this.serviceWorkerRegistrationId) 308 + Objects.hashCode(this.service) 309 + Objects.hashCode(this.eventName) 310 + Objects.hashCode(this.instanceId) 311 + Arrays.deepHashCode(this.eventMetadata); 312 } 313 } 314 315 /** Called when the recording state for the service has been updated. */ 316 public static class recordingStateChanged 317 extends BrowserEvent 318 implements java.io.Serializable 319 { 320 /** For Object Serialization. java.io.Serializable */ 321 protected static final long serialVersionUID = 1; 322 323 public boolean[] optionals() 324 { return new boolean[] { false, false, }; } 325 326 /** <CODE>[No Description Provided by Google]</CODE> */ 327 public final boolean isRecording; 328 329 /** <CODE>[No Description Provided by Google]</CODE> */ 330 public final String service; 331 332 /** 333 * Constructor 334 * 335 * @param isRecording - 336 * 337 * @param service - 338 */ 339 public recordingStateChanged(boolean isRecording, String service) 340 { 341 super("BackgroundService", "recordingStateChanged", 2); 342 343 // Exception-Check(s) to ensure that if any parameters which are not declared as 344 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 345 346 if (service == null) BRDPC.throwNPE("service"); 347 348 // Exception-Check(s) to ensure that if any parameters which must adhere to a 349 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 350 351 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 352 353 this.isRecording = isRecording; 354 this.service = service; 355 } 356 357 /** 358 * JSON Object Constructor 359 * @param jo A Json-Object having data about an instance of {@code 'recordingStateChanged'}. 360 */ 361 public recordingStateChanged (JsonObject jo) 362 { 363 super("BackgroundService", "recordingStateChanged", 2); 364 365 this.isRecording = ReadPrimJSON.getBoolean(jo, "isRecording"); 366 this.service = ReadJSON.getString(jo, "service", false, true); 367 } 368 369 370 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 371 public boolean equals(Object other) 372 { 373 if (other == null) return false; 374 if (other.getClass() != this.getClass()) return false; 375 376 recordingStateChanged o = (recordingStateChanged) other; 377 378 return 379 (this.isRecording == o.isRecording) 380 && Objects.equals(this.service, o.service); 381 } 382 383 /** Generates a Hash-Code for {@code 'this'} instance */ 384 public int hashCode() 385 { 386 return 387 (this.isRecording ? 1 : 0) 388 + Objects.hashCode(this.service); 389 } 390 } 391 392 /** 393 * Called with all existing backgroundServiceEvents when enabled, and all new 394 * events afterwards if enabled and recording. 395 */ 396 public static class backgroundServiceEventReceived 397 extends BrowserEvent 398 implements java.io.Serializable 399 { 400 /** For Object Serialization. java.io.Serializable */ 401 protected static final long serialVersionUID = 1; 402 403 public boolean[] optionals() 404 { return new boolean[] { false, }; } 405 406 /** <CODE>[No Description Provided by Google]</CODE> */ 407 public final BackgroundService.BackgroundServiceEvent backgroundServiceEvent; 408 409 /** 410 * Constructor 411 * 412 * @param backgroundServiceEvent - 413 */ 414 public backgroundServiceEventReceived 415 (BackgroundService.BackgroundServiceEvent backgroundServiceEvent) 416 { 417 super("BackgroundService", "backgroundServiceEventReceived", 1); 418 419 // Exception-Check(s) to ensure that if any parameters which are not declared as 420 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 421 422 if (backgroundServiceEvent == null) BRDPC.throwNPE("backgroundServiceEvent"); 423 424 this.backgroundServiceEvent = backgroundServiceEvent; 425 } 426 427 /** 428 * JSON Object Constructor 429 * @param jo A Json-Object having data about an instance of {@code 'backgroundServiceEventReceived'}. 430 */ 431 public backgroundServiceEventReceived (JsonObject jo) 432 { 433 super("BackgroundService", "backgroundServiceEventReceived", 1); 434 435 this.backgroundServiceEvent = ReadJSON.getObject(jo, "backgroundServiceEvent", BackgroundService.BackgroundServiceEvent.class, false, true); 436 } 437 438 439 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 440 public boolean equals(Object other) 441 { 442 if (other == null) return false; 443 if (other.getClass() != this.getClass()) return false; 444 445 backgroundServiceEventReceived o = (backgroundServiceEventReceived) other; 446 447 return 448 Objects.equals(this.backgroundServiceEvent, o.backgroundServiceEvent); 449 } 450 451 /** Generates a Hash-Code for {@code 'this'} instance */ 452 public int hashCode() 453 { 454 return 455 this.backgroundServiceEvent.hashCode(); 456 } 457 } 458 459 460 // Counter for keeping the WebSocket Request ID's distinct. 461 private static int counter = 1; 462 463 /** 464 * Enables event updates for the service. 465 * 466 * @param service - 467 * 468 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 469 * {@link Ret0}></CODE> 470 * 471 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 472 * browser receives the invocation-request. 473 * 474 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 475 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 476 * {@code >} to ensure the Browser Function has run to completion. 477 */ 478 public static Script<String, JsonObject, Ret0> startObserving(String service) 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 (service == null) BRDPC.throwNPE("service"); 484 485 // Exception-Check(s) to ensure that if any parameters which must adhere to a 486 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 487 488 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 489 490 final int webSocketID = 10000000 + counter++; 491 final boolean[] optionals = { false, }; 492 493 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 494 String requestJSON = WriteJSON.get( 495 parameterTypes.get("startObserving"), 496 parameterNames.get("startObserving"), 497 optionals, webSocketID, 498 "BackgroundService.startObserving", 499 service 500 ); 501 502 // This Remote Command does not have a Return-Value. 503 return new Script<> 504 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 505 } 506 507 /** 508 * Disables event updates for the service. 509 * 510 * @param service - 511 * 512 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 513 * {@link Ret0}></CODE> 514 * 515 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 516 * browser receives the invocation-request. 517 * 518 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 519 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 520 * {@code >} to ensure the Browser Function has run to completion. 521 */ 522 public static Script<String, JsonObject, Ret0> stopObserving(String service) 523 { 524 // Exception-Check(s) to ensure that if any parameters which are not declared as 525 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 526 527 if (service == null) BRDPC.throwNPE("service"); 528 529 // Exception-Check(s) to ensure that if any parameters which must adhere to a 530 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 531 532 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 533 534 final int webSocketID = 10001000 + counter++; 535 final boolean[] optionals = { false, }; 536 537 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 538 String requestJSON = WriteJSON.get( 539 parameterTypes.get("stopObserving"), 540 parameterNames.get("stopObserving"), 541 optionals, webSocketID, 542 "BackgroundService.stopObserving", 543 service 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 * Set the recording state for the service. 553 * 554 * @param shouldRecord - 555 * 556 * @param service - 557 * 558 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 559 * {@link Ret0}></CODE> 560 * 561 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 562 * browser receives the invocation-request. 563 * 564 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 565 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 566 * {@code >} to ensure the Browser Function has run to completion. 567 */ 568 public static Script<String, JsonObject, Ret0> setRecording 569 (boolean shouldRecord, String service) 570 { 571 // Exception-Check(s) to ensure that if any parameters which are not declared as 572 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 573 574 if (service == null) BRDPC.throwNPE("service"); 575 576 // Exception-Check(s) to ensure that if any parameters which must adhere to a 577 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 578 579 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 580 581 final int webSocketID = 10002000 + counter++; 582 final boolean[] optionals = { false, false, }; 583 584 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 585 String requestJSON = WriteJSON.get( 586 parameterTypes.get("setRecording"), 587 parameterNames.get("setRecording"), 588 optionals, webSocketID, 589 "BackgroundService.setRecording", 590 shouldRecord, service 591 ); 592 593 // This Remote Command does not have a Return-Value. 594 return new Script<> 595 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 596 } 597 598 /** 599 * Clears all stored data for the service. 600 * 601 * @param service - 602 * 603 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 604 * {@link Ret0}></CODE> 605 * 606 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 607 * browser receives the invocation-request. 608 * 609 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 610 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 611 * {@code >} to ensure the Browser Function has run to completion. 612 */ 613 public static Script<String, JsonObject, Ret0> clearEvents(String service) 614 { 615 // Exception-Check(s) to ensure that if any parameters which are not declared as 616 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 617 618 if (service == null) BRDPC.throwNPE("service"); 619 620 // Exception-Check(s) to ensure that if any parameters which must adhere to a 621 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 622 623 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 624 625 final int webSocketID = 10003000 + counter++; 626 final boolean[] optionals = { false, }; 627 628 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 629 String requestJSON = WriteJSON.get( 630 parameterTypes.get("clearEvents"), 631 parameterNames.get("clearEvents"), 632 optionals, webSocketID, 633 "BackgroundService.clearEvents", 634 service 635 ); 636 637 // This Remote Command does not have a Return-Value. 638 return new Script<> 639 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 640 } 641 642}