1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | package Torello.HTML; import static Torello.HTML.Attributes.Filter; import Torello.Java.LV; import java.util.Vector; import java.util.List; import java.util.Properties; import java.util.stream.IntStream; import java.util.stream.Collectors; class UpdateWithFilter { static int[] update( final Vector<? super TagNode> html, final int sPos, final int ePos, final Filter f ) { // Save Modified node-locations in a java stream (Use the "Primitive Int Stream") IntStream.Builder b = IntStream.builder(); // Temp-Loop Variables LV l = new LV(sPos, ePos, html); Properties p; TagNode tn; for (int i=l.start; i < l.end; i++) if ( // Only Opening TagNode's that could possibly have attributes. ((tn = ((HTMLNode) html.elementAt(i)).openTagPWA()) != null) // Retrieve all Attribute Key-Value Pairs. Take note of surrounding quotes. && ((p = tn.allAV(true, true)).size() > 0) // Run the provided filter logic, if it returns TRUE, then build new TagNode && f.filter(tn.tok, p) ) { // This makes sure not to leave out any possible "boolean" (a.k.a "Key Only") // attributes when we rebuild the new TagNode. An example of a "boolean" attribute // in HTML is "HIDDEN" which is a key that does not require any value to convey its // purpose or function. Sometimes web-page designers might type "HIDDENT=TRUE", // but it is not necessary. In any case, the "allAV(boolean, boolean)" method only // returns attributes that have BOTH a 'key' AND a 'value'. List<String> keyOnly = tn.allKeyOnlyAttributes(true).collect(Collectors.toList()); // Build a new TagNode, then replace the old one tn = new TagNode(tn.tok, p, keyOnly, null, tn.str.endsWith("/>")); html.setElementAt(tn, i); // Save the vector-index where a replacement has occurred. The user will be // provided a list of all locations where an old TagNode was replaced with a new one. b.accept(i); } // Build the IntStream, Convert the IntStream -> int[], Return it. return b.build().toArray(); } static int[] update( final Vector<? super TagNode> html, final int[] posArr, final Filter f ) { // Use Java Stream to keep a list of Vector-Locations that were updated / modified. IntStream.Builder b = IntStream.builder(); for (int i: posArr) { HTMLNode n = (HTMLNode) html.elementAt(i); if (! n.isTagNode()) throw new TagNodeExpectedException(i); TagNode tn = (TagNode) n; if (tn.isClosing) throw new OpeningTagNodeExpectedException(i); // If element-length < tok-length+5, there are no attributes! // '<', TOKEN, SPACE, ATTRIBUTE<MIN-1>, '=', '>' if (tn.str.length() < (tn.tok.length() + 5)) continue; // Retrieve all Attribute Key-Value Pairs. Properties p = tn.allAV(true, true); // This makes sure not to leave out any possible "boolean" (a.k.a "Key Only") // attributes when we rebuild the new TagNode. An example of a "boolean" attribute // in HTML is "HIDDEN" which is a key that does not require any value to convey its // purpose or function. Sometimes web-page designers might type "HIDDENT=TRUE", but // it is not necessary. In any case, the "allAV(boolean, boolean)" method only returns // attributes that have BOTH a 'key' AND a 'value'. List<String> keyOnly = tn.allKeyOnlyAttributes(true).collect(Collectors.toList()); // Run the provided filter logic, if it returns TRUE, then build new TagNode if ((p.size() > 0) && f.filter(tn.tok, p)) { // Build a new TagNode, and replace the old one. tn = new TagNode(tn.tok, p, keyOnly, null, tn.str.endsWith("/>")); html.setElementAt(tn, i); // Save the vector-index where a replacement has occured. The user will be // provided a list of all locations where an old TagNode was replaced with a // new one. b.accept(i); } } // Build the IntStream, Convert the IntStream -> int[], Return it. return b.build().toArray(); } } |