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 | package Torello.HTML; import Torello.Java.LV; import Torello.Java.Function.IntTFunction; import java.util.Vector; import java.util.stream.IntStream; class Update { static int[] update( final Vector<? super TagNode> html, final AUM mode, final int sPos, final int ePos, final String innerTag, final IntTFunction<TagNode, String> newITValueStrGetter, final SD quote ) { InnerTagKeyException.check(innerTag); // Use Java Stream to keep a list of Vector-Locations that were updated / modified. IntStream.Builder b = IntStream.builder(); // This optimization is the same as the one in TagNode.openTagPWA(). However, that method // cannot be used here, becaue for AUM.set, zero-attribute TagNode's **ALSO** have to be // updated. So this is re-implemented here. int MIN = 3 + innerTag.length(); // Loop Variables LV l = new LV(sPos, ePos, html); TagNode tn; for (int i=l.start; i < l.end; i++) // Only instances of Opening-TagNodes need to be checked - All others should be skipped if ((tn = ((HTMLNode) html.elementAt(i)).openTag()) != null) // AUM.Set does not require the attribute to already exist // **OR** Check for minimum possible str-length to have the attribute at all. if ((mode == AUM.Set) || (tn.str.length() >= (MIN + tn.tok.length()))) // If AUM.update returns a **NEW** (non-null) TagNode, replace the old one. // Make sure to use the User-Provided Function-Pointer if ((tn = mode.update(tn, innerTag, newITValueStrGetter.apply(i, tn), quote)) != null) { // Replace the old TagNode html.setElementAt(tn, i); // Make sure to keep the index where it resides, to return to the user 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 AUM mode, final int[] posArr, final String innerTag, final IntTFunction<TagNode, String> newITValueStrGetter, final SD quote ) { InnerTagKeyException.check(innerTag); // Use Java Stream to keep a list of Vector-Locations that were updated / modified. IntStream.Builder b = IntStream.builder(); // minimum possible length to have an attribute at all. // '<', TOKEN, SPACE, ATTRIBUTE, '>' int MIN = 3 + innerTag.length(); 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); // AUM.Set *DOES NOT* require the attribute to exist already (the other *DO*) if (mode != AUM.Set) // Minimum length of this element before it even could have the named inner-tag // '<', TOKEN, SPACE, ATTRIBUTE, '=', '>' if (tn.str.length() < (MIN + tn.tok.length())) continue; // Make sure to use the User-Provided Function-Pointer tn = mode.update(tn, innerTag, newITValueStrGetter.apply(i, tn), quote); // if 'tn' is non-null ==> an update *WAS* performed if (tn != null) { // Replace the old TagNode html.setElementAt(tn, i); // Make sure to keep the index where it resides, to return to the user b.accept(i); } } // Build the IntStream, Convert the IntStream -> int[], Return it. return b.build().toArray(); } } |