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><CODE>[No Description Provided by Google]</CODE></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 Performance 030{ 031 // ******************************************************************************************** 032 // ******************************************************************************************** 033 // Class Header Stuff 034 // ******************************************************************************************** 035 // ******************************************************************************************** 036 037 038 // No Pubic Constructors 039 private Performance () { } 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 : Performance.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("disable", EMPTY_VEC_STR); 078 079 v = new Vector<String>(1); 080 parameterNames.put("enable", v); 081 Collections.addAll(v, new String[] 082 { "timeDomain", }); 083 084 v = new Vector<String>(1); 085 parameterNames.put("setTimeDomain", v); 086 Collections.addAll(v, new String[] 087 { "timeDomain", }); 088 089 parameterNames.put("getMetrics", EMPTY_VEC_STR); 090 } 091 092 093 // ******************************************************************************************** 094 // ******************************************************************************************** 095 // Types - Static Inner Classes 096 // ******************************************************************************************** 097 // ******************************************************************************************** 098 099 /** Run-time execution metric. */ 100 public static class Metric 101 extends BaseType 102 implements java.io.Serializable 103 { 104 /** For Object Serialization. java.io.Serializable */ 105 protected static final long serialVersionUID = 1; 106 107 public boolean[] optionals() 108 { return new boolean[] { false, false, }; } 109 110 /** Metric name. */ 111 public final String name; 112 113 /** Metric value. */ 114 public final Number value; 115 116 /** 117 * Constructor 118 * 119 * @param name Metric name. 120 * 121 * @param value Metric value. 122 */ 123 public Metric(String name, Number value) 124 { 125 // Exception-Check(s) to ensure that if any parameters which are not declared as 126 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 127 128 if (name == null) THROWS.throwNPE("name"); 129 if (value == null) THROWS.throwNPE("value"); 130 131 this.name = name; 132 this.value = value; 133 } 134 135 /** 136 * JSON Object Constructor 137 * @param jo A Json-Object having data about an instance of {@code 'Metric'}. 138 */ 139 public Metric (JsonObject jo) 140 { 141 this.name = ReadJSON.getString(jo, "name", false, true); 142 this.value = ReadNumberJSON.get(jo, "value", false, true); 143 } 144 145 146 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 147 public boolean equals(Object other) 148 { 149 if (this == other) return true; 150 if (other == null) return false; 151 if (other.getClass() != this.getClass()) return false; 152 153 Metric o = (Metric) other; 154 155 return 156 Objects.equals(this.name, o.name) 157 && Objects.equals(this.value, o.value); 158 } 159 160 /** Generates a Hash-Code for {@code 'this'} instance */ 161 public int hashCode() 162 { 163 return 164 Objects.hashCode(this.name) 165 + Objects.hashCode(this.value); 166 } 167 } 168 169 /** Current values of the metrics. */ 170 public static class metrics 171 extends BrowserEvent 172 implements java.io.Serializable 173 { 174 /** For Object Serialization. java.io.Serializable */ 175 protected static final long serialVersionUID = 1; 176 177 public boolean[] optionals() 178 { return new boolean[] { false, false, }; } 179 180 /** Current values of the metrics. */ 181 public final Performance.Metric[] metrics; 182 183 /** Timestamp title. */ 184 public final String title; 185 186 /** 187 * Constructor 188 * 189 * @param metrics Current values of the metrics. 190 * 191 * @param title Timestamp title. 192 */ 193 public metrics(Performance.Metric[] metrics, String title) 194 { 195 super("Performance", "metrics", 2); 196 197 // Exception-Check(s) to ensure that if any parameters which are not declared as 198 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 199 200 if (metrics == null) THROWS.throwNPE("metrics"); 201 if (title == null) THROWS.throwNPE("title"); 202 203 this.metrics = metrics; 204 this.title = title; 205 } 206 207 /** 208 * JSON Object Constructor 209 * @param jo A Json-Object having data about an instance of {@code 'metrics'}. 210 */ 211 public metrics (JsonObject jo) 212 { 213 super("Performance", "metrics", 2); 214 215 this.metrics = (jo.getJsonArray("metrics") == null) 216 ? null 217 : RJArrIntoStream.objArr(jo.getJsonArray("metrics"), null, 0, Performance.Metric.class).toArray(Performance.Metric[]::new); 218 219 this.title = ReadJSON.getString(jo, "title", false, true); 220 } 221 222 223 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 224 public boolean equals(Object other) 225 { 226 if (this == other) return true; 227 if (other == null) return false; 228 if (other.getClass() != this.getClass()) return false; 229 230 metrics o = (metrics) other; 231 232 return 233 Arrays.deepEquals(this.metrics, o.metrics) 234 && Objects.equals(this.title, o.title); 235 } 236 237 /** Generates a Hash-Code for {@code 'this'} instance */ 238 public int hashCode() 239 { 240 return 241 Arrays.deepHashCode(this.metrics) 242 + Objects.hashCode(this.title); 243 } 244 } 245 246 247 // Counter for keeping the WebSocket Request ID's distinct. 248 private static int counter = 1; 249 250 /** 251 * Disable collecting and reporting metrics. 252 * 253 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 254 * {@link Ret0}></CODE> 255 * 256 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 257 * browser receives the invocation-request. 258 * 259 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 260 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 261 * {@code >} to ensure the Browser Function has run to completion. 262 */ 263 public static Script<String, JsonObject, Ret0> disable() 264 { 265 final int webSocketID = 33000000 + counter++; 266 final boolean[] optionals = new boolean[0]; 267 268 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 269 String requestJSON = WriteJSON.get( 270 parameterTypes.get("disable"), 271 parameterNames.get("disable"), 272 optionals, webSocketID, 273 "Performance.disable" 274 ); 275 276 // This Remote Command does not have a Return-Value. 277 return new Script<> 278 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 279 } 280 281 /** 282 * Enable collecting and reporting metrics. 283 * 284 * @param timeDomain Time domain to use for collecting and reporting duration metrics. 285 * <BR />Acceptable Values: ["timeTicks", "threadTicks"] 286 * <BR /><B>OPTIONAL</B> 287 * 288 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 289 * {@link Ret0}></CODE> 290 * 291 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 292 * browser receives the invocation-request. 293 * 294 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 295 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 296 * {@code >} to ensure the Browser Function has run to completion. 297 */ 298 public static Script<String, JsonObject, Ret0> enable(String timeDomain) 299 { 300 // Exception-Check(s) to ensure that if any parameters which must adhere to a 301 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 302 303 THROWS.checkIAE( 304 "timeDomain", timeDomain, 305 "timeTicks", "threadTicks" 306 ); 307 308 final int webSocketID = 33001000 + counter++; 309 final boolean[] optionals = { true, }; 310 311 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 312 String requestJSON = WriteJSON.get( 313 parameterTypes.get("enable"), 314 parameterNames.get("enable"), 315 optionals, webSocketID, 316 "Performance.enable", 317 timeDomain 318 ); 319 320 // This Remote Command does not have a Return-Value. 321 return new Script<> 322 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 323 } 324 325 /** 326 * Sets time domain to use for collecting and reporting duration metrics. 327 * Note that this must be called before enabling metrics collection. Calling 328 * this method while metrics collection is enabled returns an error. 329 * <BR /><B>EXPERIMENTAL</B> 330 * <BR /><B>DEPRECATED</B> 331 * 332 * @param timeDomain Time domain 333 * <BR />Acceptable Values: ["timeTicks", "threadTicks"] 334 * 335 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 336 * {@link Ret0}></CODE> 337 * 338 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 339 * browser receives the invocation-request. 340 * 341 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 342 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 343 * {@code >} to ensure the Browser Function has run to completion. 344 */ 345 public static Script<String, JsonObject, Ret0> setTimeDomain(String timeDomain) 346 { 347 // Exception-Check(s) to ensure that if any parameters which are not declared as 348 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 349 350 if (timeDomain == null) THROWS.throwNPE("timeDomain"); 351 352 // Exception-Check(s) to ensure that if any parameters which must adhere to a 353 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 354 355 THROWS.checkIAE( 356 "timeDomain", timeDomain, 357 "timeTicks", "threadTicks" 358 ); 359 360 final int webSocketID = 33002000 + counter++; 361 final boolean[] optionals = { false, }; 362 363 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 364 String requestJSON = WriteJSON.get( 365 parameterTypes.get("setTimeDomain"), 366 parameterNames.get("setTimeDomain"), 367 optionals, webSocketID, 368 "Performance.setTimeDomain", 369 timeDomain 370 ); 371 372 // This Remote Command does not have a Return-Value. 373 return new Script<> 374 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 375 } 376 377 /** 378 * Retrieve current values of run-time metrics. 379 * 380 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 381 * {@link Performance.Metric}[]></CODE> 382 * 383 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 384 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 385 * {@link Performance.Metric}[]></CODE> will be returned. 386 * 387 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 388 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 389 * may be retrieved.</I> 390 * 391 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 392 * <BR /><BR /><UL CLASS=JDUL> 393 * <LI><CODE>{@link Performance.Metric}[] (<B>metrics</B></CODE>) 394 * <BR />Current values for run-time metrics. 395 * </LI> 396 * </UL> */ 397 public static Script<String, JsonObject, Performance.Metric[]> getMetrics() 398 { 399 final int webSocketID = 33003000 + counter++; 400 final boolean[] optionals = new boolean[0]; 401 402 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 403 String requestJSON = WriteJSON.get( 404 parameterTypes.get("getMetrics"), 405 parameterNames.get("getMetrics"), 406 optionals, webSocketID, 407 "Performance.getMetrics" 408 ); 409 410 // 'JSON Binding' ... Converts Browser Response-JSON to 'Performance.Metric[]' 411 Function<JsonObject, Performance.Metric[]> responseProcessor = (JsonObject jo) -> 412 (jo.getJsonArray("metrics") == null) 413 ? null 414 : RJArrIntoStream.objArr(jo.getJsonArray("metrics"), null, 0, Performance.Metric.class).toArray(Performance.Metric[]::new); 415 416 return new Script<>(webSocketID, requestJSON, responseProcessor); 417 } 418 419}