001package Torello.HTML; 002 003import java.util.*; 004import java.util.function.BiConsumer; 005import java.util.concurrent.locks.*; 006 007import static Torello.Java.C.*; 008 009import Torello.Java.LV; 010 011import Torello.JavaDoc.StaticFunctional; 012import Torello.JavaDoc.Excuse; 013 014/** 015 * A fast way to print Web-Page {@code Vector's} to a {@code String}. 016 * <EMBED CLASS='external-html' DATA-FILE-ID=DEBUG> 017 */ 018@StaticFunctional(Excused="lastWasNewLine", Excuses=Excuse.FLAG) 019public class Debug 020{ 021 private Debug() { } 022 023 /** 024 * Convenience Method. 025 * <BR />Invokes: {@link #print(Vector, int, int, BiConsumer)} 026 * <BR />Requests: Print entire {@code 'page' (Vector)} 027 */ 028 public static String print 029 (Vector<? extends HTMLNode> page, BiConsumer<HTMLNode, StringBuffer> printerVersion) 030 { return print(page, 0, -1, printerVersion); } 031 032 /** 033 * Convenience Method. 034 * <BR />Invokes: {@link #print(Vector, int, int, BiConsumer)} 035 * <BR />Requests: Print entire {@code SubSection} 036 */ 037 public static String print(SubSection sec, BiConsumer<HTMLNode, StringBuffer> printerVersion) 038 { return print(sec.html, 0, -1, printerVersion); } 039 040 /** 041 * Convenience Method. 042 * <BR />Invokes: {@link #print(Vector, int, int, BiConsumer)} 043 * <BR />Requests: Print {@code 'page'} sub-range defined by parameter {@code 'dp'} 044 */ 045 public static String print( 046 Vector<? extends HTMLNode> page, DotPair dp, 047 BiConsumer<HTMLNode, StringBuffer> printerVersion 048 ) 049 { return print(page, dp.start, dp.end + 1, printerVersion); } 050 051 /** 052 * Converts HTML to a {@code String} - adding readable notes & messages. This will print 053 * every node in the vectorized-html between starting-index {@code int sPos} (inclusively) and 054 * ending-index {@code int ePos}, exclusively. 055 * 056 * @param page Any vectorized-html page or sub-page. 057 * 058 * @param sPos The printing of nodes will begin at position {@code 'sPos'} - inclusively. 059 * 060 * @param ePos The node at element-position will not be printed (exclusive), and the one 061 * previous shall print. 062 * 063 * @param printerVersion The complicated-looking function-pointer comes from the package 064 * {@code 'java.util.function.'} The literal code to pass to this parameter would be: 065 * <SPAN STYLE="color: blue; font-weight: bold;">Debug::A, Debug::B ... Debug::K</SPAN>. The 066 * programmer may also create a print-function if so desired, and pass that using a 067 * function-pointer or a {@code lambda-expression} 068 * 069 * @return a pretty printed {@code String} of the nodes in this {@code Vector}. 070 * @throws IndexOutOfBoundsException <EMBED CLASS='external-html' DATA-FILE-ID=VIOOBEX> 071 * @see LV 072 */ 073 public static String print( 074 Vector<? extends HTMLNode> page, int sPos, int ePos, 075 BiConsumer<HTMLNode, StringBuffer> printerVersion 076 ) 077 { 078 LV l = new LV(page, sPos, ePos); 079 StringBuffer sb = new StringBuffer(); 080 081 for (int i=l.start; i < l.end; i++) 082 printerVersion.accept(page.elementAt(i), sb); 083 084 return sb.toString(); 085 } 086 087 /** 088 * Converts HTML to a {@code String} - adding readable notes & messages. This version 089 * shall only print nodes whose index "is pointed to" by the elements of the position-index 090 * array parameter {@code int[] posArr}. 091 * 092 * @param page Any vectorized-html page or sub-page. 093 * 094 * @param posArr This is an array of index-pointers into the vectorized-html webpage 095 * parameter 'page.' These arrays are usually created by calls to the {@code package 096 * NodeSearch} using classes with the <B>{@code 'Find'} Key-Word</B>. Such classes return 097 * integer-arrays of pointers to nodes that matched a specific search criteria. 098 * 099 * @param printerVersion The complicated-looking function-pointer comes from the package 100 * 'java.util.function.' The literal code to pass to this parameter would be: 101 * <SPAN STYLE="color: blue; font-weight: bold;">Debug::A, Debug::B ... Debug::K</SPAN>. The 102 * programmer may also create a print-function if so desired, and pass that using a 103 * function-pointer or a {@code lambda-expression}. 104 * 105 * @return a pretty printed {@code String} of the nodes in this {@code Vector} pointed-to by 106 * the elements of {@code 'posArr'} 107 * 108 * @throws ArrayIndexOutOfBoundsException If any of the elements in {@code 'posArr'} contain 109 * index-pointers that are out of range of {@code Vector} parameter {@code 'page'}, then java 110 * will, naturally, throw this exception. 111 */ 112 public static String print( 113 Vector<? extends HTMLNode> page, int[] posArr, 114 BiConsumer<HTMLNode, StringBuffer> printerVersion 115 ) 116 { 117 StringBuffer sb = new StringBuffer(); 118 for (int i : posArr) printerVersion.accept(page.elementAt(i), sb); 119 return sb.toString(); 120 } 121 122 /** 123 * Converts HTML to a {@code String} - adding readable notes & messages. This version 124 * shall only print nodes whose index "is pointed to" by the elements of the position-index 125 * array parameter {@code int[] posArr}. 126 * 127 * <BR /><BR /><B CLASS=JDDescLabel>Note about Usability:</B> 128 * 129 * <BR />This version of print can be invaluable during debugging when trolling through pages 130 * of HTML is reduced to only the indexes that are indicated by an index-pointer array. The 131 * addition of a "radix" means that some nodes before and after the identified node can be 132 * looked at too. 133 * 134 * @param page Any vectorized-html page or sub-page. 135 * 136 * @param posArr This is an array of index-pointers into the vectorized-html webpage 137 * parameter {@code 'page'}. These arrays are usually created by calls to the {@code package 138 * NodeSearch} using classes with the <B>{@code 'Find'} Key-Word</B>. Such classes return 139 * integer-arrays of pointers to nodes that matched a specific search criteria. 140 * 141 * @param radix The number of nodes, in both the forward and reverse directions, to include 142 * in the output for a match. 143 * 144 * @param nodesHaveBeenSkippedString This will be printed whenever the print-logic has skipped 145 * nodes in the list during printing. An example of a good {@code String} to use would just be 146 * {@code Sting s = "***** Nodes Skipped *****\n";}, but any choice will do - so long as it 147 * gives the appearance the during printing there are "blank spots" that skipped some of the 148 * content of the html. 149 * 150 * @param addColorCurlyBracesToRequestedNodes If this is {@code TRUE}, and the 151 * {@code class Shell.C} has its color {@code String} evaluated, because the program is running 152 * on some acceptable version of UNIX, then a bright-green colored curly-brace set will 153 * surround each node that is explicitly a member of the index-pointer-array, parameter 154 * {@code 'posArr'} 155 * 156 * <BR /><BR />If this is unclear, this method prints every node that is pointed-to by the 157 * {@code 'posArr'} parameter. In addition to these nodes, it will print {@code 'radix'} nodes 158 * before and {@code 'radix'} nodes after each of the elements pointed to by the 159 * {@code 'posArr'} parameter. When viewing the output, if it is important to know which nodes 160 * are explicitly in the 'request-list' then adding bright-green curly braces to those output 161 * nodes will differentiate them from other nodes that are being printed because of the 162 * {@code radix} parameter. 163 * 164 * @param printerVersion The complicated-looking function-pointer comes from the package 165 * {@code 'java.util.function.'} The literal code to pass to this parameter would be: 166 * <SPAN STYLE="color: blue; font-weight: bold;">Debug::A, Debug::B ... Debug::K</SPAN>. The 167 * programmer may also create a print-function if so desired, and pass that using a 168 * function-pointer or a {@code lambda-expression} 169 * 170 * @return a pretty printed {@code String} of the nodes in this {@code Vector} pointed-to by 171 * the elements of {@code 'posArr'}, surrounded by {@code 'radix'} number of nodes in either 172 * direction. 173 * 174 * @throws ArrayIndexOutOfBoundsException If any of the elements in {@code posArr} contain 175 * index-pointers that are out of range of {@code Vector}-parameter {@code 'page'}, then java 176 * will, naturally, throw this exception 177 * 178 * @see Torello.Java.C 179 */ 180 public static String print( 181 Vector<? extends HTMLNode> page, int[] posArr, int radix, 182 String nodesHaveBeenSkippedString, 183 boolean addColorCurlyBracesToRequestedNodes, 184 BiConsumer<HTMLNode, StringBuffer> printerVersion 185 ) 186 { 187 StringBuffer sb = new StringBuffer(); 188 189 // Used internally to print-curly braces 190 TreeSet<Integer> ts = null; 191 192 // Initialize it if the curly-braces are requested 193 if (addColorCurlyBracesToRequestedNodes) 194 { 195 ts = new TreeSet<>(); 196 for (int pos : posArr) ts.add(Integer.valueOf(pos)); 197 } 198 199 int start = 0; 200 int end = 0; 201 202 for (int i : posArr) 203 { 204 // Start at precisely the current index-pointer MINUS the radix. 205 // OR ... If the loop is about to "reprint" a node because the radix is larger than the 206 // space between two consecutive nodes - then start at the node just after the 207 // last node that was printed. 208 209 start = Math.max(i - radix, end + 1); 210 211 // A large radix might get the loop past the end of the vector, AVOID THAT. 212 if (start > (page.size() - 1)) break; 213 214 215 // If the next node to be printed is immediately after the previous node that was 216 // printed IN THE UNDERLYING HTML, then no nodes have been skipped, so don't print the 217 // "nodesHaveBeenSkippedString" ... otherwise print it! 218 219 if (start > (end + 1)) sb.append(nodesHaveBeenSkippedString); 220 221 // Make sure not to go past the last node in the string, or exception will throw. 222 end = Math.min(i + radix, (page.size() - 1)); 223 224 225 // It is possible that 'start' is greater than 'end' (too much overlap), in which case 226 // the outer loop will continue on to the next index-pointer. 227 // NOTE: uses 'j <= end' NOT 'j < end' !!! (TRICKY) 228 229 if (addColorCurlyBracesToRequestedNodes) 230 231 for (int j=start; j <= end; j++) 232 { 233 boolean addColorBrackets = ts.contains(Integer.valueOf(j)); 234 235 if (addColorBrackets) 236 sb.append(BGREEN + "{" + RESET); 237 238 printerVersion.accept(page.elementAt(j), sb); 239 240 if (addColorBrackets) 241 sb.append(BGREEN + "}" + RESET); 242 } 243 244 else 245 for (int j=start; j <= end; j++) 246 printerVersion.accept(page.elementAt(j), sb); 247 } 248 249 return sb.toString(); 250 } 251 252 253 // ******************************************************************************************** 254 // ******************************************************************************************** 255 // Protected, Internal Print Methods 256 // ******************************************************************************************** 257 // ******************************************************************************************** 258 259 260 /** 261 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 262 * <CODE><B>Print Style 'A'</B></CODE> 263 * 264 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 265 * @param sb the {@code StringBuffer} that is receiving the print command. 266 * @see TagNode#str 267 */ 268 public static void A(HTMLNode n, StringBuffer sb) 269 { 270 String name = n.getClass().getSimpleName(); 271 272 273 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 274 // exception. 275 276 if (name.equals("")) name = "Anonymous Class"; 277 278 sb.append("[" + name + ":" + n.str + "]"); 279 } 280 281 /** 282 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 283 * <CODE><B>Print Style 'B'</B></CODE> 284 * 285 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 286 * @param sb the {@code StringBuffer} that is receiving the print command. 287 * @see TagNode#str 288 */ 289 public static void B(HTMLNode n, StringBuffer sb) 290 { 291 String name = n.getClass().getSimpleName(); 292 293 294 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 295 // exception. 296 297 if (name.equals("")) name = "Anonymous Class"; 298 299 sb.append("[" + name + ", StrLen=" + n.str.length() + ": " + n.str + "]"); 300 } 301 302 /** 303 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 304 * <CODE><B>Print Style 'C'</B></CODE> 305 * 306 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 307 * @param sb the {@code StringBuffer} that is receiving the print command. 308 * 309 * @see TagNode#str 310 * @see TagNode#tok 311 * @see TagNode#isClosing 312 */ 313 public static void C(HTMLNode n, StringBuffer sb) 314 { 315 String name = n.getClass().getSimpleName(); 316 317 318 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 319 // exception. 320 321 if (name.equals("")) name = "Anonymous Class"; 322 323 if (n.isTagNode()) sb.append( 324 "[" + name + ", n.tok=" + ((TagNode) n).tok + ", " + 325 "n.isClosing=" + ((TagNode) n).isClosing + ": " + n.str + "]" 326 ); 327 328 else 329 sb.append("[" + name + ": " + n.str + "]"); 330 } 331 332 /** 333 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 334 * <CODE><B>Print Style 'D'</B></CODE> 335 * 336 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 337 * @param sb the {@code StringBuffer} that is receiving the print command. 338 * 339 * @see TagNode#str 340 * @see TagNode#tok 341 * @see TagNode#isClosing 342 */ 343 public static void D(HTMLNode n, StringBuffer sb) 344 { 345 String name = n.getClass().getSimpleName(); 346 347 348 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 349 // exception. 350 351 if (name.equals("")) name = "Anonymous Class"; 352 353 if (n.isTagNode()) sb.append( 354 "[" + name + ", StrLen=" + n.str.length() + ", n.tok=" + ((TagNode) n).tok + ", " + 355 "n.isClosing=" + ((TagNode) n).isClosing + ": " + n.str + "]" 356 ); 357 358 else 359 sb.append("[" + name + ", StrLen=" + n.str.length() + ": " + n.str + "]"); 360 } 361 362 /** 363 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 364 * <CODE><B>Print Style 'E'</B></CODE> 365 * 366 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 367 * @param sb the {@code StringBuffer} that is receiving the print command. 368 * 369 * @see TagNode#str 370 * @see TagNode#tok 371 * @see TagNode#isClosing 372 */ 373 public static void E(HTMLNode n, StringBuffer sb) 374 { 375 String name = n.getClass().getSimpleName(); 376 377 378 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 379 // exception. 380 381 if (name.equals("")) name = "Anonymous Class"; 382 383 if (n.isTagNode()) sb.append( 384 "[" + name + ", StrLen=" + n.str.length() + ", n.tok=" + ((TagNode) n).tok + ", " + 385 "n.isClosing=" + ((TagNode) n).isClosing + "]\n[" + n.str + "]\n" 386 ); 387 388 else 389 sb.append("[" + name + ", StrLen=" + n.str.length() + "]\n[" + n.str + "]\n"); 390 } 391 392 /** 393 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 394 * <CODE><B>Print Style 'F'</B></CODE> 395 * 396 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 397 * @param sb the {@code StringBuffer} that is receiving the print command. 398 * 399 * @see TagNode#str 400 * @see TagNode#isClosing 401 * @see TagNode#toStringAV() 402 */ 403 public static void F(HTMLNode n, StringBuffer sb) 404 { 405 String name = n.getClass().getSimpleName(); 406 407 408 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 409 // exception. 410 411 if (name.equals("")) name = "Anonymous Class"; 412 413 if (n.isTagNode() && (! ((TagNode) n).isClosing)) 414 sb.append(((TagNode) n).toStringAV()); 415 416 else 417 sb.append("[" + name + ", StrLen=" + n.str.length() + "]\n[" + n.str + "]\n"); 418 } 419 420 /** Method 'G' is a hack - uses a global variable - THIS IS A HACK. DO NOT WORRY ABOUT IT. */ 421 private static boolean lastWasNewLine = false; 422 423 /** 424 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 425 * <CODE><B>Print Style 'G'</B></CODE> 426 * 427 * <BR /><BR /><B CLASS=JDDescLabel>Thread Safety Point:</B> 428 * <BR />Print Style G <I>is not {@code Thread} safe!</I>. 429 * 430 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 431 * @param sb the {@code StringBuffer} that is receiving the print command. 432 * 433 * @see TagNode#str 434 * @see TagNode#tok 435 * @see TagNode#isClosing 436 * @see TagNode#toStringAV() 437 */ 438 public static void G(HTMLNode n, StringBuffer sb) 439 { 440 String name = n.getClass().getSimpleName(); 441 442 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 443 // exception. 444 445 if (name.equals("")) name = "Anonymous Class"; 446 447 TagNode tn = null; 448 449 if ( n.isTagNode() 450 && (! (tn = (TagNode) n).isClosing) 451 && (tn.str.length() > (tn.tok.length() + 4)) 452 ) 453 { 454 sb.append((lastWasNewLine ? "" : "\n") + ((TagNode) n).toStringAV()); 455 lastWasNewLine = true; 456 } 457 458 else 459 { 460 sb.append("[" + name + ", StrLen=" + n.str.length() + ": " + n.str + "]"); 461 lastWasNewLine = false; 462 }; 463 } 464 465 /** 466 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 467 * <CODE><B>Print Style 'H'</B></CODE> 468 * 469 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 470 * @param sb the {@code StringBuffer} that is receiving the print command. 471 * 472 * @see C 473 * @see C#RESET 474 * @see C#BRED 475 * @see C#BCYAN 476 * @see TagNode#str 477 * @see TagNode#tok 478 * @see TagNode#isClosing 479 */ 480 public static void H(HTMLNode n, StringBuffer sb) 481 { 482 String name = n.getClass().getSimpleName(); 483 484 485 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 486 // exception. 487 488 if (name.equals("")) name = "Anonymous Class"; 489 490 if (n.isTagNode()) sb.append( 491 "[" + name + ", StrLen=" + BCYAN + n.str.length() + RESET + ", " + 492 "n.tok=" + BCYAN + ((TagNode) n).tok + RESET +", " + 493 "n.isClosing=" + BCYAN + ((TagNode) n).isClosing + RESET + "]" + 494 "[" + BRED + n.str + RESET + "]" 495 ); 496 497 else sb.append( 498 "[" + name + ", StrLen=" + BCYAN + n.str.length() + RESET + ": " + 499 BRED + n.str + RESET + "]" 500 ); 501 } 502 503 /** 504 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 505 * <CODE><B>Print Style 'I'</B></CODE> 506 * 507 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 508 * @param sb the {@code StringBuffer} that is receiving the print command. 509 * 510 * @see C 511 * @see C#RESET 512 * @see C#BRED 513 * @see C#BCYAN 514 * @see TagNode#str 515 * @see TagNode#tok 516 */ 517 public static void I(HTMLNode n, StringBuffer sb) 518 { 519 String name = n.getClass().getSimpleName(); 520 521 522 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 523 // exception. 524 525 if (name.equals("")) name = "Anonymous Class"; 526 527 if (n.isTagNode()) sb.append( 528 "[" + name + ", StrLen=" + BCYAN + n.str.length() + RESET + ", " + 529 "n.tok=" + BCYAN + ((TagNode) n).tok + RESET + ", " + 530 "n.isClosing=" + BCYAN + ((TagNode) n).isClosing + RESET + "]\n" + 531 "[" + BRED + n.str + RESET + "]\n" 532 ); 533 534 else sb.append( 535 "[" + name + ", StrLen=" + BCYAN + n.str.length() + RESET + "]\n" + 536 "[" + BRED + n.str + RESET + "]\n" 537 ); 538 } 539 540 /** 541 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 542 * <CODE><B>Print Style 'J'</B></CODE> 543 * 544 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 545 * @param sb the {@code StringBuffer} that is receiving the print command. 546 * 547 * @see C 548 * @see C#RESET 549 * @see C#BRED 550 * @see C#BYELLOW 551 * @see TagNode#str 552 */ 553 public static void J(HTMLNode n, StringBuffer sb) 554 { 555 String name = n.getClass().getSimpleName(); 556 557 558 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent 559 // exception. 560 561 if (name.equals("")) name = "Anonymous Class"; 562 563 if (n.isTagNode()) 564 sb.append("[" + BRED + n.str + RESET + "]"); 565 566 else if (n.isCommentNode()) 567 sb.append("[" + BYELLOW + n.str + RESET + "]"); 568 569 else 570 sb.append("[" + n.str + "]"); 571 } 572 573 /** 574 * Prints an HTML Element ({@code TagNode, TextNode} or {@code CommentNode}) using 575 * <CODE><B>Print Style 'K'</B></CODE> 576 * 577 * @param n An {@code HTMLNode} that will print to the {@code StringBuffer} 578 * @param sb the {@code StringBuffer} that is receiving the print command. 579 * 580 * @see C 581 * @see C#RESET 582 * @see C#BRED 583 * @see C#BYELLOW 584 * @see TagNode#str 585 */ 586 public static void K(HTMLNode n, StringBuffer sb) 587 { 588 String name = n.getClass().getSimpleName(); 589 590 // Extremely Unlikely Programmer has extended HTMLNode, but just in case, to prevent exception. 591 if (name.equals("")) name = "Anonymous Class"; 592 593 if (n.isTagNode()) 594 sb.append("[" + BRED + n.str + RESET + "]\n"); 595 596 else if (n.isCommentNode()) 597 sb.append("[" + BYELLOW + n.str + RESET + "]\n"); 598 599 else 600 sb.append("[" + n.str + "]\n"); 601 } 602}