|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.openide.windows; import java.awt.BorderLayout; import java.awt.Component; import java.awt.DefaultKeyboardFocusManager; import java.awt.KeyboardFocusManager; import java.awt.event.ActionEvent; import java.beans.FeatureDescriptor; import java.util.*; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.JTextField; import junit.framework.*; import org.netbeans.junit.*; import org.openide.cookies.*; import org.openide.nodes.*; import org.openide.util.*; import org.openide.util.lookup.AbstractLookup; import org.openide.util.lookup.InstanceContent; /** * Check the behaviour of TopComponent's lookup. * @author Jaroslav Tulach, Jesse Glick */ public class TopComponentGetLookupTest extends NbTestCase { /** top component we work on */ protected TopComponent top; /** its lookup */ protected Lookup lookup; public TopComponentGetLookupTest(String testName) { super(testName); } public static void main(String[] args) { junit.textui.TestRunner.run(suite()); } public static Test suite() { return new NbTestSuite(TopComponentGetLookupTest.class); } /** Setup component with lookup. */ protected void setUp () { top = new TopComponent (); lookup = top.getLookup (); } protected boolean runInEQ () { return true; } /** Test to find nodes. */ private void doTestNodes(Node[] arr, Class c, int cnt) { if (arr != null) { top.setActivatedNodes(arr); } assertNotNull ("At least one node is registered", lookup.lookup (c)); Lookup.Result res = lookup.lookup (new Lookup.Template (c)); Collection coll = res.allItems(); assertEquals ("Two registered: " + coll, cnt, coll.size ()); } public void testNodes () { doTestNodes(new Node[] {new N("1"), new N("2")}, N.class, 2); doTestNodes(new Node[] {new N("1"), new N("2")}, FeatureDescriptor.class, 2); } private void doTestNodesWithChangesInLookup (Class c) { InstanceContent ic = new InstanceContent(); Node[] arr = new Node[] { new AbstractNode(Children.LEAF, new AbstractLookup(ic)), new AbstractNode(Children.LEAF, Lookup.EMPTY), }; arr[0].setName("cookie-container-node"); arr[1].setName("node-as-cookie"); //doTestNodes(arr, AbstractNode.class); doTestNodes (arr, c, 2); ic.add (arr[1]); /* Huh? There should be both [0] and [1], how can you say which one will be returned? assertEquals ("Now the [1] is in lookup of [0]", arr[1], lookup.lookup (c)); */ Collection all = lookup.lookup(new Lookup.Template(c)).allInstances(); assertEquals("Two nodes are in TC lookup", 2, all.size()); assertEquals("They are the ones we expect", new HashSet(Arrays.asList(arr)), new HashSet(all)); assertTrue("Lookup simple query gives one or the other", new HashSet(Arrays.asList(arr)).contains(lookup.lookup(c))); assertEquals("Have two lookup items", 2, lookup.lookup(new Lookup.Template(c)).allItems().size()); doTestNodes (null, c, 2); } public void testNodesWhenTheyAreNotInTheirLookup () { doTestNodesWithChangesInLookup(AbstractNode.class); } public void testNodesSuperclassesWhenTheyAreNotInTheirLookup () { doTestNodesWithChangesInLookup(FeatureDescriptor.class); } public void testFilterNodeProblems () { class CookieN extends AbstractNode implements Node.Cookie { public CookieN () { super (Children.LEAF); getCookieSet ().add (this); } } CookieN n = new CookieN (); FilterNode fn = new FilterNode (n); top.setActivatedNodes (new Node[] { fn }); assertTrue ("CookieN is in FilterNode lookup", n == fn.getLookup ().lookup (CookieN.class)); assertTrue ("CookieN is in TopComponent", n == lookup.lookup (CookieN.class)); assertEquals ("Just one node", 1, lookup.lookup (new Lookup.Template (Node.class)).allItems ().size ()); assertTrue ("Plain cookie found", n == lookup.lookup (Node.Cookie.class)); } /** Tests changes in cookies. */ public void testCookies () { N[] arr = { new N ("1"), new N ("2"), new N ("3") }; top.setActivatedNodes (arr); assertEquals ("Three nodes there", 3, top.getActivatedNodes ().length); L l = new L (); Lookup.Result res = lookup.lookup(new Lookup.Template(OpenCookie.class)); res.addLookupListener (l); assertEquals ("Empty now", res.allItems().size (), 0); arr[0].state (0x01); // enabled open cookie assertEquals ("One item", res.allItems ().size (), 1); l.check ("One change", 1); arr[2].state (0x02); // change of different cookie assertEquals ("Still one item", res.allItems ().size (), 1); l.check ("No change", 0); arr[2].state (0x03); // added also OpenCookie assertEquals ("Both items", res.allItems ().size (), 2); l.check ("One change again", 1); arr[0].state (0x00); assertEquals ("One still there", res.allItems ().size (), 1); assertEquals("The second object", lookup.lookup(OpenCookie.class), arr[2].getCookie(OpenCookie.class)); top.setActivatedNodes(new Node[0]); assertNull("No cookie now", lookup.lookup(OpenCookie.class)); } public void testNodesAreInTheLookupAndNothingIsFiredBeforeFirstQuery () { AbstractNode n1 = new AbstractNode(Children.LEAF, Lookup.EMPTY); top.setActivatedNodes(new Node[] { n1 }); assertEquals ("One node there", 1, top.getActivatedNodes ().length); assertEquals ("Is the right now", n1, top.getActivatedNodes ()[0]); Lookup.Result res = lookup.lookup(new Lookup.Template(Node.class)); L l = new L (); res.addLookupListener(l); l.check ("Nothing fired before first query", 0); res.allInstances (); l.check ("Nothing is fired on first query", 0); lookup.lookup(new Lookup.Template(Node.class)).allInstances(); l.check ("And additional query does not change anything either", 0); } public void testNodesAreThereEvenIfTheyAreNotContainedInTheirOwnLookup () { Lookup.Result res = lookup.lookup(new Lookup.Template(Node.class)); AbstractNode n1 = new AbstractNode(Children.LEAF, Lookup.EMPTY); InstanceContent content = new InstanceContent (); AbstractNode n2 = new AbstractNode(Children.LEAF, new AbstractLookup(content)); assertNull ("Not present in its lookup", n1.getLookup ().lookup (n1.getClass ())); assertNull ("Not present in its lookup", n2.getLookup ().lookup (n2.getClass ())); top.setActivatedNodes (new AbstractNode[] { n1 }); assertEquals ("But node is in the lookup", n1, lookup.lookup (n1.getClass ())); assertEquals ("One item there", 1, res.allInstances ().size ()); L listener = new L (); res.addLookupListener(listener); top.setActivatedNodes (new AbstractNode[] { n2 }); assertEquals ("One node there", 1, top.getActivatedNodes ().length); assertEquals ("n2", n2, top.getActivatedNodes ()[0]); //MK - here it changes twice.. because the setAtivatedNodes is trigger on inner TC, then lookup of MVTC contains old activated node.. // at this monent the merged lookup contains both items.. later it gets synchronized by setting the activated nodes on the MVTC as well.. // then it contains only the one correct node.. listener.check ("Node changed", 1); Collection addedByTCLookup = res.allInstances(); assertEquals ("One item still", 1, addedByTCLookup.size ()); content.add (n2); assertEquals ("After the n2.getLookup starts to return itself, there is no change", addedByTCLookup, res.allInstances ()); // this could be commented out if necessary: listener.check ("And nothing is fired", 0); content.remove (n2); assertEquals ("After the n2.getLookup stops to return itself, there is no change", addedByTCLookup, res.allInstances ()); // this could be commented out if necessary: listener.check ("And nothing is fired", 0); content.add (n1); // this could be commented out if necessary: listener.check ("And nothing is fired", 0); // Change from former behavior (#36336): we don't *want* n1 in res. Collection one = res.allInstances(); assertEquals("Really just the activated node", 1, one.size()); Iterator it = one.iterator(); assertEquals("It is the one added by the TC lookup", n2, it.next()); } public void testNoChangeWhenSomethingIsChangedOnNotActivatedNode () { doTestNoChangeWhenSomethingIsChangedOnNotActivatedNode (0); } public void testNoChangeWhenSomethingIsChangedOnNotActivatedNode2 () { doTestNoChangeWhenSomethingIsChangedOnNotActivatedNode (50); } private void doTestNoChangeWhenSomethingIsChangedOnNotActivatedNode (int initialSize) { Object obj = new OpenCookie() { public void open() {} }; Lookup.Result res = lookup.lookup(new Lookup.Template(OpenCookie.class)); Lookup.Result nodeRes = lookup.lookup (new Lookup.Template(Node.class)); InstanceContent ic = new InstanceContent (); CountingLookup cnt = new CountingLookup (ic); AbstractNode ac = new AbstractNode(Children.LEAF, cnt); for (int i = 0; i < initialSize; i++) { ic.add (new Integer (i)); } top.setActivatedNodes(new org.openide.nodes.Node[] { ac }); assertEquals ("One node there", 1, top.getActivatedNodes ().length); assertEquals ("It is the ac one", ac, top.getActivatedNodes ()[0]); ic.add (obj); L listener = new L (); res.allItems(); nodeRes.allItems (); res.addLookupListener (listener); Collection allListeners = cnt.listeners; assertEquals ("Has the cookie", 1, res.allItems ().size ()); listener.check ("No changes yet", 0); ic.remove (obj); assertEquals ("Does not have the cookie", 0, res.allItems ().size ()); listener.check ("One change", 1); top.setActivatedNodes (new N[0]); assertEquals("The nodes are empty", 0, top.getActivatedNodes ().length); listener.checkAtLeast ("There should be no change, but there is one now, improve if possible", checkAtLeastCount()); cnt.queries = 0; ic.add (obj); ic.add (ac); listener.check ("Removing the object or node from not active node does not send any event", 0); nodeRes.allItems (); listener.check ("Queriing for node does generate an event", 0); assertEquals ("No Queries to the not active node made", 0, cnt.queries); assertEquals ("No listeneners on cookies", allListeners, cnt.listeners); } public void testBug32470FilterNodeAndANodeImplementingACookie () { class NY extends AbstractNode implements SaveCookie { public NY () { super(Children.LEAF); getCookieSet ().add (this); } public void save () { } } Node ny = new NY (); Node node = new FilterNode (new FilterNode (ny, null, ny.getLookup ())); top.setActivatedNodes (new Node[] { node }); Lookup.Template nodeTemplate = new Lookup.Template(Node.class); Lookup.Template saveTemplate = new Lookup.Template(SaveCookie.class); java.util.Collection res; res = lookup.lookup (nodeTemplate).allInstances (); assertEquals("just one returned", res.size(), 1); assertEquals("node is node", node, res.iterator().next()); //MK - the above 2 tests should test the same.. // assertEquals ("FilterNode is the only node there", // Collections.singletonList(node), res // ); res = lookup.lookup (saveTemplate).allInstances (); assertEquals("just one returned", res.size(), 1); assertEquals("node is node", ny, res.iterator().next()); //MK - the above 2 tests should test the same.. // assertEquals ("SaveCookie is there only once", // Collections.singletonList(ny), res // ); res = lookup.lookup (nodeTemplate).allInstances (); assertEquals("just one returned", res.size(), 1); assertEquals("node is node", node, res.iterator().next()); //MK - the above 2 tests should test the same.. // assertEquals ("FilterNode is still the only node there", // Collections.singletonList(node), res // ); } public void testActionMapIsTakenFromComponentAndAlsoFromFocusedOne () { JTextField panel = new JTextField(); class Def extends DefaultKeyboardFocusManager { private Component c; public Def(Component c) { this.c = c; } public Component getFocusOwner() { return c; } } KeyboardFocusManager prev = KeyboardFocusManager.getCurrentKeyboardFocusManager(); try { KeyboardFocusManager.setCurrentKeyboardFocusManager(new Def (panel)); top.add(BorderLayout.CENTER, panel); class Act extends AbstractAction { public void actionPerformed(ActionEvent ev) { } } Act act1 = new Act (); Act act2 = new Act (); Act act3 = new Act (); top.getActionMap ().put ("globalRegistration", act1); top.getActionMap ().put ("doubleRegistration", act2); panel.getActionMap ().put ("doubleRegistration", act3); panel.getActionMap ().put ("focusedRegistration", act3); ActionMap map = (ActionMap)top.getLookup ().lookup (ActionMap.class); assertEquals ("actions registered directly on TC are found", act1, map.get ("globalRegistration")); assertEquals ("even if they are provided by focused component", act2, map.get ("doubleRegistration")); assertEquals ("Should be focused now", panel, KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() ); assertEquals ("actions are delegated to focus owner, if not present", act3, map.get ("focusedRegistration")); JTextField f = new JTextField (); f.getActionMap ().put ("focusedRegistration", act3); KeyboardFocusManager.setCurrentKeyboardFocusManager(new Def (f)); assertEquals ("f should be focused now", f, KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() ); assertEquals ("but as it is not in the right component, nothing is found", null, map.get ("focusedRegistration")); } finally { KeyboardFocusManager.setCurrentKeyboardFocusManager (prev); } } public void testChangingNodesDoesNotChangeActionMap () { N node = new N ("testChangingNodesDoesNotChangeActionMap"); node.state (0x00); top.setActivatedNodes(new Node[] { node }); Lookup.Result res = lookup.lookup (new Lookup.Template (ActionMap.class)); assertEquals ("One item there", 1, res.allInstances ().size ()); ActionMap map = (ActionMap)res.allInstances().toArray()[0]; L l = new L (); res.addLookupListener (l); node.state (0x01); assertEquals ("Map is still the same", map, res.allInstances().toArray()[0]); l.check ("No change in lookup", 0); top.setActivatedNodes (new Node[] { Node.EMPTY }); assertEquals ("Map remains the same", map, res.allInstances().toArray()[0]); l.checkAtLeast ("There should be no change, but alas there is one right now", checkAtLeastCount()); } public void testMapKeys45323 () { assertNotNull (top.getActionMap ().keys ()); } protected int checkAtLeastCount() { return 1; } /** * Check that even if a node has a different node in its lookup, a * query on Node.class will produce only the actual activated nodes. * Other queries may return the embedded node, but not duplicates. * @see "#36336" */ public void testForeignNodesInLookupIgnoredForNodeQuery() throws Exception { class CloseCookieNode extends AbstractNode implements CloseCookie { CloseCookieNode() { super(Children.LEAF); setName("n1"); } public boolean close() {return true;} } Node n1 = new CloseCookieNode(); Node n2 = new AbstractNode(Children.LEAF) { { setName("n2"); class ViewCookieNode extends AbstractNode implements ViewCookie { ViewCookieNode() { super(Children.LEAF); setName("n3"); } public void view() {} } getCookieSet().add(new ViewCookieNode()); getCookieSet().add(new OpenCookie() { public void open() {} }); } }; Node[] sel = new Node[] {n1, n2}; assertEquals("First node in selection has CloseCookie", 1, n1.getLookup().lookup(new Lookup.Template(CloseCookie.class)).allInstances().size()); assertEquals("Second node in selection has OpenCookie", 1, n2.getLookup().lookup(new Lookup.Template(OpenCookie.class)).allInstances().size()); assertEquals("Second node in selection has ViewCookie (actually a Node)", 1, n2.getLookup().lookup(new Lookup.Template(ViewCookie.class)).allInstances().size()); ViewCookie v = (ViewCookie)n2.getCookie(ViewCookie.class); assertNotNull(v); assertTrue(v instanceof Node); assertEquals("Second node in selection has two nodes in its own lookup", new HashSet(Arrays.asList(new Object[] {n2, v})), new HashSet(n2.getLookup().lookup(new Lookup.Template(Node.class)).allInstances())); assertEquals(2, n2.getLookup().lookup(new Lookup.Template(Node.class)).allInstances().size()); top.setActivatedNodes(sel); assertEquals("CloseCookie propagated from one member of node selection to TC lookup", 1, lookup.lookup(new Lookup.Template(CloseCookie.class)).allInstances().size()); assertEquals("OpenCookie propagated from one member of node selection to TC lookup", 1, lookup.lookup(new Lookup.Template(OpenCookie.class)).allInstances().size()); assertEquals("ViewCookie propagated from one member of node selection to TC lookup", 1, lookup.lookup(new Lookup.Template(ViewCookie.class)).allInstances().size()); assertEquals("But TC lookup query on Node gives only selection, not cookie node", new HashSet(Arrays.asList(sel)), new HashSet(lookup.lookup(new Lookup.Template(Node.class)).allInstances())); assertEquals(2, lookup.lookup(new Lookup.Template(Node.class)).allInstances().size()); assertEquals("TC lookup query on FeatureDescriptor gives all three however", 3, lookup.lookup(new Lookup.Template(FeatureDescriptor.class)).allInstances().size()); top.setActivatedNodes(new Node[] {n1}); assertEquals("After setting node selection to one node, TC lookup has only that node", Collections.singleton(n1), new HashSet(lookup.lookup(new Lookup.Template(Node.class)).allInstances())); assertEquals(1, lookup.lookup(new Lookup.Template(Node.class)).allInstances().size()); assertEquals("And the OpenCookie is gone", 0, lookup.lookup(new Lookup.Template(OpenCookie.class)).allInstances().size()); assertEquals("And the ViewCookie is gone", 0, lookup.lookup(new Lookup.Template(ViewCookie.class)).allInstances().size()); assertEquals("But the CloseCookie remains", 1, lookup.lookup(new Lookup.Template(CloseCookie.class)).allInstances().size()); } public void testAssociateLookupCanBecalledJustOnce () throws Exception { class TC extends TopComponent { public TC () { } public TC (Lookup l) { super (l); } public void asso (Lookup l) { associateLookup (l); } } TC tc = new TC (); assertNotNull ("There is default lookup", tc.getLookup ()); try { tc.asso (Lookup.EMPTY); fail ("Should throw an exception"); } catch (IllegalStateException ex) { // ok, should be thrown } tc = new TC (Lookup.EMPTY); assertEquals ("Should return the provided lookup", Lookup.EMPTY, tc.getLookup ()); try { tc.asso (Lookup.EMPTY); fail ("Should throw an exception - second association not possible"); } catch (IllegalStateException ex) { // ok, should be thrown } tc = new TC (); tc.asso (Lookup.EMPTY); assertEquals ("First association was successful", Lookup.EMPTY, tc.getLookup ()); try { tc.asso (new TC ().getLookup ()); fail ("Should throw an exception - second association not possible"); } catch (IllegalStateException ex) { // ok, should be thrown } } /** Listener to count number of changes. */ private static final class L extends Object implements LookupListener { private int cnt; /** A change in lookup occured. * @param ev event describing the change */ public void resultChanged(LookupEvent ev) { cnt++; } /** Checks at least given number of changes. */ public void checkAtLeast (String text, int num) { if (cnt < num) { fail (text + " expected at least " + num + " but was " + cnt); } cnt = 0; } /** Checks number of modifications. */ public void check (String text, int num) { assertEquals (text, num, cnt); cnt = 0; } } /** Overides some methods so it is not necessary to use the data object. */ protected static final class N extends AbstractNode { private Node.Cookie[] cookies = { new OpenCookie() { public void open() {} }, new EditCookie() { public void edit() {} }, new SaveCookie() { public void save() {} }, new CloseCookie() { public boolean close() { return true; } }, }; private int s; public N (String name) { super(Children.LEAF); setName (name); } public void state (int s) { this.s = s; fireCookieChange (); } public Node.Cookie getCookie(Class c) { int mask = 0x01; for (int i = 0; i < cookies.length; i++) { if ((s & mask) != 0 && c.isInstance(cookies[i])) { return cookies[i]; } mask = mask << 1; } return null; } } private static final class CountingLookup extends Lookup { private Lookup delegate; public List listeners = new ArrayList(); public int queries; public CountingLookup(InstanceContent ic) { delegate = new AbstractLookup (ic); } public Object lookup(Class clazz) { return delegate.lookup (clazz); } public Lookup.Result lookup(Lookup.Template template) { if ( !Node.Cookie.class.isAssignableFrom(template.getType()) && !Node.class.isAssignableFrom(template.getType()) ) { return delegate.lookup (template); } final Lookup.Result d = delegate.lookup (template); class Wrap extends Lookup.Result { public void addLookupListener(LookupListener l) { listeners.add (l); d.addLookupListener (l); } public void removeLookupListener(LookupListener l) { listeners.remove (l); d.removeLookupListener (l); } public Collection allInstances() { queries++; return d.allInstances (); } public Collection allItems() { queries++; return d.allItems (); } public Set allClasses() { queries++; return d.allClasses (); } } return new Wrap (); } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.