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) BRDPC.throwNPE("source"); 215 if (level == null) BRDPC.throwNPE("level"); 216 if (text == null) BRDPC.throwNPE("text"); 217 if (timestamp == null) BRDPC.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 BRDPC.checkIAE( 223 "source", source, 224 "xml", "javascript", "network", "storage", "appcache", "rendering", "security", "deprecation", "worker", "violation", "intervention", "recommendation", "other" 225 ); 226 BRDPC.checkIAE( 227 "level", level, 228 "verbose", "info", "warning", "error" 229 ); 230 BRDPC.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 : ReadArrJSON.DimN.objArr(jo.getJsonArray("args"), null, 0, RunTime.RemoteObject[].class); 267 268 } 269 270 271 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 272 public boolean equals(Object other) 273 { 274 if (other == null) return false; 275 if (other.getClass() != this.getClass()) return false; 276 277 LogEntry o = (LogEntry) other; 278 279 return 280 Objects.equals(this.source, o.source) 281 && Objects.equals(this.level, o.level) 282 && Objects.equals(this.text, o.text) 283 && Objects.equals(this.category, o.category) 284 && Objects.equals(this.timestamp, o.timestamp) 285 && Objects.equals(this.url, o.url) 286 && Objects.equals(this.lineNumber, o.lineNumber) 287 && Objects.equals(this.stackTrace, o.stackTrace) 288 && Objects.equals(this.networkRequestId, o.networkRequestId) 289 && Objects.equals(this.workerId, o.workerId) 290 && Arrays.deepEquals(this.args, o.args); 291 } 292 293 /** Generates a Hash-Code for {@code 'this'} instance */ 294 public int hashCode() 295 { 296 return 297 Objects.hashCode(this.source) 298 + Objects.hashCode(this.level) 299 + Objects.hashCode(this.text) 300 + Objects.hashCode(this.category) 301 + Objects.hashCode(this.timestamp) 302 + Objects.hashCode(this.url) 303 + Objects.hashCode(this.lineNumber) 304 + this.stackTrace.hashCode() 305 + Objects.hashCode(this.networkRequestId) 306 + Objects.hashCode(this.workerId) 307 + Arrays.deepHashCode(this.args); 308 } 309 } 310 311 /** Violation configuration setting. */ 312 public static class ViolationSetting 313 extends BaseType 314 implements java.io.Serializable 315 { 316 /** For Object Serialization. java.io.Serializable */ 317 protected static final long serialVersionUID = 1; 318 319 public boolean[] optionals() 320 { return new boolean[] { false, false, }; } 321 322 /** Violation type. */ 323 public final String name; 324 325 /** Time threshold to trigger upon. */ 326 public final Number threshold; 327 328 /** 329 * Constructor 330 * 331 * @param name Violation type. 332 * <BR />Acceptable Values: ["longTask", "longLayout", "blockedEvent", "blockedParser", "discouragedAPIUse", "handler", "recurringHandler"] 333 * 334 * @param threshold Time threshold to trigger upon. 335 */ 336 public ViolationSetting(String name, Number threshold) 337 { 338 // Exception-Check(s) to ensure that if any parameters which are not declared as 339 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 340 341 if (name == null) BRDPC.throwNPE("name"); 342 if (threshold == null) BRDPC.throwNPE("threshold"); 343 344 // Exception-Check(s) to ensure that if any parameters which must adhere to a 345 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 346 347 BRDPC.checkIAE( 348 "name", name, 349 "longTask", "longLayout", "blockedEvent", "blockedParser", "discouragedAPIUse", "handler", "recurringHandler" 350 ); 351 352 this.name = name; 353 this.threshold = threshold; 354 } 355 356 /** 357 * JSON Object Constructor 358 * @param jo A Json-Object having data about an instance of {@code 'ViolationSetting'}. 359 */ 360 public ViolationSetting (JsonObject jo) 361 { 362 this.name = ReadJSON.getString(jo, "name", false, true); 363 this.threshold = ReadNumberJSON.get(jo, "threshold", false, true); 364 } 365 366 367 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 368 public boolean equals(Object other) 369 { 370 if (other == null) return false; 371 if (other.getClass() != this.getClass()) return false; 372 373 ViolationSetting o = (ViolationSetting) other; 374 375 return 376 Objects.equals(this.name, o.name) 377 && Objects.equals(this.threshold, o.threshold); 378 } 379 380 /** Generates a Hash-Code for {@code 'this'} instance */ 381 public int hashCode() 382 { 383 return 384 Objects.hashCode(this.name) 385 + Objects.hashCode(this.threshold); 386 } 387 } 388 389 /** Issued when new message was logged. */ 390 public static class entryAdded 391 extends BrowserEvent 392 implements java.io.Serializable 393 { 394 /** For Object Serialization. java.io.Serializable */ 395 protected static final long serialVersionUID = 1; 396 397 public boolean[] optionals() 398 { return new boolean[] { false, }; } 399 400 /** The entry. */ 401 public final Log.LogEntry entry; 402 403 /** 404 * Constructor 405 * 406 * @param entry The entry. 407 */ 408 public entryAdded(Log.LogEntry entry) 409 { 410 super("Log", "entryAdded", 1); 411 412 // Exception-Check(s) to ensure that if any parameters which are not declared as 413 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 414 415 if (entry == null) BRDPC.throwNPE("entry"); 416 417 this.entry = entry; 418 } 419 420 /** 421 * JSON Object Constructor 422 * @param jo A Json-Object having data about an instance of {@code 'entryAdded'}. 423 */ 424 public entryAdded (JsonObject jo) 425 { 426 super("Log", "entryAdded", 1); 427 428 this.entry = ReadJSON.getObject(jo, "entry", Log.LogEntry.class, false, true); 429 } 430 431 432 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 433 public boolean equals(Object other) 434 { 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 = 28000000 + 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 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.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 = 28001000 + 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 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 516 } 517 518 /** 519 * Enables log domain, sends the entries collected so far to the client by means of the 520 * <CODE>entryAdded</CODE> 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 = 28002000 + 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 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.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) BRDPC.throwNPE("config"); 572 573 final int webSocketID = 28003000 + 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 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.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 = 28004000 + 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 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 619 } 620 621}