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 127 128 129 130 131 | package Torello.HTML; /** * Represents HTML Comments, and is one of only three HTML Element Classes provided by the Java * HTML Library Tool, and also one of the three data-classes that can be generated by the HTML * Parser. * * <EMBED CLASS='external-html' DATA-FILE-ID=COMMENT_NODE> * * <EMBED CLASS='external-html' DATA-FILE-ID=HTML_NODE_SUB_IMG> * * @see TagNode * @see TextNode * @see HTMLNode */ @Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="HTML_NODE_SUBCLASS") public final class CommentNode extends HTMLNode implements CharSequence, java.io.Serializable, Cloneable, Comparable<CommentNode> { /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ public static final long serialVersionUID = 1; /** * This stores a copy of the body of the comment. Specifically, (and simply) the java string * method {@code body = str.substring(4, str.length() - 3);} is called and stored here. Yes, * this does mean that extra memory / double memory is used to store comments, however the * trade-offs are somewhat high. * * <BR /><BR /><B><SPAN STYLE="color: red;">TRADEOFFS:</B></SPAN> If the programmer or user * ever wishes to perform a search, it becomes obvious that leaving off the beginning and * trailing {@code '<!--'} and {@code '-->'} markers when specifying a search provides more * easily readable code, and less error prone code. Thus, when using the * {@code CommentNodeFind, Get, Peek, Poll, etc...} methods in the {@code package NodeSearch}, * a Java String {@code substring(...)} would have to be invoked on every search comparison * loop invocation. Primarily, keeping {@code class HTMLNode} and it's descendants all * immutable is a much higher priority to ensure clean code, it becomes necessary to keep a * redundant copy of the body {@code String}. */ public final String body; /** * This constructor simply makes a call to {@code super(s); } <I>a.k.a.</I> * {@code class HTML.HTMLNode} * * <BR /><BR />This constructor also checks to ensure that the internal {@code String}-field * ({@code public final String str}) contains beginning and ending comment markers: * {@code '<!--'} and {@code '-->'} * * @throws IllegalArgumentException If the passed string does not start and end with the * appropriate HTML comment-markers: {@code <!--} and {@code -->} */ public CommentNode(String s) { super(s); if (! s.startsWith("<!--")) throw new IllegalArgumentException ("The passed HTML string does not start with comment marker '<!--'"); if (! s.endsWith("-->")) throw new IllegalArgumentException ("The passed HTML string does not end with comment marker '-->'"); body = str.substring(4, str.length() - 3); if (body.contains("-->")) throw new IllegalArgumentException ("The passed HTML string has multiple occurrences of substring '-->'"); } /** * This method identifies that {@code 'this'} instance of (abstract parent-class) * {@link HTMLNode} is, indeed, an instance of sub-class {@code CommentNode}. * * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> * * <BR />This method is final, and cannot be modified by sub-classes. * * @return This method shall always return {@code TRUE} It overrides the parent-class * {@code HTMLNode} method {@link #isCommentNode()}, which always returns {@code FALSE}. */ @Override public final boolean isCommentNode() { return true; } /** * This method identifies that {@code 'this'} instance of (abstract parent-class) * {@link HTMLNode} is, indeed, an instance of sub-class {@code CommentNode}. * * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> * * <BR />This method is final, and cannot be modified by sub-classes. * * @return {@code 'this'} reference. This method can be used inside loops for improving * the readability of loop-condition expressions. See example below: * * <DIV CLASS=EXAMPLE>{@code * Vector<HTMLNode> fileVec = HTMLPage.getPageTokens(new URL("http://some.url.com"), false); * CommentNode c; * * // NOTE: The casting to class CommentNode is automatically acheived with this method, * // which can make loops a lot easier to read. Only a CommentNode instance will have * // a '.body' field. Attempting to read a '.body' field from an instance of HTMLNode * // would immediately generate a compile-time error. * * for (HTMLNode n : fileVec) * if ((c = myHTMLVector.elementAt(i).ifCommentNode()) != null) * if (c.body.equals("Some Comment Node Text")) * ... * }</div> * * <BR /><BR />This method-version overrides the parent-class-version, which always returns * null. This method is <I>not overriden by other {@code HTMLNode} sub-classes.</I> */ @Override public final CommentNode ifCommentNode() { return this; } /** * Java's {@code interface Cloneable} requirements. This instantiates a new * {@code CommentNode} with identical {@code String str} and {@code String body} fields. * @return A new {@code CommentNode} whose internal fields are identical to this one. */ public CommentNode clone() { return new CommentNode(str); } /** * Java's {@code interface Comparable<T>} requirements. This does a very simple comparison * using the underlying field {@code final String str} that all {@code HTMLNode's} contain. * @param cn Any other {@code CommentNode} to be compared to {@code 'this' CommentNode} * @return An integer that fulfils Java's {@code interface Comparable<T> public boolean * compareTo(T t)} method requirements. */ public int compareTo(CommentNode cn) { return this.body.compareToIgnoreCase(cn.body); } } |