Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fixed items order in a JTree by some really ugly coding

  • Loading branch information...
commit df8c71147933eb42238cb794571a239d3c158eec 1 parent 350bee2
Acerbic authored
View
215 src/dloader/GUI.java
@@ -8,6 +8,7 @@
import java.util.Collection;
import java.util.Deque;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.LinkedList;
import javax.swing.border.BevelBorder;
@@ -46,28 +47,28 @@
private MyWorker newWorker;
- @SuppressWarnings("serial")
- class MyRenderer extends DefaultTreeCellRenderer {
-
- public Component getTreeCellRendererComponent(
- JTree tree,
- Object value,
- boolean sel,
- boolean expanded,
- boolean leaf,
- int row,
- boolean hasFocus) {
-
- super.getTreeCellRendererComponent(
- tree, value, sel,
- expanded, leaf, row,
- hasFocus);
- if (value instanceof DefaultMutableTreeNode)
- return this;
- return this;
- }
-
- }
+// @SuppressWarnings("serial")
+// class MyRenderer extends DefaultTreeCellRenderer {
+//
+// public Component getTreeCellRendererComponent(
+// JTree tree,
+// Object value,
+// boolean sel,
+// boolean expanded,
+// boolean leaf,
+// int row,
+// boolean hasFocus) {
+//
+// super.getTreeCellRendererComponent(
+// tree, value, sel,
+// expanded, leaf, row,
+// hasFocus);
+// if (value instanceof DefaultMutableTreeNode)
+// return this;
+// return this;
+// }
+//
+// }
public Thread getEventDispatchThread() {
return eventDispatchThread;
@@ -108,7 +109,7 @@ public GUI() throws HeadlessException {
{}
}
));
- tree.setCellRenderer(new MyRenderer());
+// tree.setCellRenderer(new MyRenderer());
tree.setBorder(new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
lblStatus = new JLabel("kkkkss");
@@ -239,11 +240,12 @@ public void init() {
}
private void initPrefetch() {
- lblStatus.setText("Prefetching");
- if (newWorker == null)
+ if (newWorker == null) {
+ lblStatus.setText("Prefetching");
newWorker = new MyWorker(rootPage, JobType.READCACHEPAGES);
- newWorker.execute();
- btnPrefetch.setEnabled(false);
+ newWorker.execute();
+ btnPrefetch.setEnabled(false);
+ }
}
private void finishPrefetch() {
@@ -254,11 +256,12 @@ private void finishPrefetch() {
}
private void initScan() {
- lblStatus.setText("Scanning");
- if (newWorker == null)
+ if (newWorker == null) {
+ lblStatus.setText("Scanning");
newWorker = new MyWorker(rootPage, JobType.UPDATEPAGES);
- newWorker.execute();
- btnFetch.setEnabled(false);
+ newWorker.execute();
+ btnFetch.setEnabled(false);
+ }
}
private void finishScan() {
@@ -269,7 +272,7 @@ private void finishScan() {
}
/**
- * Receiving message from SwingWorker
+ * Receiving message from MyWorker (SwingWorker)
* @param p - page node to update
* @param message - status info
* @param value - numeral info
@@ -291,85 +294,143 @@ else if (!p.getParent().childPages.contains(p))
}
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
- DefaultMutableTreeNode parent = (DefaultMutableTreeNode) model.getRoot();
- for (AbstractPage currentPage: pathToPage) {
- // check if this page exists in the tree
- DefaultMutableTreeNode child = null;
- boolean found = false;
- for (@SuppressWarnings("unchecked")
- Enumeration<DefaultMutableTreeNode> children = parent.children(); children.hasMoreElements();) {
- child = children.nextElement();
- if (currentPage.equals(pageOfNode(child))) {
- found = true;
- break;
- }
- }
- if (! found) {
+ DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) model.getRoot();
+ for (AbstractPage childPage: pathToPage) {
+ // check if this page exists in the parent
+ DefaultMutableTreeNode childNode = getNodeOfPage (parentNode, childPage);
+
+ if (childNode == null) {
// currentPage's node was not found in parent node
- //TODO: fix elements order in tree....
// add new item under this parent
- child = new DefaultMutableTreeNode();
- TreeNodePageWrapper childsUserObject = new TreeNodePageWrapper(currentPage, child);
- child.setUserObject(childsUserObject);
-
- parent.add(child);
+ childNode = new DefaultMutableTreeNode();
+ TreeNodePageWrapper childsUserObject = new TreeNodePageWrapper(childPage, childNode);
+ childNode.setUserObject(childsUserObject);
+ if (childPage.getParent() == null)
+ parentNode.add(childNode); // to the end
+ else {
+ int insertionIndex = findInsertionPoint(parentNode, childPage);
+
+ if (insertionIndex == -1)
+ parentNode.add(childNode); // to the end
+ else
+ parentNode.insert(childNode, insertionIndex);
+
+ }
int[] indices = new int[1];
- indices[0] = parent.getIndex(child);
+ indices[0] = parentNode.getIndex(childNode);
// new item's children if any (that way they maintain their order)
- for (AbstractPage subPage: currentPage.childPages) {
+ for (AbstractPage subPage: childPage.childPages) {
DefaultMutableTreeNode subChild = new DefaultMutableTreeNode();
subChild.setUserObject(new TreeNodePageWrapper(subPage, subChild));
}
- model.nodesWereInserted(parent, indices); //notification to repaint
+ model.nodesWereInserted(parentNode, indices); //notification to repaint
//expand only if not a Track
if (!(childsUserObject.page instanceof Track))
- tree.expandPath(new TreePath(parent.getPath()));
+ tree.expandPath(new TreePath(parentNode.getPath()));
}
- parent = child; // advance to search next element in our pathToPage
+ parentNode = childNode; // advance to search next element in our pathToPage
}
// after search is complete, parent points to a DefaultMutableTreeNode
// containing TreeNodePageWrapper containing original p (but now p is different)
- // Reading cache forces reset of page data (children refs), the node branch must be trimmed accordingly
+ // Reading cache/ downloading a page forces reset of page data (children refs),
+ // the node branch must be trimmed accordingly
if (message.equals("read from cache") || message.equals("read cache failed")
|| message.equals("cache reading failed, submitting download job")
|| message.equals("download finished") || message.equals("up to date")
|| message.equals("download failed")
)
- trimBranch(parent, model);
+ trimBranch(parentNode, model);
// pass message to the user object and refresh its visual if needed
- if (((TreeNodePageWrapper)parent.getUserObject()).update(message, value))
- model.nodeChanged(parent);
+ if (((TreeNodePageWrapper)parentNode.getUserObject()).update(message, value))
+ model.nodeChanged(parentNode);
}
+
+ private int findInsertionPoint(DefaultMutableTreeNode parentNode,
+ AbstractPage childPage) {
+ // time to find proper insertion position (assume nodes are ordered same way as pages so far with "skips" probably existing)
+ // p1 p2 p3 p4 p5 p6
+ // n1 n2 n3 n4
+ Iterator<AbstractPage> pageLooker = childPage.getParent().childPages.iterator();
+ @SuppressWarnings("unchecked")
+ Enumeration<DefaultMutableTreeNode> nodeLooker = parentNode.children();
+
+ // check "DoubleListMatcher.graphml" automaton diagram to understand the following
+ // *S*
+ // *A1*
+ while (nodeLooker.hasMoreElements()) { // *G* exit
+ DefaultMutableTreeNode currentNode = nodeLooker.nextElement();
+
+ // *A2*
+ if (!pageLooker.hasNext())
+ break; // *H* an ERROR has happened, since it is supposed to be and an impossible state.
+ AbstractPage currentPage = pageLooker.next();
+
+ // these are B-C-D123-B and B-C-E-B loops
+ b_loop:
+ while (! getPageOfNode(currentNode).equals(currentPage)) { // *A2*->*B* check AND *E*->*B* check
+ // *B*
+ if (childPage.equals(currentPage)) {
+ return parentNode.getIndex(currentNode); // *F*
+ }
+ // *C*
+ if (getPageOfNode(parentNode).childPages.contains(getPageOfNode(currentNode))) {
+ // *D2*
+ while (pageLooker.hasNext())
+ currentPage = pageLooker.next();
+ if (getPageOfNode(currentNode).equals(currentPage))
+ break b_loop; // -> *A*
+ // *D3*
+ if (childPage.equals(currentPage)) {
+ return parentNode.getIndex(currentNode); // *F*
+ }
+ return -1; //*H*
+ }
+ else // *E*
+ if (nodeLooker.hasMoreElements())
+ currentNode = nodeLooker.nextElement(); //skip one
+ // -> *B*
+ else
+ break; // *G* exit
+ }
+ }
+ // *G*
+ return -1;
+ }
/**
* Remove branch->children nodes don't correspond to branch->page->children pages
+ * and cancel their respective jobs running and scheduled
+ * O (n*n)
* @param branch - node branch to clean up
* @param model - reference model
*/
private void trimBranch(DefaultMutableTreeNode branch, DefaultTreeModel model) {
- AbstractPage branchPage = pageOfNode(branch);
+ AbstractPage branchPage = getPageOfNode(branch);
Collection<DefaultMutableTreeNode> removeList = new LinkedList<>();
for (@SuppressWarnings("unchecked")
Enumeration<DefaultMutableTreeNode> children = branch.children(); children.hasMoreElements();) {
DefaultMutableTreeNode childNode = children.nextElement();
- AbstractPage childPage = pageOfNode(childNode);
+ AbstractPage childPage = getPageOfNode(childNode);
if (! branchPage.childPages.contains(childPage)) {
// child's page is no more contained within its parent's page children collection
removeList.add(childNode); // can't remove on spot, it will fuck up the iteration
}
}
- for (DefaultMutableTreeNode element: removeList) {
+
+ for (DefaultMutableTreeNode element: removeList) {
+ // ordinary, this should never happen. if this is executing, it means that cache data was in conflict
+ // with updated net data.
model.removeNodeFromParent(element);
//since this page is no more of our concern, all jobs executing and pending are irrelevant CPU consumers
- newWorker.stopJobsForPage(pageOfNode(element));
+ newWorker.stopJobsForPage(getPageOfNode(element));
}
}
@@ -385,9 +446,31 @@ public void myWorkerDone (AbstractPage root, JobMaster.JobType jobType) {
}
}
- private AbstractPage pageOfNode(DefaultMutableTreeNode node) {
+ /**
+ * Shorthand to extract the page this node is displaying through user object
+ * @param node
+ * @return null if user object is not a AbstractPage wrapper
+ */
+ private AbstractPage getPageOfNode(DefaultMutableTreeNode node) {
if (node.getUserObject() instanceof TreeNodePageWrapper)
return ((TreeNodePageWrapper)node.getUserObject()).page;
else return null;
}
+
+ /**
+ * Search children nodes of a parentNode for a DefaultMutableTreeNode containing given AbstractPage.
+ * @param parentNode - parent of nodes to search among
+ * @param page - page to search
+ * @return found node or null if not found
+ */
+ private DefaultMutableTreeNode getNodeOfPage (DefaultMutableTreeNode parentNode, AbstractPage page) {
+ DefaultMutableTreeNode childNode = null;
+ for (@SuppressWarnings("unchecked")
+ Enumeration<DefaultMutableTreeNode> children = parentNode.children(); children.hasMoreElements();) {
+ childNode = children.nextElement();
+ if (page.equals(getPageOfNode(childNode)))
+ return childNode;
+ }
+ return null;
+ }
}
View
8 src/dloader/WebDownloader.java
@@ -21,13 +21,13 @@
*/
public class WebDownloader {
-/**
+ /**
* Downloads and saves a resource by given string address (URL) .
* @param from - resource URL string
- * @param to - file to save to.
- * @param reporter TODO
+ * @param to - file to save to.
+ * @param reporter - way to publish download progress.
* @return size of the downloaded file in bytes,
- * 0 if download was skipped (file exists and not zero length)
+ * 0 if download was skipped (file exists and not zero length)
* @throws IOException on stream problems or server has responded bad
*/
public static long fetchWebFile(String from, String to, ProgressReporter reporter) throws IOException {
View
628 src/dloader/gui/DoubleListMatcher.graphml
@@ -0,0 +1,628 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
+ <!--Created by yFiles for Java 2.9-->
+ <key for="graphml" id="d0" yfiles.type="resources"/>
+ <key for="port" id="d1" yfiles.type="portgraphics"/>
+ <key for="port" id="d2" yfiles.type="portgeometry"/>
+ <key for="port" id="d3" yfiles.type="portuserdata"/>
+ <key attr.name="url" attr.type="string" for="node" id="d4"/>
+ <key attr.name="description" attr.type="string" for="node" id="d5"/>
+ <key for="node" id="d6" yfiles.type="nodegraphics"/>
+ <key attr.name="Description" attr.type="string" for="graph" id="d7"/>
+ <key attr.name="url" attr.type="string" for="edge" id="d8"/>
+ <key attr.name="description" attr.type="string" for="edge" id="d9"/>
+ <key for="edge" id="d10" yfiles.type="edgegraphics"/>
+ <graph edgedefault="directed" id="G">
+ <data key="d7"/>
+ <node id="n0">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="89.0" width="91.0" x="1266.015625" y="283.0"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="56.705078125" x="17.1474609375" y="35.1494140625">get next n<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n1">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="83.0" x="1652.015625" y="286.5"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="34.357421875" x="24.3212890625" y="31.6494140625">n != p<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n2">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="83.0" x="1527.515625" y="466.0"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="33.40234375" modelName="custom" textColor="#000000" visible="true" width="44.705078125" x="19.1474609375" y="24.298828125">n != p
+nn == p<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n3">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="83.0" x="1424.015625" y="600.0"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="24.021484375" x="29.4892578125" y="31.6494140625">end<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n4">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="129.0" x="1421.515625" y="54.25"/>
+ <y:Fill color="#CCFFFF" color2="#CCFFFF" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="33.40234375" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="119.388671875" x="4.8056640625" y="24.298828125">ERROR.
+P was never matched</y:NodeLabel>
+ <y:Shape type="rectangle"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n5">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="83.0" x="1270.015625" y="472.0"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="14.0078125" x="34.49609375" y="31.6494140625">!n<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n6">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="83.0" x="1270.015625" y="43.0"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="33.40234375" modelName="custom" textColor="#000000" visible="true" width="37.36328125" x="22.818359375" y="24.298828125">start
+get nn<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n7">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="119.54216867469879" width="121.0" x="1819.515625" y="267.7289156626506"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="48.103515625" modelName="custom" textColor="#000000" visible="true" width="74.7109375" x="23.14453125" y="35.71932652484941">n != p
+nn != p
+Search n in p<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n8">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="83.0" x="1736.515625" y="505.0"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="36.689453125" x="23.1552734375" y="31.6494140625">next n
+<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n9">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="71.61417142857135" width="271.2025217183784" x="1279.3131032816216" y="-116.61417142857135"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="62.8046875" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="244.80859375" x="13.196963984189324" y="4.404741964285677">nn - new node to be inserted (childPage)
+n - node iterator (currentNode)
+p - pages iterator (currentPage)
+note: this prevents insertion of duplicates of n</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n10">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1235.515625" y="264.25"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="40.6943359375" x="-5.84716796875" y="-0.37646484375">A1</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n11">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1646.015625" y="246.5"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="24.009765625" x="2.4951171875" y="-0.37646484375">B</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n12">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1978.015625" y="286.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="25.6650390625" x="1.66748046875" y="-0.37646484375">C</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n13">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1499.515625" y="466.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="22.3251953125" x="3.33740234375" y="-0.37646484375">F</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n14">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1819.515625" y="538.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="24.009765625" x="2.4951171875" y="-0.37646484375">E</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n15">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1206.515625" y="472.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="27.3349609375" x="0.83251953125" y="-0.37646484375">G</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n16">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1499.515625" y="-7.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="25.6650390625" x="1.66748046875" y="-0.37646484375">H</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n17">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1537.015625" y="642.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="24.009765625" x="2.4951171875" y="-0.37646484375">X</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n18">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1235.515625" y="-7.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="24.009765625" x="2.4951171875" y="-0.37646484375">S</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n19">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="89.0" width="91.0" x="1459.515625" y="283.0"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="30.689453125" x="30.1552734375" y="35.1494140625">get p<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n20">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1430.515625" y="264.25"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="40.6943359375" x="-5.84716796875" y="-0.37646484375">A2</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n21">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="83.0" x="1902.0" y="97.5"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="48.103515625" modelName="custom" textColor="#000000" visible="true" width="70.71484375" x="6.142578125" y="16.9482421875">n != p
+nn != p
+n found later<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n22">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="82.0" width="83.0" x="1619.015625" y="115.25"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="34.357421875" x="24.3212890625" y="31.6494140625">n != p<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n23">
+ <data key="d6">
+ <y:ShapeNode>
+ <y:Geometry height="89.0" width="91.0" x="1781.0" y="8.5"/>
+ <y:Fill color="#FFCC00" transparent="false"/>
+ <y:BorderStyle color="#000000" type="line" width="1.0"/>
+ <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="custom" textColor="#000000" visible="true" width="30.689453125" x="30.1552734375" y="35.1494140625">get p<y:LabelModel>
+ <y:SmartNodeLabelModel distance="4.0"/>
+ </y:LabelModel>
+ <y:ModelParameter>
+ <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
+ </y:ModelParameter>
+ </y:NodeLabel>
+ <y:Shape type="ellipse"/>
+ </y:ShapeNode>
+ </data>
+ </node>
+ <node id="n24">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1962.03125" y="51.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="42.349609375" x="-6.6748046875" y="-0.37646484375">D1</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n25">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1865.515625" y="-31.5"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="42.349609375" x="-6.6748046875" y="-0.37646484375">D2</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <node id="n26">
+ <data key="d6">
+ <y:GenericNode configuration="com.yworks.flowchart.process">
+ <y:Geometry height="40.0" width="29.0" x="1706.015625" y="170.0"/>
+ <y:Fill hasColor="false" transparent="false"/>
+ <y:BorderStyle hasColor="false" type="line" width="1.0"/>
+ <y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="30" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="40.7529296875" modelName="internal" modelPosition="c" textColor="#0000FF" visible="true" width="42.349609375" x="-6.6748046875" y="-0.37646484375">D3</y:NodeLabel>
+ </y:GenericNode>
+ </data>
+ </node>
+ <edge id="e0" source="n19" target="n1">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="34.357421875" x="33.5712890625" y="2.0">n != p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e1" source="n2" target="n3">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#FF0000" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="135.068359375" x="-17.352304031599715" y="25.05523681640625">new insertion = index(n)</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e2" source="n1" target="n2">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="44.705078125" x="-30.306244151506007" y="46.5780029296875">nn == p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e3" source="n19" target="n4">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="58.029296875" x="-3.249302004843912" y="-82.86734008789062">no more p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e4" source="n0" target="n5">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="58.029296875" x="2.0" y="40.6494140625">no more n</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e5" source="n5" target="n3">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#FF0000" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="stail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="121.744140625" x="44.571624755859375" y="16.68302461698454">new insertion = at end</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e6" source="n6" target="n0">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#FF0000" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e7" source="n1" target="n7">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="41.03125" x="21.734375" y="2.0">nn != p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e8" source="n19" target="n0">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+ <y:Point x="1414.5" y="232.9140625"/>
+ </y:Path>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="head" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="38.03125" x="-133.8157271954467" y="-49.23892733273385">n == p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e9" source="n7" target="n21">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="33.40234375" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="112.732421875" x="23.449560968249898" y="-63.85767961984658">n found somewhere
+later</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e10" source="n7" target="n8">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="29.202728710373776" ty="-29.10080001831011"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="62.01953125" x="-18.527352444137478" y="53.40687395578408">n is a stray</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e11" source="n8" target="n1">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="34.357421875" x="-21.822346074084635" y="-80.30081176757812">n != p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e12" source="n8" target="n0">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+ <y:Point x="1503.515625" y="578.0"/>
+ </y:Path>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="38.03125" x="-299.56807430061735" y="-80.5926513671875">n == p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e13" source="n8" target="n5">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="1.734375" ty="21.1640625">
+ <y:Point x="1778.015625" y="746.6640625"/>
+ <y:Point x="1313.25" y="746.6640625"/>
+ </y:Path>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="head" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="58.029296875" x="-261.3974609375" y="138.962890625">no more n</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e14" source="n0" target="n19">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="33.35546875" x="34.572265625" y="2.0">has n</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e15" source="n21" target="n23">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#FF0000" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e16" source="n23" target="n23">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e17" source="n23" target="n22">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="34.357421875" x="-29.56775892502469" y="19.636594836796945">n != p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e18" source="n23" target="n4">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+ <y:Point x="1693.515625" y="64.5"/>
+ </y:Path>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e19" source="n22" target="n21">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="41.03125" x="79.5599365234375" y="-2.990347456520027">nn != p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e20" source="n22" target="n2">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+ <y:Point x="1576.5" y="267.5"/>
+ </y:Path>
+ <y:LineStyle color="#00FF00" type="dashed" width="1.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="shead" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="44.705078125" x="-74.62067322463145" y="18.263565063476562">nn == p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e21" source="n22" target="n1">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="tail" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="44.705078125" x="12.540512196339023" y="35.99781799316406">nn == p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ <edge id="e22" source="n23" target="n0">
+ <data key="d10">
+ <y:QuadCurveEdge straightness="0.1">
+ <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
+ <y:Point x="1678.5" y="-20.0"/>
+ <y:Point x="1472.5" y="-11.5"/>
+ </y:Path>
+ <y:LineStyle color="#00FF00" type="line" width="2.0"/>
+ <y:Arrows source="none" target="standard"/>
+ <y:EdgeLabel alignment="center" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.701171875" modelName="six_pos" modelPosition="shead" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" visible="true" width="38.03125" x="-93.97249739137419" y="-26.606128074027396">n == p</y:EdgeLabel>
+ </y:QuadCurveEdge>
+ </data>
+ </edge>
+ </graph>
+ <data key="d0">
+ <y:Resources/>
+ </data>
+</graphml>
View
1  src/dloader/gui/MyWorker.java
@@ -47,7 +47,6 @@ public void report(AbstractPage page, String type, long i) {
// try {
// Thread.sleep(300);
// } catch (InterruptedException e) {
-// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
View
3  src/dloader/gui/TreeNodePageWrapper.java
@@ -10,6 +10,7 @@
*
* It simultaneously wraps AbstractPage object, tracks download job progress by capturing PageJob's messages
* and provides "toString()" method to represent a page in JTree view.
+ * It does not change node tree model. All modifying of the tree is located at GUI.updateTree(...)
* @author Acerbic
*
*/
@@ -75,7 +76,7 @@ public boolean update(String type, long report) {
@Override
public String toString() {
- // TODO fix representation
+ // TODO
String header = "<html>";
String bottom = "</html>";
View
23 src/dloader/page/AbstractPage.java
@@ -11,7 +11,7 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
-import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
@@ -84,9 +84,11 @@
* It is important this variable is concurrent, since many different threads may iterate
* through children at any given moment.
* This list is empty on construction and filled with elements by loadFromCache() and updateFromNet() calls.
+ * Due to efficiency issues, elements should be added as .addAll(...) when possible
*/
public final
- Collection<AbstractPage> childPages = new ConcurrentLinkedQueue<>();
+// Queue<AbstractPage> childPages = new ConcurrentLinkedQueue<>();
+ List<AbstractPage> childPages = new CopyOnWriteArrayList<>();
/**
@@ -335,9 +337,10 @@ boolean loadFromCache () {
/**
* Downloads the page, parses it and creates child nodes.
+ * Note: children pages are dropped always. Their references are no longer part of the page tree.
+ * Note2: it is better to invoke updateFromNet(), as it preserves children pages if they are identical to the new data
* @throws ProblemsReadingDocumentException if any error
*/
- //FIXME: make this private (public for testing purposes)
public final
void downloadPage(ProgressReporter reporter) throws ProblemsReadingDocumentException {
Main.log(Level.FINE, String.format("Downloading %s from network...%n", url.toString()));
@@ -363,15 +366,16 @@ void downloadPage(ProgressReporter reporter) throws ProblemsReadingDocumentExcep
// discover info about children pages
childPages.clear();
Collection<Element> result = queryXPathList(getChildNodesXPath(), doc);
+ List<AbstractPage> newChildren = new LinkedList<>();
for (Element el: result)
try {
- childPages.add(parseChild(el));
+ newChildren.add(parseChild(el));
} catch (ProblemsReadingDocumentException e) {
Main.log(Level.WARNING, "unable to parse child data", e);
} // skip this child to next one
+
+ childPages.addAll(newChildren);
}
-// if (reporter != null)
-// reporter.report("download finished", 1);
Main.log(Level.FINE, String.format("...finished %s.%n", url.toString()));
}
@@ -439,11 +443,12 @@ private void mergeNewChildren (Collection<AbstractPage> oldChildren, Collection<
oldChild = current; break;
}
+ List<AbstractPage> resultChildren = new LinkedList<>();
if (oldChild != null) {
- childPages.add(oldChild);
- oldChildren.remove(oldChild); // very little optimization
+ resultChildren.add(oldChild);
} else
- childPages.add(newChild);
+ resultChildren.add(newChild);
+ childPages.addAll(resultChildren);
}
}
/**
View
3  src/dloader/page/Track.java
@@ -40,7 +40,7 @@
/**
* Set of custom properties read from page, saved to cache and
* resulting audio file metadata tags. Before iterating through properties,
- * they might be required to be update with "title" field from getTitle().
+ * they might be required to be updated with "title" field from getTitle().
*/
private Properties properties; // thread-safe class
@@ -95,7 +95,6 @@ public Track(String url, String saveTo, AbstractPage parent) throws IllegalArgum
public synchronized
boolean saveResult(ProgressReporter reporter) throws IOException {
Path p = Paths.get(getTrackFileName());
- // TODO: progress reporting in HERE
boolean wasDownloaded =
WebDownloader.fetchWebFile(getProperty("mediaLink"), p.toString(), reporter) != 0;
View
1  src/dloader/pagejob/UpdatePageJob.java
@@ -50,7 +50,6 @@ public void run() {
// try {
// Thread.sleep(3000);
// } catch (InterruptedException e) {
-// // TODO Auto-generated catch block
// e.printStackTrace();
// }
if (page.updateFromNet(this) || forceDownload) {
Please sign in to comment.
Something went wrong with that request. Please try again.