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.*; 013 014import static Torello.Java.Additional.JFlag.*; 015 016import Torello.Java.StrCmpr; 017import Torello.JavaDoc.StaticFunctional; 018import Torello.JavaDoc.JDHeaderBackgroundImg; 019import Torello.JavaDoc.Excuse; 020 021/** 022 * <SPAN CLASS=CopiedJDK><B>Defines events for background web platform features.</B></SPAN> 023 * 024 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE> 025 */ 026@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION}) 027@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE") 028public class BackgroundService 029{ 030 // ******************************************************************************************** 031 // ******************************************************************************************** 032 // Class Header Stuff 033 // ******************************************************************************************** 034 // ******************************************************************************************** 035 036 037 // No Pubic Constructors 038 private BackgroundService () { } 039 040 // These two Vector's are used by all the "Methods" exported by this class. java.lang.reflect 041 // is used to generate the JSON String's. It saves thousands of lines of Auto-Generated Code. 042 private static final Map<String, Vector<String>> parameterNames = new HashMap<>(); 043 private static final Map<String, Vector<Class<?>>> parameterTypes = new HashMap<>(); 044 045 // Some Methods do not take any parameters - for instance all the "enable()" and "disable()" 046 // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now, 047 // offically, two empty-vectors. One for String's, and the other for Classes. 048 049 private static final Vector<String> EMPTY_VEC_STR = new Vector<>(); 050 private static final Vector<Class<?>> EMPTY_VEC_CLASS = new Vector<>(); 051 052 static 053 { 054 for (Method m : BackgroundService.class.getMethods()) 055 { 056 // This doesn't work! The parameter names are all "arg0" ... "argN" 057 // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter! 058 // 059 // Vector<String> parameterNamesList = new Vector<>(); -- NOPE! 060 061 Vector<Class<?>> parameterTypesList = new Vector<>(); 062 063 for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType()); 064 065 parameterTypes.put( 066 m.getName(), 067 (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS 068 ); 069 } 070 } 071 072 static 073 { 074 Vector<String> v = null; 075 076 v = new Vector<String>(1); 077 parameterNames.put("startObserving", v); 078 Collections.addAll(v, new String[] 079 { "service", }); 080 081 v = new Vector<String>(1); 082 parameterNames.put("stopObserving", v); 083 Collections.addAll(v, new String[] 084 { "service", }); 085 086 v = new Vector<String>(2); 087 parameterNames.put("setRecording", v); 088 Collections.addAll(v, new String[] 089 { "shouldRecord", "service", }); 090 091 v = new Vector<String>(1); 092 parameterNames.put("clearEvents", v); 093 Collections.addAll(v, new String[] 094 { "service", }); 095 } 096 097 098 // ******************************************************************************************** 099 // ******************************************************************************************** 100 // Types - Static Inner Classes 101 // ******************************************************************************************** 102 // ******************************************************************************************** 103 104 /** 105 * The Background Service that will be associated with the commands/events. 106 * Every Background Service operates independently, but they share the same 107 * API. 108 */ 109 public static final String[] ServiceName = 110 { 111 "backgroundFetch", "backgroundSync", "pushMessaging", "notifications", "paymentHandler", 112 "periodicBackgroundSync", 113 }; 114 115 /** A key-value pair for additional event information to pass along. */ 116 public static class EventMetadata extends BaseType 117 { 118 /** For Object Serialization. java.io.Serializable */ 119 protected static final long serialVersionUID = 1; 120 121 public boolean[] optionals() 122 { return new boolean[] { false, false, }; } 123 124 /** <CODE>[No Description Provided by Google]</CODE> */ 125 public final String key; 126 127 /** <CODE>[No Description Provided by Google]</CODE> */ 128 public final String value; 129 130 /** 131 * Constructor 132 * 133 * @param key - 134 * 135 * @param value - 136 */ 137 public EventMetadata(String key, String value) 138 { 139 // Exception-Check(s) to ensure that if any parameters which are not declared as 140 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 141 142 if (key == null) BRDPC.throwNPE("key"); 143 if (value == null) BRDPC.throwNPE("value"); 144 145 this.key = key; 146 this.value = value; 147 } 148 149 /** 150 * JSON Object Constructor 151 * @param jo A Json-Object having data about an instance of {@code 'EventMetadata'}. 152 */ 153 public EventMetadata (JsonObject jo) 154 { 155 this.key = ReadJSON.getString(jo, "key", false, true); 156 this.value = ReadJSON.getString(jo, "value", false, true); 157 } 158 159 } 160 161 /** <CODE>[No Description Provided by Google]</CODE> */ 162 public static class BackgroundServiceEvent extends BaseType 163 { 164 /** For Object Serialization. java.io.Serializable */ 165 protected static final long serialVersionUID = 1; 166 167 public boolean[] optionals() 168 { return new boolean[] { false, false, false, false, false, false, false, }; } 169 170 /** Timestamp of the event (in seconds). */ 171 public final Number timestamp; 172 173 /** The origin this event belongs to. */ 174 public final String origin; 175 176 /** The Service Worker ID that initiated the event. */ 177 public final String serviceWorkerRegistrationId; 178 179 /** The Background Service this event belongs to. */ 180 public final String service; 181 182 /** A description of the event. */ 183 public final String eventName; 184 185 /** An identifier that groups related events together. */ 186 public final String instanceId; 187 188 /** A list of event-specific information. */ 189 public final BackgroundService.EventMetadata[] eventMetadata; 190 191 /** 192 * Constructor 193 * 194 * @param timestamp Timestamp of the event (in seconds). 195 * 196 * @param origin The origin this event belongs to. 197 * 198 * @param serviceWorkerRegistrationId The Service Worker ID that initiated the event. 199 * 200 * @param service The Background Service this event belongs to. 201 * 202 * @param eventName A description of the event. 203 * 204 * @param instanceId An identifier that groups related events together. 205 * 206 * @param eventMetadata A list of event-specific information. 207 */ 208 public BackgroundServiceEvent( 209 Number timestamp, String origin, String serviceWorkerRegistrationId, String service, 210 String eventName, String instanceId, BackgroundService.EventMetadata[] eventMetadata 211 ) 212 { 213 // Exception-Check(s) to ensure that if any parameters which are not declared as 214 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 215 216 if (timestamp == null) BRDPC.throwNPE("timestamp"); 217 if (origin == null) BRDPC.throwNPE("origin"); 218 if (serviceWorkerRegistrationId == null) BRDPC.throwNPE("serviceWorkerRegistrationId"); 219 if (service == null) BRDPC.throwNPE("service"); 220 if (eventName == null) BRDPC.throwNPE("eventName"); 221 if (instanceId == null) BRDPC.throwNPE("instanceId"); 222 if (eventMetadata == null) BRDPC.throwNPE("eventMetadata"); 223 224 // Exception-Check(s) to ensure that if any parameters which must adhere to a 225 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 226 227 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 228 229 this.timestamp = timestamp; 230 this.origin = origin; 231 this.serviceWorkerRegistrationId = serviceWorkerRegistrationId; 232 this.service = service; 233 this.eventName = eventName; 234 this.instanceId = instanceId; 235 this.eventMetadata = eventMetadata; 236 } 237 238 /** 239 * JSON Object Constructor 240 * @param jo A Json-Object having data about an instance of {@code 'BackgroundServiceEvent'}. 241 */ 242 public BackgroundServiceEvent (JsonObject jo) 243 { 244 this.timestamp = ReadJSON.getNUMBER(jo, "timestamp", false, true); 245 this.origin = ReadJSON.getString(jo, "origin", false, true); 246 this.serviceWorkerRegistrationId = ReadJSON.getString(jo, "serviceWorkerRegistrationId", false, true); 247 this.service = ReadJSON.getString(jo, "service", false, true); 248 this.eventName = ReadJSON.getString(jo, "eventName", false, true); 249 this.instanceId = ReadJSON.getString(jo, "instanceId", false, true); 250 this.eventMetadata = (jo.getJsonArray("eventMetadata") == null) 251 ? null 252 : ReadArrJSON.DimN.objArr(jo.getJsonArray("eventMetadata"), null, 0, BackgroundService.EventMetadata[].class); 253 } 254 255 } 256 257 /** Called when the recording state for the service has been updated. */ 258 public static class recordingStateChanged extends BrowserEvent 259 { 260 /** For Object Serialization. java.io.Serializable */ 261 protected static final long serialVersionUID = 1; 262 263 public boolean[] optionals() 264 { return new boolean[] { false, false, }; } 265 266 /** <CODE>[No Description Provided by Google]</CODE> */ 267 public final boolean isRecording; 268 269 /** <CODE>[No Description Provided by Google]</CODE> */ 270 public final String service; 271 272 /** 273 * Constructor 274 * 275 * @param isRecording - 276 * 277 * @param service - 278 */ 279 public recordingStateChanged(boolean isRecording, String service) 280 { 281 super("BackgroundService", "recordingStateChanged", 2); 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 (service == null) BRDPC.throwNPE("service"); 287 288 // Exception-Check(s) to ensure that if any parameters which must adhere to a 289 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 290 291 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 292 293 this.isRecording = isRecording; 294 this.service = service; 295 } 296 297 /** 298 * JSON Object Constructor 299 * @param jo A Json-Object having data about an instance of {@code 'recordingStateChanged'}. 300 */ 301 public recordingStateChanged (JsonObject jo) 302 { 303 super("BackgroundService", "recordingStateChanged", 2); 304 305 this.isRecording = ReadJSON.getBoolean(jo, "isRecording"); 306 this.service = ReadJSON.getString(jo, "service", false, true); 307 } 308 309 } 310 311 /** 312 * Called with all existing backgroundServiceEvents when enabled, and all new 313 * events afterwards if enabled and recording. 314 */ 315 public static class backgroundServiceEventReceived extends BrowserEvent 316 { 317 /** For Object Serialization. java.io.Serializable */ 318 protected static final long serialVersionUID = 1; 319 320 public boolean[] optionals() 321 { return new boolean[] { false, }; } 322 323 /** <CODE>[No Description Provided by Google]</CODE> */ 324 public final BackgroundService.BackgroundServiceEvent backgroundServiceEvent; 325 326 /** 327 * Constructor 328 * 329 * @param backgroundServiceEvent - 330 */ 331 public backgroundServiceEventReceived 332 (BackgroundService.BackgroundServiceEvent backgroundServiceEvent) 333 { 334 super("BackgroundService", "backgroundServiceEventReceived", 1); 335 336 // Exception-Check(s) to ensure that if any parameters which are not declared as 337 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 338 339 if (backgroundServiceEvent == null) BRDPC.throwNPE("backgroundServiceEvent"); 340 341 this.backgroundServiceEvent = backgroundServiceEvent; 342 } 343 344 /** 345 * JSON Object Constructor 346 * @param jo A Json-Object having data about an instance of {@code 'backgroundServiceEventReceived'}. 347 */ 348 public backgroundServiceEventReceived (JsonObject jo) 349 { 350 super("BackgroundService", "backgroundServiceEventReceived", 1); 351 352 this.backgroundServiceEvent = ReadJSON.XL.getObject(jo, "backgroundServiceEvent", BackgroundService.BackgroundServiceEvent.class, false, true); 353 } 354 355 } 356 357 358 // Counter for keeping the WebSocket Request ID's distinct. 359 private static int counter = 1; 360 361 /** 362 * Enables event updates for the service. 363 * 364 * @param service - 365 * 366 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 367 * {@link Ret0}></CODE> 368 * 369 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 370 * browser receives the invocation-request. 371 * 372 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 373 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 374 * {@code >} to ensure the Browser Function has run to completion. 375 */ 376 public static Script<String, JsonObject, Ret0> startObserving(String service) 377 { 378 // Exception-Check(s) to ensure that if any parameters which are not declared as 379 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 380 381 if (service == null) BRDPC.throwNPE("service"); 382 383 // Exception-Check(s) to ensure that if any parameters which must adhere to a 384 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 385 386 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 387 388 final int webSocketID = 10000000 + counter++; 389 final boolean[] optionals = { false, }; 390 391 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 392 String requestJSON = WriteJSON.get( 393 parameterTypes.get("startObserving"), 394 parameterNames.get("startObserving"), 395 optionals, webSocketID, 396 "BackgroundService.startObserving", 397 service 398 ); 399 400 // This Remote Command does not have a Return-Value. 401 return new Script<> 402 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 403 } 404 405 /** 406 * Disables event updates for the service. 407 * 408 * @param service - 409 * 410 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 411 * {@link Ret0}></CODE> 412 * 413 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 414 * browser receives the invocation-request. 415 * 416 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 417 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 418 * {@code >} to ensure the Browser Function has run to completion. 419 */ 420 public static Script<String, JsonObject, Ret0> stopObserving(String service) 421 { 422 // Exception-Check(s) to ensure that if any parameters which are not declared as 423 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 424 425 if (service == null) BRDPC.throwNPE("service"); 426 427 // Exception-Check(s) to ensure that if any parameters which must adhere to a 428 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 429 430 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 431 432 final int webSocketID = 10001000 + counter++; 433 final boolean[] optionals = { false, }; 434 435 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 436 String requestJSON = WriteJSON.get( 437 parameterTypes.get("stopObserving"), 438 parameterNames.get("stopObserving"), 439 optionals, webSocketID, 440 "BackgroundService.stopObserving", 441 service 442 ); 443 444 // This Remote Command does not have a Return-Value. 445 return new Script<> 446 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 447 } 448 449 /** 450 * Set the recording state for the service. 451 * 452 * @param shouldRecord - 453 * 454 * @param service - 455 * 456 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 457 * {@link Ret0}></CODE> 458 * 459 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 460 * browser receives the invocation-request. 461 * 462 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 463 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 464 * {@code >} to ensure the Browser Function has run to completion. 465 */ 466 public static Script<String, JsonObject, Ret0> setRecording 467 (boolean shouldRecord, String service) 468 { 469 // Exception-Check(s) to ensure that if any parameters which are not declared as 470 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 471 472 if (service == null) BRDPC.throwNPE("service"); 473 474 // Exception-Check(s) to ensure that if any parameters which must adhere to a 475 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 476 477 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 478 479 final int webSocketID = 10002000 + counter++; 480 final boolean[] optionals = { false, false, }; 481 482 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 483 String requestJSON = WriteJSON.get( 484 parameterTypes.get("setRecording"), 485 parameterNames.get("setRecording"), 486 optionals, webSocketID, 487 "BackgroundService.setRecording", 488 shouldRecord, service 489 ); 490 491 // This Remote Command does not have a Return-Value. 492 return new Script<> 493 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 494 } 495 496 /** 497 * Clears all stored data for the service. 498 * 499 * @param service - 500 * 501 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 502 * {@link Ret0}></CODE> 503 * 504 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 505 * browser receives the invocation-request. 506 * 507 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 508 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 509 * {@code >} to ensure the Browser Function has run to completion. 510 */ 511 public static Script<String, JsonObject, Ret0> clearEvents(String service) 512 { 513 // Exception-Check(s) to ensure that if any parameters which are not declared as 514 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 515 516 if (service == null) BRDPC.throwNPE("service"); 517 518 // Exception-Check(s) to ensure that if any parameters which must adhere to a 519 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 520 521 BRDPC.checkIAE("service", service, "BackgroundService.ServiceName", BackgroundService.ServiceName); 522 523 final int webSocketID = 10003000 + counter++; 524 final boolean[] optionals = { false, }; 525 526 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 527 String requestJSON = WriteJSON.get( 528 parameterTypes.get("clearEvents"), 529 parameterNames.get("clearEvents"), 530 optionals, webSocketID, 531 "BackgroundService.clearEvents", 532 service 533 ); 534 535 // This Remote Command does not have a Return-Value. 536 return new Script<> 537 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 538 } 539 540}