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