57 import java.util.ArrayList;
58 import java.util.Arrays;
59 import java.util.Comparator;
60 import java.util.logging.Logger;
61
62 /**
63 * This is the data model bridge between JT Harness core and the GUI.
64 */// NOTE: if you are going to request the worker lock and the htLock, you
65 // MUST do it in that order. Be mindful of holding the htLock and
66 // calling a synchronized method, that is illegal and you must
67 // release the htLock before making the method call.
68 class TestTreeModel implements TreeModel, TestResultTable.TreeObserver {
69
70 TestTreeModel() {
71 }
72
73 TestTreeModel(Parameters p, FilterSelectionHandler filterHandler, UIFactory uif) {
74 this.filterHandler = filterHandler;
75 this.uif = uif;
76
77 cache = new Hashtable();
78 cacheQueue = new LinkedList();
79 suspendedQueue = new LinkedList();
80
81 cacheWorker = new CacheWorker();
82 cacheWorker.setPriority(Thread.MIN_PRIORITY + 1);
83 cacheWorker.start();
84
85 setParameters(p);
86
87 watcher = new FilterWatcher();
88 filterHandler.addObserver(watcher);
89 lastFilter = filterHandler.getActiveFilter();
90 }
91
92 synchronized void dispose() {
93 disposed = true;
94
95 if (trt != null) {
96 trt.removeObserver(this);
97 trt.dispose();
98 trt = null;
99 }
482 processInsert0(path, tr);
483 }
484 }
485
486 private void processInsert0(TT_BasicNode[] path, TestResult tr) {
487 TT_TestNode newNode = new TT_TestNode(path[path.length - 1], tr);
488 //int pos = path[path.length - 1].addTest(newNode, sortComparator);
489 TreeModelEvent tme = path[path.length - 1].addTest(newNode, sortComparator);
490 if (tme == null) return;
491
492 for (int i = 0; i < treeModelListeners.length; i++) {
493 ((TreeModelListener) treeModelListeners[i]).treeNodesInserted(tme);
494 }
495
496 }
497
498 TreePath resolveUrl(String path) {
499 if (path == null || path.length() == 0 || root == null) {
500 return null;
501 }
502 ArrayList<TT_TreeNode> al = new ArrayList();
503 al.add(root);
504 TT_BasicNode spot = root;
505
506 StringBuffer sb = new StringBuffer(path);
507
508 while (sb.length() > 0) {
509 int slash = sb.indexOf("/");
510 String current = null;
511 if (slash < 0) {
512 current = sb.toString();
513 sb.setLength(0);
514 } else {
515 current = sb.substring(0, slash);
516 sb = sb.delete(0, slash+1);
517 }
518
519 TT_TreeNode node = spot.findByName(current);
520
521 if (node == null) {
522 return null;
633 }
634
635 return transPath;
636 }
637
638 String[] pathsToStrings(TreePath[] paths) {
639 if (paths == null || paths.length == 0 ||
640 !(getRoot() instanceof TT_BasicNode))
641 return null;
642
643 String[] result = new String[paths.length];
644 for (int i = 0; i < paths.length; i++) {
645 TT_TreeNode tn = (TT_TreeNode)(paths[i].getLastPathComponent());
646 result[i] = tn.getLongPath();
647 }
648
649 return result;
650 }
651
652 TreePath[] urlsToPaths(String[] urls) {
653 ArrayList<TreePath> result = new ArrayList();
654
655 for (int i = 0; i < urls.length; i++) {
656 TreePath thisOne = urlToPath(urls[i]);
657 if (thisOne == null)
658 continue; // skipped for some reason
659 else
660 result.add(thisOne);
661 }
662
663 TreePath[] res = new TreePath[result.size()];
664 result.toArray(res);
665 return res;
666 }
667
668 TreePath urlToPath(String url) {
669 if (url == null)
670 return null;
671
672 String[] urlPath = StringArray.splitList(url, "/");
673 TT_TreeNode[] transPath = new TT_TreeNode[urlPath.length+1];
800 // see note in setParameters()
801 //if (params == null)
802 // throw IllegalStateException();
803
804 // assumptions:
805 // - a model must have a non-null TRT
806 if (isCompatible(trt, newTrt)) {
807 swapTables(newTrt);
808 } else {
809 if (trt != null) {
810 trt.removeObserver(this);
811 }
812 trt = newTrt;
813 trt.addObserver(this);
814 }
815
816 root = new TT_BasicNode(null, (TRT_TreeNode) (trt.getRoot()),
817 (trt.getTestFinder() == null ? null : trt.getTestFinder().getComparator()));
818
819 // prime relevant nodes with root and first level
820 relevantNodes = Collections.synchronizedSet(new HashSet());
821 relevantTests = Collections.synchronizedSet(new HashSet());
822
823 addRelevantNode((TT_TreeNode) getRoot());
824 TT_BasicNode tn = ((TT_BasicNode) getRoot());
825 for (int i = 0; i < ((TT_BasicNode) getRoot()).getChildCount(); i++) {
826 addRelevantNode((TT_TreeNode) (tn.getChildAt(i)));
827 }
828 notifyFullStructure();
829
830 if (debug > 0) {
831 Debug.println("TTM - Model watching " + trt);
832 if (trt.getWorkDir() != null) {
833 Debug.println(" -> Workdir=" + trt.getWorkDir());
834 Debug.println(" -> Workdir path=" + trt.getWorkDir().getPath());
835 Debug.println(" -> root = " + trt.getRoot());
836 }
837 }
838 }
839
840 static boolean isCompatible(TestResultTable t1, TestResultTable t2) {
841 // assumptions:
985
986 // wake up the worker
987 synchronized (cacheWorker) {
988 cacheWorker.notify();
989 }
990 }
991
992 /**
993 * Invalidate all collected node information.
994 * This is likely used when the internal contents of the parameters have
995 * changed. If the cache is not invalidated at certain points, rendering
996 * of the tree may be incorrect.
997 */
998 void invalidateNodeInfo() {
999 synchronized (htLock) {
1000 Enumeration e = cache.keys();
1001 while (e.hasMoreElements()) {
1002 (cache.get(e.nextElement())).invalidate();
1003 } // while
1004
1005 cache = new Hashtable();
1006 cacheQueue = new LinkedList();
1007 suspendedQueue = new LinkedList();
1008 }
1009
1010 // reprocess any needed nodes
1011 Iterator it = relevantNodes.iterator();
1012 while (it.hasNext()) {
1013 TT_TreeNode tn = (TT_TreeNode) it.next();
1014 if (tn instanceof TT_BasicNode) {
1015 getNodeInfo(((TT_BasicNode) tn).getTableNode(), false);
1016 }
1017 } // while
1018 }
1019
1020 /**
1021 * Invalidate any collected data about the given node.
1022 * This operation includes stopping any thread scanning for info and
1023 * removing the entry from the cache.
1024 *
1025 * @param node The node to invalidate in the cache. Must not be null.
1026 * @deprecated The cache will be smart enough to not need this.
1027 */
|
57 import java.util.ArrayList;
58 import java.util.Arrays;
59 import java.util.Comparator;
60 import java.util.logging.Logger;
61
62 /**
63 * This is the data model bridge between JT Harness core and the GUI.
64 */// NOTE: if you are going to request the worker lock and the htLock, you
65 // MUST do it in that order. Be mindful of holding the htLock and
66 // calling a synchronized method, that is illegal and you must
67 // release the htLock before making the method call.
68 class TestTreeModel implements TreeModel, TestResultTable.TreeObserver {
69
70 TestTreeModel() {
71 }
72
73 TestTreeModel(Parameters p, FilterSelectionHandler filterHandler, UIFactory uif) {
74 this.filterHandler = filterHandler;
75 this.uif = uif;
76
77 cache = new Hashtable<>();
78 cacheQueue = new LinkedList<>();
79 suspendedQueue = new LinkedList<>();
80
81 cacheWorker = new CacheWorker();
82 cacheWorker.setPriority(Thread.MIN_PRIORITY + 1);
83 cacheWorker.start();
84
85 setParameters(p);
86
87 watcher = new FilterWatcher();
88 filterHandler.addObserver(watcher);
89 lastFilter = filterHandler.getActiveFilter();
90 }
91
92 synchronized void dispose() {
93 disposed = true;
94
95 if (trt != null) {
96 trt.removeObserver(this);
97 trt.dispose();
98 trt = null;
99 }
482 processInsert0(path, tr);
483 }
484 }
485
486 private void processInsert0(TT_BasicNode[] path, TestResult tr) {
487 TT_TestNode newNode = new TT_TestNode(path[path.length - 1], tr);
488 //int pos = path[path.length - 1].addTest(newNode, sortComparator);
489 TreeModelEvent tme = path[path.length - 1].addTest(newNode, sortComparator);
490 if (tme == null) return;
491
492 for (int i = 0; i < treeModelListeners.length; i++) {
493 ((TreeModelListener) treeModelListeners[i]).treeNodesInserted(tme);
494 }
495
496 }
497
498 TreePath resolveUrl(String path) {
499 if (path == null || path.length() == 0 || root == null) {
500 return null;
501 }
502 ArrayList<TT_TreeNode> al = new ArrayList<>();
503 al.add(root);
504 TT_BasicNode spot = root;
505
506 StringBuffer sb = new StringBuffer(path);
507
508 while (sb.length() > 0) {
509 int slash = sb.indexOf("/");
510 String current = null;
511 if (slash < 0) {
512 current = sb.toString();
513 sb.setLength(0);
514 } else {
515 current = sb.substring(0, slash);
516 sb = sb.delete(0, slash+1);
517 }
518
519 TT_TreeNode node = spot.findByName(current);
520
521 if (node == null) {
522 return null;
633 }
634
635 return transPath;
636 }
637
638 String[] pathsToStrings(TreePath[] paths) {
639 if (paths == null || paths.length == 0 ||
640 !(getRoot() instanceof TT_BasicNode))
641 return null;
642
643 String[] result = new String[paths.length];
644 for (int i = 0; i < paths.length; i++) {
645 TT_TreeNode tn = (TT_TreeNode)(paths[i].getLastPathComponent());
646 result[i] = tn.getLongPath();
647 }
648
649 return result;
650 }
651
652 TreePath[] urlsToPaths(String[] urls) {
653 ArrayList<TreePath> result = new ArrayList<>();
654
655 for (int i = 0; i < urls.length; i++) {
656 TreePath thisOne = urlToPath(urls[i]);
657 if (thisOne == null)
658 continue; // skipped for some reason
659 else
660 result.add(thisOne);
661 }
662
663 TreePath[] res = new TreePath[result.size()];
664 result.toArray(res);
665 return res;
666 }
667
668 TreePath urlToPath(String url) {
669 if (url == null)
670 return null;
671
672 String[] urlPath = StringArray.splitList(url, "/");
673 TT_TreeNode[] transPath = new TT_TreeNode[urlPath.length+1];
800 // see note in setParameters()
801 //if (params == null)
802 // throw IllegalStateException();
803
804 // assumptions:
805 // - a model must have a non-null TRT
806 if (isCompatible(trt, newTrt)) {
807 swapTables(newTrt);
808 } else {
809 if (trt != null) {
810 trt.removeObserver(this);
811 }
812 trt = newTrt;
813 trt.addObserver(this);
814 }
815
816 root = new TT_BasicNode(null, (TRT_TreeNode) (trt.getRoot()),
817 (trt.getTestFinder() == null ? null : trt.getTestFinder().getComparator()));
818
819 // prime relevant nodes with root and first level
820 relevantNodes = Collections.synchronizedSet(new HashSet<TT_TreeNode>());
821 relevantTests = Collections.synchronizedSet(new HashSet<TestResult>());
822
823 addRelevantNode((TT_TreeNode) getRoot());
824 TT_BasicNode tn = ((TT_BasicNode) getRoot());
825 for (int i = 0; i < ((TT_BasicNode) getRoot()).getChildCount(); i++) {
826 addRelevantNode((TT_TreeNode) (tn.getChildAt(i)));
827 }
828 notifyFullStructure();
829
830 if (debug > 0) {
831 Debug.println("TTM - Model watching " + trt);
832 if (trt.getWorkDir() != null) {
833 Debug.println(" -> Workdir=" + trt.getWorkDir());
834 Debug.println(" -> Workdir path=" + trt.getWorkDir().getPath());
835 Debug.println(" -> root = " + trt.getRoot());
836 }
837 }
838 }
839
840 static boolean isCompatible(TestResultTable t1, TestResultTable t2) {
841 // assumptions:
985
986 // wake up the worker
987 synchronized (cacheWorker) {
988 cacheWorker.notify();
989 }
990 }
991
992 /**
993 * Invalidate all collected node information.
994 * This is likely used when the internal contents of the parameters have
995 * changed. If the cache is not invalidated at certain points, rendering
996 * of the tree may be incorrect.
997 */
998 void invalidateNodeInfo() {
999 synchronized (htLock) {
1000 Enumeration e = cache.keys();
1001 while (e.hasMoreElements()) {
1002 (cache.get(e.nextElement())).invalidate();
1003 } // while
1004
1005 cache = new Hashtable<>();
1006 cacheQueue = new LinkedList<>();
1007 suspendedQueue = new LinkedList<>();
1008 }
1009
1010 // reprocess any needed nodes
1011 Iterator it = relevantNodes.iterator();
1012 while (it.hasNext()) {
1013 TT_TreeNode tn = (TT_TreeNode) it.next();
1014 if (tn instanceof TT_BasicNode) {
1015 getNodeInfo(((TT_BasicNode) tn).getTableNode(), false);
1016 }
1017 } // while
1018 }
1019
1020 /**
1021 * Invalidate any collected data about the given node.
1022 * This operation includes stopping any thread scanning for info and
1023 * removing the entry from the cache.
1024 *
1025 * @param node The node to invalidate in the cache. Must not be null.
1026 * @deprecated The cache will be smart enough to not need this.
1027 */
|