001package Torello.HTML.NodeSearch; 002 003import java.util.*; 004import java.util.regex.Pattern; 005import java.util.function.Predicate; 006 007import Torello.HTML.*; 008import Torello.Java.LV; 009 010/** 011 * {@code Static} methods for building and instantiating an 012 * {@link HNLI}<CODE><</CODE>{@link TagNode}<CODE>></CODE> (which extends the basic 013 * iterator class) for iterating the tags inside of an HTML-{@code Vector}, using match-critera 014 * which specify attribute name & value requirements. 015 * 016 * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=InnerTagIterator> 017 */ 018@Torello.JavaDoc.JDHeaderBackgroundImg 019@Torello.JavaDoc.StaticFunctional 020public class InnerTagIterator 021{ 022 private InnerTagIterator() { } 023 024 // **** CRITERIA: htmlTag 025 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, String htmlTag, String innerTag) 026 { return GET(html, ARGCHECK.htmlTag(htmlTag), ARGCHECK.innerTag(innerTag), ARGCHECK.TRUE); } 027 028 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, String htmlTag, String innerTag, TextComparitor tc, String... compareStr) 029 { return GET(html, ARGCHECK.htmlTag(htmlTag), ARGCHECK.innerTag(innerTag), ARGCHECK.TC(tc, compareStr)); } 030 031 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, String htmlTag, String innerTag, Pattern p) 032 { return GET(html, ARGCHECK.htmlTag(htmlTag), ARGCHECK.innerTag(innerTag), ARGCHECK.REGEX(p)); } 033 034 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, String htmlTag, String innerTag, Predicate<String> attributeValuePred) 035 { return GET(html, ARGCHECK.htmlTag(htmlTag), ARGCHECK.innerTag(innerTag), attributeValuePred); } 036 037 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, Predicate<TagNode> p, String... htmlTags) 038 { return GET(html, p, ARGCHECK.htmlTags(htmlTags)); } 039 040 // **** CRITERIA, htmlTag null 041 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, String innerTag) 042 { return GET(html, null, ARGCHECK.innerTag(innerTag), ARGCHECK.TRUE); } 043 044 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, String innerTag, TextComparitor tc, String... compareStr) 045 { return GET(html, null, ARGCHECK.innerTag(innerTag), ARGCHECK.TC(tc, compareStr)); } 046 047 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, String innerTag, Pattern p) 048 { return GET(html, null, ARGCHECK.innerTag(innerTag), ARGCHECK.REGEX(p)); } 049 050 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, String innerTag, Predicate<String> attributeValuePred) 051 { return GET(html, null, ARGCHECK.innerTag(innerTag), attributeValuePred); } 052 053 public static HNLI<TagNode> get(Vector<? extends HTMLNode> html, Predicate<TagNode> p) 054 { return GET(html, p); } 055 056 // ****************************************************************************** 057 // private builder methods 058 // ****************************************************************************** 059 060 private static HNLI<TagNode> GET 061 (Vector<? extends HTMLNode> html, Predicate<TagNode> p, String... htmlTags) 062 { 063 Predicate<TagNode> p2 = (htmlTags.length == 0) 064 ? (TagNode tn) -> (! tn.isClosing) && p.test(tn) 065 : (TagNode tn) -> (! tn.isClosing) && tn.isTag(htmlTags) && p.test(tn); 066 067 return new HNLI<TagNode>(html, p2, TagNode.class); 068 } 069 070 private static HNLI<TagNode> GET 071 (Vector<? extends HTMLNode> html, String htmlTag, String innerTag, Predicate<String> compare) 072 { 073 if (htmlTag == null) return new HNLI<TagNode>(html, 074 tagNode -> 075 { 076 if (tagNode.isClosing) return false; 077 078 String innerTagValue = tagNode.AVOPT(innerTag); 079 080 return (innerTagValue != null) && compare.test(innerTagValue); 081 082 }, TagNode.class 083 // The HNLI expects the last parameter to its constructor to be the class of the 084 // iterator. This is the solution to the "Java Generics Type Erasure Problem" 085 ); 086 087 else return new HNLI<TagNode>(html, 088 tagNode -> 089 { 090 if (tagNode.isClosing) return false; 091 092 if (! htmlTag.equals(tagNode.tok)) return false; 093 094 String innerTagValue = tagNode.AVOPT(innerTag); 095 096 return (innerTagValue != null) && compare.test(innerTagValue); 097 098 }, TagNode.class 099 // REMEMBER, the HNLI<...> Generic class will iterate through 100 // TagNode's, TextNode's and CommentNode's. The only one of these 101 // three that may be more difficult is the "TagNode" class - because it has 102 // both opening and closing versions of the node, and more data-fields. The 103 // TextNode and CommentNode classes do not have "extra" data-fields that contain 104 // more information, nor are there "different types" of TextNode's and CommentNode's 105 // The HNLI expects the last parameter to its constructor to be the class of the 106 // iterator. This is the solution to the "Java Generics Type Erasure Problem" 107 ); 108 } 109 110}