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