Package Torello.HTML
Interface Replaceable
-
- All Superinterfaces:
java.lang.Comparable<Replaceable>
- All Known Implementing Classes:
CommentNodeIndex
,NodeIndex
,SubSection
,TagNodeIndex
,TextNodeIndex
public interface Replaceable extends java.lang.Comparable<Replaceable>
The classReplaceNodes
offers a great efficiency-improvement optimization for modifying vectorized-HTML. HTML Pages can be very long, and the insertion or removal of a piece or snippet of HMTL may result in the shifting of hundreds (or even thousands!) ofHTMLNode's
. This can incur a non-trivial performance cost if many there are many updates and changes to be made to a page.
Exceprt fromcurrentNodes()
:Replaceable's
are, sort-of, the exact opposite of Java'sList
method'subList'
. According to the Sun / Oracle Documentation forjava.util.List.subList(int fromIndex, int toIndex)
, any changes ffinamade to an instance of a'subList'
are immediately reflected back into the originalList
from where they were created.
TheList.subList
operation has the advantage of being extremely easy to work with - however, an HTML-PageVector
has the potential of being hundreds of nodes long. Any operations that involve insertion or deletion will likely be terribly inefficient.
When the HTML inside of aReplaceable
is modified - nothing happens to the originalVector
whatsoever!. Until a user requests that the original HTML-Vector
be updated to reflect all changes that he or she has made, the original HTML remains untouched. When an update request is finally issued, all changes are made all at once, and at the same time!
Again - seeReplaceNodes.r(Vector, Iterable, boolean)
to understand how quick updates on HTML-Pages is done using theReplaceable
interface.
Utilizing classReplaceNodes
:
ClassReplaceNodes
offers three methods for performing these optimized replacement methods. These methods are listed below. The optimization that is utilized there is to first calculate the size / length of the updatedVector
, and then do the entire update all at once. This eliminates to do any shifting and only performs a single resizing of theVector
.
These methods will work in lock-step with interface'Replaceable'
to actually perform the update after all Vectorized-HTML has been changed, sufficiently as deemed by the programmer:ReplaceNodes.r(Vector, Iterable, boolean)
ReplaceNodes.listLI(Vector, DotPair, ObjIntConsumer)
ReplaceNodes.tableTR(Vector, DotPair, ObjIntConsumer)
The Java Doc Upgrader Tool in this JAR Library heavily relies on using instances ofReplaceable
to update and modify Java Doc HTML in a fast, simple & efficient manner.
Though this class may look somewhat complicated to understand, in all reality it is actually very simple. Load a web-page from disk (or download one from the Internet) and run it through the parser (classHTMLPage
) to make a Vectorized-HTML Page. Next, build a few instances ofSubSection
which hold both the location of an HTML snippet and HTML itself.
Finallly, make whatever modifications you want to those HTML snippets, and call theReplaceNodes
method listed first in the list above! The page should be updated quickly with little cost overhead.
Peek Operation Replaceables
The classInnerTagPeekInclusive
andTagNodePeekInclusive
will always generate properly ordered / sorted references that implement theReplaceable
interface! Furthermore, these instances will be ones that are sorted and do not overlap.
This means that if a set or collection ofReplaceable's
were created using theNodeSearch 'Peek'
Search-Classes, theReplaceNodes.r(Vector, Iterable, boolean)
requirements that theReplaceable's
be ordered, sorted and non-overlapping would be automatically met.
This interface is implemented by all return-values for theNodeSearch
Peek operations.
Hi-Lited Source-Code:- View Here: Torello/HTML/Replaceable.java
- Open New Browser-Tab: Torello/HTML/Replaceable.java
File Size: 27,420 Bytes Line Count: 557 '\n' Characters Found
-
-
Method Summary
Number / Vector-Size of Nodes Modifier and Type Method int
currentSize()
int
originalSize()
Location of the Node(s) in the Original-Vector Modifier and Type Method int
originalLocationEnd()
int
originalLocationStart()
Retrieving the Node(s) Modifier and Type Method Vector<HTMLNode>
currentNodes()
HTMLNode
firstCurrentNode()
HTMLNode
lastCurrentNode()
Updating the Original-Vector, from whence these Node(s) were Extracted Modifier and Type Method int
update(Vector<HTMLNode> originalHTML)
Insert the Node(s) within this Instance into an HTML-Vector Modifier and Type Method boolean
addAllInto(int index, Vector<HTMLNode> html)
boolean
addAllInto(Vector<HTMLNode> html)
Build new Replaceable which Reflects New Nodes & Size, Incorprates New Location Modifier and Type Method default Replaceable
moveAndUpdate(int sPos)
Build new Replaceable using Original-Location, but having New Nodes & Size Modifier and Type Method default Replaceable
clearHTML()
default Replaceable
setHTML(Vector<HTMLNode> newHTML)
default Replaceable
setHTML(HTMLNode newHTML)
Build an Empty Replaceable Modifier and Type Method static Replaceable
empty(int sPos)
Create a new Replaceable, avoiding the Limitations of SubSection
&NodeIndex
Modifier and Type Method static Replaceable
create(int location, Vector<HTMLNode> html)
static Replaceable
create(DotPair location, Vector<HTMLNode> html)
static Replaceable
createInsertion(int location, Vector<HTMLNode> html)
Methods: interface java.lang.Comparable Modifier and Type Method default int
compareTo(Replaceable other)
Test if this
Instance is an Anonymous ClassModifier and Type Method default boolean
isSynthetic()
-
-
-
Method Detail
-
compareTo
default int compareTo(Replaceable other)
Java'sComparable
interface requirements.- Specified by:
compareTo
in interfacejava.lang.Comparable<Replaceable>
- Returns:
- An integer based on comparing the starting locations for two
Replaceable
instances. - Code:
- Exact Method Body:
return this.originalLocationStart() - other.originalLocationStart();
-
originalSize
int originalSize()
Reports how many nodes were copied intothis
instance. For implementing classes that inheritNodeIndex
, this value will always be one. For others, it should report exactly how manyHTMLNode's
were copied.- Returns:
- Number of nodes originally contained by
this
instance.
The purpose ofReplaceable's
is to allow a user to modify HTML using a smaller sub-list, without having to operate on the entire HTML-Vector
since adding & removing nodes is one variant ofVector
-modification, the original-size may often differ from the current-size.
When modifying HTML, if a web-page is broken into smaller-pieces, and changes are restricted to those smaller sub-lists (and the original page is rebuilt, all at once, after all changes have been made) then those modifications should require far-fewer time-consuming list-shift operations, tremendously improving the performance of the code.
-
currentSize
int currentSize()
Returns how many nodes are currently inthis
instance.- Returns:
- Number of nodes. See explanation of the original size,
versus the current size
here
-
originalLocationStart
int originalLocationStart()
Returns the start-location within the original page-Vector
from whence the HTML contents ofthis
instance were retrieved.
Start is Inclusive:
The returned value is inclusive of the actual, original-range ofthis
instance. This means the firstHTMLNode
copied intothis
instance' internal data-structure was atoriginalLocationStart()
.
Implementations of Replaceable:
The two concrete implementatons of this interface (NodeIndex
andSubSection
) - both enforce the'final'
modifier on their location-fields. (See:NodeIndex.index
andSubSection.location
).- Returns:
- The
Vector
start-index from whence this HTML was copied.
-
originalLocationEnd
int originalLocationEnd()
Returns the end-location within the original page-Vector
from whence the HTML contents ofthis
instance were retrieved.
Start is Exclusive:
The returned value is exclusive of the actual, original-range ofthis
instance. This means the lastHTMLNode
copied intothis
instance' internal data-structure was atoriginalLocationEnd() - 1
Implementations of Replaceable:
The two concrete implementatons of this interface (NodeIndex
andSubSection
) - both enforce the'final'
modifier on their location-fields. (See:NodeIndex.index
andSubSection.location
).- Returns:
- The
Vector
end-index from whence this HTML was copied.
-
currentNodes
java.util.Vector<HTMLNode> currentNodes()
All nodes currently contained by thisReplaceable
. The concrete-classes which implementReplaceable
(SubSection
&TagNodeIndex
) allow for the html they hold to be modified. The modification to aReplaceable
happens independently from the original HTML Page out of which it was copied.Replaceable's
are, sort-of, the exact opposite of Java'sList
method'subList'
. According to the Sun / Oracle Documentation forjava.util.List.subList(int fromIndex, int toIndex)
, any changes made to an instance of a'subList'
are immediately reflected back into the originalList
from where they were created.
TheList.subList
operation has the advantage of being extremely easy to work with - however, an HTML-PageVector
has the potential of being hundreds of nodes long. Any operations that involve insertion or deletion will likely be terribly inefficient.
When the HTML inside of aReplaceable
is modified - nothing happens to the originalVector
whatsoever!. Until a user requests that the original HTML-Vector
be updated to reflect all changes that he or she has made, the original HTML remains untouched. When an update request is finally issued, all changes are made all at once, and at the same time!
Again - seeReplaceNodes.r(Vector, Iterable, boolean)
to understand how quick updates on HTML-Pages is done using theReplaceable
interface.- Returns:
- An HTML-
Vector
of the nodes.
-
firstCurrentNode
HTMLNode firstCurrentNode()
The first node currently contained by thisReplaceable
- Returns:
- The First Node
-
lastCurrentNode
HTMLNode lastCurrentNode()
The last node currently contained by thisReplaceable
- Returns:
- The last node
-
addAllInto
boolean addAllInto(java.util.Vector<HTMLNode> html)
Add all nodes currently retained inthis
instance into the HTML-Vector
parameterhtml
. The nodes are appended to the end of'html'
. Implementing classesNodeIndex
andSubSection
simply use the JavaVector
method'sadd
(forNodeIndex
) andaddAll
(forSubSection
).- Parameters:
html
- The HTML-Vector
into which the nodes will be appended (to the end of thisVector
, usingVector
methodsadd
oraddAll
dependent upon whether one or more-than-one nodes are being inserted).- Returns:
- The result of
Vector
methodadd
, or methodallAll
-
addAllInto
boolean addAllInto(int index, java.util.Vector<HTMLNode> html)
Add all nodes currently retained inthis
instance into the HTML-Vector
parameterhtml
.- Parameters:
index
- The'html'
parameter'sVector
-index where these nodes are to be insertedhtml
- The HTML-Vector
into which the nodes will be appended (to the end of thisVector
, usingVector
methodsadd
oraddAll
dependent upon whether one or more-than-one nodes are being inserted).- Returns:
- The result of
Vector
methodadd
, or methodallAll
-
update
int update(java.util.Vector<HTMLNode> originalHTML)
Replaces the original range of nodes insideoriginalHTML
with the current-nodes ofthis
instance, using the original-location of the node(s).
Replaceable's Primary Value:
The main value of using theReplaceable
interface is to allow for more expedient replacing / modifying HTML Pages. If many changes need to be made to a page, first extracting and copying the sub-sections that need changing intoReplaceable's
instances (using the Peek operations in package NodeSearch), and then re-copying those sections back into the original page-Vector
after changing them - avoids the cost that would be incurred from repeatedly inserting and shifting a long list of nodes in a large HTML Page.
Therefore, this method is probably best avoided, as it is defeating the entire-purpose of aRelaceable
. This method will update the nodes at the location in the original-Vector
, which is fine, but if more than one update / change is needed, using this method over-and-over again will re-introduce the exact shifting that was supposed to be avoided by (and is the whole reason for...) usingReplaceable's
in the first place!
The following example should make this clear:
Example:
Vector<HTMLNode> page = HTMLPage.getPageTokens(new URL("http://some.url.com/"), false); Vector<SubSection> myTableRows = TagNodePeekInclusive.all(page, "tr"); TagNode OPEN_SPAN = HTMLTags.hasTag("SPAN", TC.OpeningTags); TagNode CLOSE_SPAN = HTMLTags.hasTag("SPAN", TC.ClosingTags); int counter = 1; for (SubSection tableRow : myTableRows) { // Retrieve the <TR> Tag & Give it a CSS-ID TagNode tr = tableRow.html.elementAt(0).asTagNode().setID("ROW" + counter++, null); // Put the newly created <TR ID=..> into the vector. It was the first-element in the SubSection tableRow.html.setElementAt(tr, 0); // Add a <SPAN>...</SPAN> surrounding the first line of text // NOTE: This assumes that tableRow[1] (second SubSection node) is a TextNode with text tableRow.html.insertElementAt(OPEN_SPAN, 1); tableRow.html.insertElementAt(CLOSE_SPAN, 3); } // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // This version DESTROYS THE BENEFIT of using TagNodePeekInclusive // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // // Here, if the original html-page was thousands of nodes long, every table-row // update will force thousands of nodes to be shifted to the right over-and-over // again! for (SubSection tableRow : myTableRows) tableRow.update(page); // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** // This builds a new Vector much more efficiently, avoiding costly node-shifting // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** page = ReplaceNodes.r(page, myTableRows, false).a;
- Parameters:
originalHTML
- The original page-Vector
where the nodes inthis
instance were retrieved- Returns:
- The change in the size of the
Vector
- Throws:
java.lang.IndexOutOfBoundsException
- IforiginalLocationStart()
ororiginalLocationEnd()
are not within the bounds of the input html-page.- See Also:
ReplaceNodes.r(Vector, Iterable, boolean)
-
setHTML
default Replaceable setHTML(java.util.Vector<HTMLNode> newHTML)
This method may be used for arbitrary replacements. An instance ofNodeIndex
(one of its sub-classes) only contains a singleHTMLNode
. To change that to a list, or to remove that node altogether, invoke this method, and a new instance ofReplaceable
will be automatically created, and returned.
This may be a little tricky at first, but the primary reason for using this method is that size-changes that would make a single-node (NodeIndex
instance) into a list (SubSection
instance), or vice-versa, would require building a different type ofReplaceable
instance. This method will automatically build that instance into aReplaceable
that retains its original location, but reflects its new contents and size.
Once again, the primary impetus for this method is using it with an in-place page update having multiple-replacements, vis-a-vis a call toReplaceNodes.r(Vector, Iterable, boolean)
.- Parameters:
newHTML
- The contents of'this'
replaceable will be assigned to the the html in this parameter.- Returns:
- a new replaceable whose location has not changed,
but whose contents are the contents of
newHTML
. - Code:
- Exact Method Body:
final int oldSize = this.originalSize(); final int newSize = newHTML.size(); final int sPos = this.originalLocationStart(); final int ePos = this.originalLocationEnd(); // SubSection ==> SubSection if ((oldSize > 1) && (newSize > 1)) return new SubSection(new DotPair(sPos, ePos - 1), newHTML); // NodeIndex ==> NodeIndex if ((oldSize == 1) && (newSize == 1)) return NodeIndex.newNodeIndex(sPos, newHTML.elementAt(0)); // Empty ==> Empty if ((oldSize == 0) && (newSize == 0)) return empty(sPos); return new ReplaceableAdapter(sPos, ePos, newHTML);
-
setHTML
default Replaceable setHTML(HTMLNode newHTML)
See the description insetHTML(Vector)
to understand when to usesetHTML
. This method is identical, but accepts a singleHTMLNode
instance, instead of an html list.- Parameters:
newHTML
- The contents of'this'
replaceable will be assigned to the the html contained bynewHTML
. (The returned instance will have the same location values)- Returns:
- a new replaceable whose location has not changed,
but whose contents are
newHTML
. - See Also:
setHTML(Vector)
- Code:
- Exact Method Body:
// NodeIndex ==> NodeIndex if (this.originalSize() == 1) return NodeIndex.newNodeIndex(this.originalLocationStart(), newHTML); Vector<HTMLNode> v = new Vector<>(); v.add(newHTML); return new ReplaceableAdapter (this.originalLocationStart(), this.originalLocationEnd(), v);
-
clearHTML
default Replaceable clearHTML()
Removes all HTML from thisReplaceable
, such that'scurrentNodes()
would return an empty HTML list.- Returns:
- a new replaceable whose original location has not changed, but whose contents are empty.
- See Also:
setHTML(Vector)
- Code:
- Exact Method Body:
if (currentSize() == 0) return Replaceable.empty(originalLocationStart()); return new ReplaceableAdapter (originalLocationStart(), originalLocationEnd(), new Vector<>());
-
create
static Replaceable create(DotPair location, java.util.Vector<HTMLNode> html)
Provides a mechanism for creating aSubSection
instance whosehtml
does not match the size of thelocation
where thathtml
is to be placed.- Parameters:
location
- The range in any HTML Page by which the newhtml
will be replaced.html
- The html that will ultimately be used to replace the current-html, on a web-page, at the specifiedlocation
.- Returns:
- An instance of a
Replaceable
, that is, in-effect, aSubSection
, but one whose location/bounds do not match the size of the new-html
.
NOTE: This method allows a user to bypass the exception-check that classSubSection
performs when building an instance of that class. - Code:
- Exact Method Body:
return new ReplaceableAdapter(location.start, location.end + 1, html);
-
create
static Replaceable create(int location, java.util.Vector<HTMLNode> html)
Creates a newReplaceable
instance whose original-location is just a single-node, but whose newhtml
may be an arbitrarily-sized htmlVector
.- Parameters:
location
- The node in any HTML Page which shall be replaced by'html'
html
- The html that will replace the node on an HTML page located at'location'
- Returns:
- An instance of a
Replaceable
that is, in effect, aSubSection
, but one whose location/bounds are not (necessarily) a single page-index.
NOTE: This method allows a user to bypass the requirement that aNodeIndex
occupy only a single-node. - Code:
- Exact Method Body:
return new ReplaceableAdapter(location, location + 1, html);
-
createInsertion
static Replaceable createInsertion(int location, java.util.Vector<HTMLNode> html)
Creates a newReplaceable
instance whose original-location had zero-length- Parameters:
location
- The location in any HTML Page into which the'html'
shall be insertedhtml
- The html that will be inserted into an HTML Page at index'location'
- Returns:
- An instance of a
Replaceable
- whose original-location had a zero-length - Code:
- Exact Method Body:
return new ReplaceableAdapter(location, location, html);
-
moveAndUpdate
default Replaceable moveAndUpdate(int sPos)
This method is mostly of internal-use, mainly byReplaceNodes.r(Vector, Iterable, boolean)
- Parameters:
sPos
- The new location in an html page-Vector
where the contents of thisReplaceable
are now located.- Returns:
- A new instance, whose html-contents are identical, but is located at
'sPos'
(and having an ending-location ofsPos + currentSize()
). - Code:
- Exact Method Body:
// IMPORTANT: This method is extremely un-important! It looks kind of unreadable. // All it is doing is REGISTERING the changes to his SubSection or NodeIndex // by building a new SubSection or new NodeIndex. // // PRIMARILY: Since the *WHOLE POINT* is to make all of the changes to an HTML Page, first, // before doing an update ... Having updated Replaceable's is mostly a waste. // Specifically, after the page has been updated, keeping the sub-parts of the // page would no longer be necessary! // // ReplaceNodes: This class offers the option to 'updateReplaceablesAfterBuild' in case // (for whatever reason) the user has decided another round of page updates is // needed. final int size = currentSize(); switch (size) { case 0: return Replaceable.empty(sPos); case 1: return NodeIndex.newNodeIndex(sPos, firstCurrentNode()); default: return new SubSection( // DotPair.end is inclusive, so subtract 1 new DotPair(sPos, sPos + size - 1), // The current HTML Vector currentNodes() ); }
-
empty
static Replaceable empty(int sPos)
Returns an emptyReplaceable
(an instance having 0HTMLNode's
) located atsPos
.
NoSuchElementException:
Attempting to retrieve nodes from the returned-instance will generate a JavaNoSuchElementException
.- Parameters:
sPos
- The location of this zero-elementReplaceable
- Returns:
- The new instance.
- Code:
- Exact Method Body:
return new ReplaceableAdapter(sPos, sPos, new Vector<>());
-
isSynthetic
default boolean isSynthetic()
Identifies whether or not'this'
instance is an anonymous class, that was built from the (internal)ReplaceableAdapter
.- Returns:
TRUE
if'this'
is neither an instance that inheritsNodeIndex
nor inheritsSubSection
. Such instances are built from an internalReplaceableAdapter
, and are produced by the methods:setHTML(Vector)
,setHTML(HTMLNode)
,clearHTML()
, andempty(int)
.- Code:
- Exact Method Body:
return false;
-
-