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>Provides access to log entries.</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 Log 034{ 035 // ******************************************************************************************** 036 // ******************************************************************************************** 037 // Class Header Stuff 038 // ******************************************************************************************** 039 // ******************************************************************************************** 040 041 042 // No Pubic Constructors 043 private Log () { } 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 : Log.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 parameterNames.put("clear", EMPTY_VEC_STR); 082 083 parameterNames.put("disable", EMPTY_VEC_STR); 084 085 parameterNames.put("enable", EMPTY_VEC_STR); 086 087 v = new Vector<String>(1); 088 parameterNames.put("startViolationsReport", v); 089 Collections.addAll(v, new String[] 090 { "config", }); 091 092 parameterNames.put("stopViolationsReport", EMPTY_VEC_STR); 093 } 094 095 096 // ******************************************************************************************** 097 // ******************************************************************************************** 098 // Types - Static Inner Classes 099 // ******************************************************************************************** 100 // ******************************************************************************************** 101 102 /** Log entry. */ 103 public static class LogEntry 104 extends BaseType 105 implements java.io.Serializable 106 { 107 /** For Object Serialization. java.io.Serializable */ 108 protected static final long serialVersionUID = 1; 109 110 public boolean[] optionals() 111 { return new boolean[] { false, false, false, true, false, true, true, true, true, true, true, }; } 112 113 /** Log entry source. */ 114 public final String source; 115 116 /** Log entry severity. */ 117 public final String level; 118 119 /** Logged text. */ 120 public final String text; 121 122 /** 123 * <CODE>[No Description Provided by Google]</CODE> 124 * <BR /><B CLASS=Opt>OPTIONAL</B> 125 */ 126 public final String category; 127 128 /** Timestamp when this entry was added. */ 129 public final Number timestamp; 130 131 /** 132 * URL of the resource if known. 133 * <BR /><B CLASS=Opt>OPTIONAL</B> 134 */ 135 public final String url; 136 137 /** 138 * Line number in the resource. 139 * <BR /><B CLASS=Opt>OPTIONAL</B> 140 */ 141 public final Integer lineNumber; 142 143 /** 144 * JavaScript stack trace. 145 * <BR /><B CLASS=Opt>OPTIONAL</B> 146 */ 147 public final RunTime.StackTrace stackTrace; 148 149 /** 150 * Identifier of the network request associated with this entry. 151 * <BR /><B CLASS=Opt>OPTIONAL</B> 152 */ 153 public final String networkRequestId; 154 155 /** 156 * Identifier of the worker associated with this entry. 157 * <BR /><B CLASS=Opt>OPTIONAL</B> 158 */ 159 public final String workerId; 160 161 /** 162 * Call arguments. 163 * <BR /><B CLASS=Opt>OPTIONAL</B> 164 */ 165 public final RunTime.RemoteObject[] args; 166 167 /** 168 * Constructor 169 * 170 * @param source Log entry source. 171 * <BR />Acceptable Values: ["xml", "javascript", "network", "storage", "appcache", "rendering", "security", "deprecation", "worker", "violation", "intervention", "recommendation", "other"] 172 * 173 * @param level Log entry severity. 174 * <BR />Acceptable Values: ["verbose", "info", "warning", "error"] 175 * 176 * @param text Logged text. 177 * 178 * @param category - 179 * <BR />Acceptable Values: ["cors"] 180 * <BR /><B CLASS=Opt>OPTIONAL</B> 181 * 182 * @param timestamp Timestamp when this entry was added. 183 * 184 * @param url URL of the resource if known. 185 * <BR /><B CLASS=Opt>OPTIONAL</B> 186 * 187 * @param lineNumber Line number in the resource. 188 * <BR /><B CLASS=Opt>OPTIONAL</B> 189 * 190 * @param stackTrace JavaScript stack trace. 191 * <BR /><B CLASS=Opt>OPTIONAL</B> 192 * 193 * @param networkRequestId Identifier of the network request associated with this entry. 194 * <BR /><B CLASS=Opt>OPTIONAL</B> 195 * 196 * @param workerId Identifier of the worker associated with this entry. 197 * <BR /><B CLASS=Opt>OPTIONAL</B> 198 * 199 * @param args Call arguments. 200 * <BR /><B CLASS=Opt>OPTIONAL</B> 201 */ 202 public LogEntry( 203 String source, String level, String text, String category, Number timestamp, 204 String url, Integer lineNumber, RunTime.StackTrace stackTrace, 205 String networkRequestId, String workerId, RunTime.RemoteObject[] args 206 ) 207 { 208 // Exception-Check(s) to ensure that if any parameters which are not declared as 209 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 210 211 if (source == null) THROWS.throwNPE("source"); 212 if (level == null) THROWS.throwNPE("level"); 213 if (text == null) THROWS.throwNPE("text"); 214 if (timestamp == null) THROWS.throwNPE("timestamp"); 215 216 // Exception-Check(s) to ensure that if any parameters which must adhere to a 217 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 218 219 THROWS.checkIAE( 220 "source", source, 221 "xml", "javascript", "network", "storage", "appcache", "rendering", "security", "deprecation", "worker", "violation", "intervention", "recommendation", "other" 222 ); 223 THROWS.checkIAE( 224 "level", level, 225 "verbose", "info", "warning", "error" 226 ); 227 THROWS.checkIAE( 228 "category", category, 229 "cors" 230 ); 231 232 this.source = source; 233 this.level = level; 234 this.text = text; 235 this.category = category; 236 this.timestamp = timestamp; 237 this.url = url; 238 this.lineNumber = lineNumber; 239 this.stackTrace = stackTrace; 240 this.networkRequestId = networkRequestId; 241 this.workerId = workerId; 242 this.args = args; 243 } 244 245 /** 246 * JSON Object Constructor 247 * @param jo A Json-Object having data about an instance of {@code 'LogEntry'}. 248 */ 249 public LogEntry (JsonObject jo) 250 { 251 this.source = ReadJSON.getString(jo, "source", false, true); 252 this.level = ReadJSON.getString(jo, "level", false, true); 253 this.text = ReadJSON.getString(jo, "text", false, true); 254 this.category = ReadJSON.getString(jo, "category", true, false); 255 this.timestamp = ReadNumberJSON.get(jo, "timestamp", false, true); 256 this.url = ReadJSON.getString(jo, "url", true, false); 257 this.lineNumber = ReadBoxedJSON.getInteger(jo, "lineNumber", true); 258 this.stackTrace = ReadJSON.getObject(jo, "stackTrace", RunTime.StackTrace.class, true, false); 259 this.networkRequestId = ReadJSON.getString(jo, "networkRequestId", true, false); 260 this.workerId = ReadJSON.getString(jo, "workerId", true, false); 261 this.args = (jo.getJsonArray("args") == null) 262 ? null 263 : RJArrIntoStream.objArr(jo.getJsonArray("args"), null, 0, RunTime.RemoteObject.class).toArray(RunTime.RemoteObject[]::new); 264 265 } 266 267 268 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 269 public boolean equals(Object other) 270 { 271 if (this == other) return true; 272 if (other == null) return false; 273 if (other.getClass() != this.getClass()) return false; 274 275 LogEntry o = (LogEntry) other; 276 277 return 278 Objects.equals(this.source, o.source) 279 && Objects.equals(this.level, o.level) 280 && Objects.equals(this.text, o.text) 281 && Objects.equals(this.category, o.category) 282 && Objects.equals(this.timestamp, o.timestamp) 283 && Objects.equals(this.url, o.url) 284 && Objects.equals(this.lineNumber, o.lineNumber) 285 && Objects.equals(this.stackTrace, o.stackTrace) 286 && Objects.equals(this.networkRequestId, o.networkRequestId) 287 && Objects.equals(this.workerId, o.workerId) 288 && Arrays.deepEquals(this.args, o.args); 289 } 290 291 /** Generates a Hash-Code for {@code 'this'} instance */ 292 public int hashCode() 293 { 294 return 295 Objects.hashCode(this.source) 296 + Objects.hashCode(this.level) 297 + Objects.hashCode(this.text) 298 + Objects.hashCode(this.category) 299 + Objects.hashCode(this.timestamp) 300 + Objects.hashCode(this.url) 301 + Objects.hashCode(this.lineNumber) 302 + this.stackTrace.hashCode() 303 + Objects.hashCode(this.networkRequestId) 304 + Objects.hashCode(this.workerId) 305 + Arrays.deepHashCode(this.args); 306 } 307 } 308 309 /** Violation configuration setting. */ 310 public static class ViolationSetting 311 extends BaseType 312 implements java.io.Serializable 313 { 314 /** For Object Serialization. java.io.Serializable */ 315 protected static final long serialVersionUID = 1; 316 317 public boolean[] optionals() 318 { return new boolean[] { false, false, }; } 319 320 /** Violation type. */ 321 public final String name; 322 323 /** Time threshold to trigger upon. */ 324 public final Number threshold; 325 326 /** 327 * Constructor 328 * 329 * @param name Violation type. 330 * <BR />Acceptable Values: ["longTask", "longLayout", "blockedEvent", "blockedParser", "discouragedAPIUse", "handler", "recurringHandler"] 331 * 332 * @param threshold Time threshold to trigger upon. 333 */ 334 public ViolationSetting(String name, Number threshold) 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 (name == null) THROWS.throwNPE("name"); 340 if (threshold == null) THROWS.throwNPE("threshold"); 341 342 // Exception-Check(s) to ensure that if any parameters which must adhere to a 343 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 344 345 THROWS.checkIAE( 346 "name", name, 347 "longTask", "longLayout", "blockedEvent", "blockedParser", "discouragedAPIUse", "handler", "recurringHandler" 348 ); 349 350 this.name = name; 351 this.threshold = threshold; 352 } 353 354 /** 355 * JSON Object Constructor 356 * @param jo A Json-Object having data about an instance of {@code 'ViolationSetting'}. 357 */ 358 public ViolationSetting (JsonObject jo) 359 { 360 this.name = ReadJSON.getString(jo, "name", false, true); 361 this.threshold = ReadNumberJSON.get(jo, "threshold", false, true); 362 } 363 364 365 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 366 public boolean equals(Object other) 367 { 368 if (this == other) return true; 369 if (other == null) return false; 370 if (other.getClass() != this.getClass()) return false; 371 372 ViolationSetting o = (ViolationSetting) other; 373 374 return 375 Objects.equals(this.name, o.name) 376 && Objects.equals(this.threshold, o.threshold); 377 } 378 379 /** Generates a Hash-Code for {@code 'this'} instance */ 380 public int hashCode() 381 { 382 return 383 Objects.hashCode(this.name) 384 + Objects.hashCode(this.threshold); 385 } 386 } 387 388 /** Issued when new message was logged. */ 389 public static class entryAdded 390 extends BrowserEvent 391 implements java.io.Serializable 392 { 393 /** For Object Serialization. java.io.Serializable */ 394 protected static final long serialVersionUID = 1; 395 396 public boolean[] optionals() 397 { return new boolean[] { false, }; } 398 399 /** The entry. */ 400 public final Log.LogEntry entry; 401 402 /** 403 * Constructor 404 * 405 * @param entry The entry. 406 */ 407 public entryAdded(Log.LogEntry entry) 408 { 409 super("Log", "entryAdded", 1); 410 411 // Exception-Check(s) to ensure that if any parameters which are not declared as 412 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 413 414 if (entry == null) THROWS.throwNPE("entry"); 415 416 this.entry = entry; 417 } 418 419 /** 420 * JSON Object Constructor 421 * @param jo A Json-Object having data about an instance of {@code 'entryAdded'}. 422 */ 423 public entryAdded (JsonObject jo) 424 { 425 super("Log", "entryAdded", 1); 426 427 this.entry = ReadJSON.getObject(jo, "entry", Log.LogEntry.class, false, true); 428 } 429 430 431 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 432 public boolean equals(Object other) 433 { 434 if (this == other) return true; 435 if (other == null) return false; 436 if (other.getClass() != this.getClass()) return false; 437 438 entryAdded o = (entryAdded) other; 439 440 return 441 Objects.equals(this.entry, o.entry); 442 } 443 444 /** Generates a Hash-Code for {@code 'this'} instance */ 445 public int hashCode() 446 { 447 return 448 this.entry.hashCode(); 449 } 450 } 451 452 453 // Counter for keeping the WebSocket Request ID's distinct. 454 private static int counter = 1; 455 456 /** 457 * Clears the log. 458 * 459 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 460 * {@link Ret0}></CODE> 461 * 462 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 463 * browser receives the invocation-request. 464 * 465 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 466 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 467 * {@code >} to ensure the Browser Function has run to completion. 468 */ 469 public static Script<String, JsonObject, Ret0> clear() 470 { 471 final int webSocketID = 31000000 + counter++; 472 final boolean[] optionals = new boolean[0]; 473 474 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 475 String requestJSON = WriteJSON.get( 476 parameterTypes.get("clear"), 477 parameterNames.get("clear"), 478 optionals, webSocketID, 479 "Log.clear" 480 ); 481 482 // This Remote Command does not have a Return-Value. 483 return new Script<> 484 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 485 } 486 487 /** 488 * Disables log domain, prevents further log entries from being reported to the client. 489 * 490 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 491 * {@link Ret0}></CODE> 492 * 493 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 494 * browser receives the invocation-request. 495 * 496 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 497 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 498 * {@code >} to ensure the Browser Function has run to completion. 499 */ 500 public static Script<String, JsonObject, Ret0> disable() 501 { 502 final int webSocketID = 31001000 + counter++; 503 final boolean[] optionals = new boolean[0]; 504 505 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 506 String requestJSON = WriteJSON.get( 507 parameterTypes.get("disable"), 508 parameterNames.get("disable"), 509 optionals, webSocketID, 510 "Log.disable" 511 ); 512 513 // This Remote Command does not have a Return-Value. 514 return new Script<> 515 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 516 } 517 518 /** 519 * Enables log domain, sends the entries collected so far to the client by means of the 520 * {@code entryAdded} notification. 521 * 522 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 523 * {@link Ret0}></CODE> 524 * 525 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 526 * browser receives the invocation-request. 527 * 528 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 529 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 530 * {@code >} to ensure the Browser Function has run to completion. 531 */ 532 public static Script<String, JsonObject, Ret0> enable() 533 { 534 final int webSocketID = 31002000 + counter++; 535 final boolean[] optionals = new boolean[0]; 536 537 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 538 String requestJSON = WriteJSON.get( 539 parameterTypes.get("enable"), 540 parameterNames.get("enable"), 541 optionals, webSocketID, 542 "Log.enable" 543 ); 544 545 // This Remote Command does not have a Return-Value. 546 return new Script<> 547 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 548 } 549 550 /** 551 * start violation reporting. 552 * 553 * @param config Configuration for violations. 554 * 555 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 556 * {@link Ret0}></CODE> 557 * 558 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 559 * browser receives the invocation-request. 560 * 561 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 562 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 563 * {@code >} to ensure the Browser Function has run to completion. 564 */ 565 public static Script<String, JsonObject, Ret0> startViolationsReport 566 (Log.ViolationSetting[] config) 567 { 568 // Exception-Check(s) to ensure that if any parameters which are not declared as 569 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 570 571 if (config == null) THROWS.throwNPE("config"); 572 573 final int webSocketID = 31003000 + counter++; 574 final boolean[] optionals = { false, }; 575 576 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 577 String requestJSON = WriteJSON.get( 578 parameterTypes.get("startViolationsReport"), 579 parameterNames.get("startViolationsReport"), 580 optionals, webSocketID, 581 "Log.startViolationsReport", 582 (Object) config 583 ); 584 585 // This Remote Command does not have a Return-Value. 586 return new Script<> 587 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 588 } 589 590 /** 591 * Stop violation reporting. 592 * 593 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 594 * {@link Ret0}></CODE> 595 * 596 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 597 * browser receives the invocation-request. 598 * 599 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 600 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 601 * {@code >} to ensure the Browser Function has run to completion. 602 */ 603 public static Script<String, JsonObject, Ret0> stopViolationsReport() 604 { 605 final int webSocketID = 31004000 + counter++; 606 final boolean[] optionals = new boolean[0]; 607 608 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 609 String requestJSON = WriteJSON.get( 610 parameterTypes.get("stopViolationsReport"), 611 parameterNames.get("stopViolationsReport"), 612 optionals, webSocketID, 613 "Log.stopViolationsReport" 614 ); 615 616 // This Remote Command does not have a Return-Value. 617 return new Script<> 618 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 619 } 620 621}