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