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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | package Torello.HTML; import java.util.Vector; import java.io.Serializable; import java.util.Comparator; /** * The abstract parent class of all three {@code NodeIndex} classes, {@link TagNodeIndex}, * {@link TextNodeIndex} and {@link CommentNodeIndex}. * * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=NODE_INDEX> * * @param <NODE> The class of {@code HTMLNode} represented by this {@code NodeIndex} instance. * @see HTMLNode * @see CommentNodeIndex * @see TagNodeIndex * @see TextNodeIndex */ @SuppressWarnings("rawtypes") public abstract class NodeIndex<NODE extends HTMLNode> implements CharSequence, Serializable, Cloneable, Replaceable { // ******************************************************************************************** // ******************************************************************************************** // Fields // ******************************************************************************************** // ******************************************************************************************** /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ public static final long serialVersionUID = 1; /** * An index to a node from a web-page. This index must point to a the exact same node inside * of a vectorized-html page as the node stored in member-field {@code HTMLNode 'n'}. */ public final int index; /** * A {@code HTMLNode} from a web-page. This node is supposed to be the same node stored at the * index specified by member-field {@code int 'index'} of some vectorized-html web-page in * memory or on disk. */ public NODE n; // ******************************************************************************************** // ******************************************************************************************** // Constructor // ******************************************************************************************** // ******************************************************************************************** /** * a default constructor. This assigns a value to the index field. * * @param index This is the vector-index location of HTMLNode 'n' inside of a vectorized-HTML * web-page. * * <BR /><BR /><B><SPAN STYLE="color: red;">STALE DATA NOTE:</B></SPAN> This class is a * minor-use class, not one of the primary data classes. This instance shall become 'useless' * the moment the vector that was used to instantiate this class is modified, and the node 'n' * is no longer at vector-index 'index.' These "NodeIndex" classes are retained, not * deprecated due to the fundamental nature of using the classes of the NodeSearch Package. * Data is easily made stale. Generally, when modifying HTML Vectors, the easiest thing to do * is <I><B>to remember to modify a vector at specific locations by iterating from the end of * the vector, back to the beginning.</I></B> This will generally prevent "state-data * vector-indexes" from rearing their ugly head. * * @param n An HTMLNode that needs to be the node found in the underlying vector at * vector-index 'index.' * * @throws IndexOutOfBoundsException if {@code index} is negative, this exception is thrown. * @throws NullPointerException if {@code n} is null. */ protected NodeIndex(int index, NODE n) { this.index = index; this.n = n; if (n == null) throw new NullPointerException( "HTMLNode parameter 'n' to this constructor was passed a null value, but this " + "is not allowed here." ); if (index < 0) throw new IndexOutOfBoundsException( "Integer parameter 'index' to this constructor was passed a negative value: " + index ); } /** * Simple dispatch method helper that switches on the class of input parameter {@code 'n'}. * * @param n Any of the three Java HTML defined {@code HTMLNode} subclasses - {@link TagNode}, * {@link TextNode} or {@code CommentNode} * * @return A {@code NodeIndex} inheriting class that is appropriate to {@code 'n'}. * * @throws IllegalArgumentException If the user has extended class {@code HTMLNode}, and passed * this unrecognized {@code HTMLNode} Type. */ public static final NodeIndex<?> newNodeIndex(int index, HTMLNode n) { Class<?> newNodeClass = n.getClass(); if (TagNode.class.isAssignableFrom(newNodeClass)) return new TagNodeIndex(index, (TagNode) n); if (TextNode.class.isAssignableFrom(newNodeClass)) return new TextNodeIndex(index, (TextNode) n); if (CommentNode.class.isAssignableFrom(newNodeClass)) return new CommentNodeIndex(index, (CommentNode) n); throw new IllegalArgumentException ("Parameter 'n' has a Type that is an Unrecognized HTMLNode-SubClass Type"); } // ******************************************************************************************** // ******************************************************************************************** // java.lang.Object Methods // ******************************************************************************************** // ******************************************************************************************** /** * Java's {@code public boolean equals(Object o)} requirements. * * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> * * <BR />This method is final, and cannot be modified by sub-classes. * * @param o This may be any Java Object, but only ones of {@code 'this'} type whose * internal-values are identical will bring this method to return true. * * @return {@code TRUE} If {@code 'this'} equals another object {@code HTMLNode}. */ public final boolean equals(Object o) { if (o == null) return false; if (o == this) return true; if (! this.getClass().equals(o.getClass())) return false; NodeIndex<?> other = (NodeIndex) o; return other.n.str.equals(this.n.str) && (other.index == this.index); } /** * Java's hash-code requirement. * * @return A hash-code that may be used when storing this node in a java hashed-collection. * The {@link #index} of this {@code NodeIndex} ought to be be a unique hash. */ public int hashCode() { return index; } /** * Java's {@code interface Comparable<T>} requirements. This does a very simple comparison * using the vector-index position. * * <BR /><BR /><B><SPAN STYLE="color: red;">FINAL METHOD:</B></SPAN> This method is final, and * cannot be modified by sub-classes. * * @param ni Any other {@code NodeIndex} to be compared to {@code 'this' NodeIndex} * * @return An integer that fulfils Java's {@code interface Comparable<T> public boolean * compareTo(T t)} method requirements. * * @see #index */ // @SuppressWarnings("rawtypes") // public final int compareTo(NodeIndex ni) // { return this.index - ni.index; } /** * This is an "alternative Comparitor" that can be used for sorting instances of this class. * It should work with the {@code Collections.sort(List, Comparator)} method in the standard * JDK package {@code java.util.*;} * * <BR /><BR /><B CLASS=JDDescLabel>Comparitor Heuristic:</B> * * <BR />This version utilizes the standard JDK method {@code String.compareTo(String)}. * * @see HTMLNode#str */ public static final Comparator<TextNodeIndex> comp2 = (TextNodeIndex txni1, TextNodeIndex txni2) -> txni1.n.str.compareTo(txni2.n.str); /** * This is an "alternative Comparitor" that can be used for sorting instances of this class. * It should work with the {@code Collections.sort(List, Comparator)} method in the standard * JDK package {@code java.util.*;} * * <BR /><BR /><B CLASS=JDDescLabel>Comparitor Heuristic:</B> * * <BR />This version utilizes the standard JDK method * {@code String.compareToIgnoreCase(String)}. * * @see HTMLNode#str */ public static final Comparator<TextNodeIndex> comp3 = (TextNodeIndex txni1, TextNodeIndex txni2) -> txni1.n.str.compareToIgnoreCase(txni2.n.str); // ******************************************************************************************** // ******************************************************************************************** // CharSequence Methods // ******************************************************************************************** // ******************************************************************************************** /** * Returns the char value at the specified index of the {@code public final String str} field * of {@code 'this'} field {@code public final HTMLNode n}. * An index ranges from zero to length() - 1. The first char value of the sequence is at index * zero, the next at index one, and so on, as for array indexing. * * <BR /><BR />If the char value specified by the index is a surrogate, the surrogate value is * returned. * * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> * * <BR />This method is final, and cannot be modified by sub-classes. * * @param index The index of the char value to be returned * * @return The specified char value */ public final char charAt(int index) { return n.str.charAt(index); } /** * Returns the length of the {@code public final String str} field of {@code 'this'} field * {@code public final HTMLNode n}. The length is the number of 16-bit chars in the sequence. * * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> * * <BR />This method is final, and cannot be modified by sub-classes. * * @return the number of chars in {@code this.n.str} */ public final int length() { return n.str.length(); } /** * Returns a CharSequence that is a subsequence of the {@code public final String str} field of * {@code 'this'} field {@code public final HTMLNode n}. * The subsequence starts with the char value at the specified index and ends with the char * value at index end - 1. The length (in chars) of the returned sequence is end - start, so * if start == end then an empty sequence is returned. * * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> * * <BR />This method is final, and cannot be modified by sub-classes. * * @param start The start index, inclusive * * @param end The end index, exclusive * * @return The specified subsequence */ public final CharSequence subSequence(int start, int end) { return n.str.substring(start, end); } /** * Returns the {@code public final String str} field of {@code 'this'} field {@code public * final HTMLNode n}. * * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B> * * <BR />This method is final, and cannot be modified by sub-classes. * * @return A string consisting of exactly this sequence of characters. * * @see HTMLNode#str */ public final String toString() { return n.str; } // ******************************************************************************************** // ******************************************************************************************** // Replaceable Methods // ******************************************************************************************** // ******************************************************************************************** public int originalSize() { return 1; } public int currentSize() { return 1; }; public int originalLocationStart() { return index; } public int originalLocationEnd() { return index + 1; } public NODE firstCurrentNode() { return n; } public NODE lastCurrentNode() { return n; } private Vector<HTMLNode> CURRENT_NODES = null; public Vector<HTMLNode> currentNodes() { if (CURRENT_NODES == null) CURRENT_NODES = new Vector<>(1); CURRENT_NODES.add(n); return CURRENT_NODES; } public boolean addAllInto(Vector<HTMLNode> fileVec) { return fileVec.add(n); } public boolean addAllInto(int index, Vector<HTMLNode> fileVec) { fileVec.insertElementAt(n, index); return true; } public int update(Vector<HTMLNode> fileVec) { fileVec.setElementAt(n, index); return 0; } } |