| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.openide.windows; |
| |
| import java.awt.EventQueue; |
| import java.awt.event.ActionEvent; |
| import java.beans.FeatureDescriptor; |
| import java.lang.ref.Reference; |
| import java.lang.ref.WeakReference; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import javax.swing.AbstractAction; |
| import javax.swing.ActionMap; |
| import org.netbeans.junit.NbTestCase; |
| import org.netbeans.modules.openide.windows.GlobalActionContextImpl; |
| import org.openide.nodes.AbstractNode; |
| import org.openide.nodes.Children; |
| import org.openide.nodes.Node; |
| import org.openide.util.Lookup; |
| import org.openide.util.Lookup.Result; |
| import org.openide.util.lookup.AbstractLookup; |
| import org.openide.util.lookup.InstanceContent; |
| |
| /** Tests behaviour of GlobalContextProviderImpl |
| * and its cooperation with activated and current nodes. |
| * |
| * @author Jaroslav Tulach |
| */ |
| public class GlobalContextImplTest extends NbTestCase |
| implements org.openide.util.LookupListener { |
| private static Object KEY = new Object(); |
| |
| private javax.swing.Action sampleAction = new AbstractActionImpl (); |
| private TopComponent tc; |
| private Lookup lookup; |
| private Lookup.Result result; |
| private int cnt; |
| |
| |
| public GlobalContextImplTest(java.lang.String testName) { |
| super(testName); |
| } |
| |
| @Override |
| protected int timeOut() { |
| return 15000; |
| } |
| |
| @Override |
| protected void setUp () throws Exception { |
| tc = new TopComponent (); |
| tc.getActionMap ().put (KEY, sampleAction); |
| tc.requestActive(); |
| |
| |
| Lookup global = Lookup.getDefault(); |
| |
| Object p = global.lookup (org.openide.util.ContextGlobalProvider.class); |
| assertNotNull ("There is one", p); |
| assertEquals ("Action context provider is our as well", org.netbeans.modules.openide.windows.GlobalActionContextImpl.class, p.getClass ()); |
| |
| |
| lookup = org.openide.util.Utilities.actionsGlobalContext(); |
| result = lookup.lookup (new Lookup.Template<Node> (Node.class)); |
| result.addLookupListener (this); |
| result.allItems(); |
| } |
| |
| private void assertActionMap () { |
| ActionMap map = lookup.lookup(ActionMap.class); |
| assertNotNull ("Map has to be there", map); |
| |
| javax.swing.Action action = map.get (KEY); |
| assertEquals ("It is really our action", sampleAction, action); |
| } |
| |
| |
| public void testCurrentNodes () throws Exception { |
| tc.setActivatedNodes(new Node[] {Node.EMPTY}); |
| |
| assertEquals ("This fires change", 1, cnt); |
| |
| assertEquals ("One item in result", 1, result.allItems ().size ()); |
| Lookup.Item item = (Lookup.Item)result.allItems ().iterator ().next (); |
| assertEquals ("Item should return Node.EMPTY", Node.EMPTY, item.getInstance()); |
| assertActionMap (); |
| |
| tc.setActivatedNodes (null); |
| assertEquals ("One change", 2, cnt); |
| |
| assertEquals ("One empty item in result", 1, result.allItems ().size ()); |
| item = (Lookup.Item)result.allItems ().iterator ().next (); |
| assertEquals ("Item should return null", null, item.getInstance()); |
| assertEquals ("Name is null", "none", item.getId ()); |
| assertActionMap (); |
| |
| Result<MyNode> subclass = lookup.lookup (new Lookup.Template<MyNode> (MyNode.class)); |
| assertTrue("No items are returned", subclass.allItems().isEmpty()); |
| |
| Result<FeatureDescriptor> superclass = lookup.lookup (new Lookup.Template<FeatureDescriptor>(FeatureDescriptor.class)); |
| assertEquals("One item is returned", 1, superclass.allItems().size()); |
| item = (Lookup.Item)superclass.allItems ().iterator ().next (); |
| assertEquals ("Item should return null", null, item.getInstance()); |
| |
| tc.setActivatedNodes (new Node[0]); |
| assertEquals ("No change", 3, cnt); |
| |
| assertEquals ("No items in lookup", 0, result.allItems ().size ()); |
| assertActionMap (); |
| } |
| |
| public void testRequestVisibleBlinksTheActionMapForAWhile () throws Exception { |
| doRequestVisibleBlinksTheActionMapForAWhile(new TopComponent(), true,false); |
| } |
| |
| public void testSetParentMapBlinks () throws Exception { |
| doRequestVisibleBlinksTheActionMapForAWhile(new TopComponent(), false,false); |
| } |
| |
| public void testSetParentMapBlinksRecursive () throws Exception { |
| doRequestVisibleBlinksTheActionMapForAWhile(new TopComponent(), false, true); |
| } |
| |
| private void doRequestVisibleBlinksTheActionMapForAWhile(TopComponent my, boolean requestVisible, final boolean recursive) throws Exception { |
| final org.openide.nodes.Node n = new org.openide.nodes.AbstractNode (org.openide.nodes.Children.LEAF); |
| tc.setActivatedNodes(new Node[] { n }); |
| |
| assertActionMap (); |
| |
| class L implements org.openide.util.LookupListener { |
| Lookup.Result<ActionMap> res = lookup.lookup (new Lookup.Template<ActionMap> (ActionMap.class)); |
| ArrayList<ActionMap> maps = new ArrayList<ActionMap> (); |
| int cnt; |
| |
| public void resultChanged (org.openide.util.LookupEvent ev) { |
| assertTrue("Changes are comming from AWT thread only", EventQueue.isDispatchThread()); |
| assertEquals ("Still only one", 1, res.allItems ().size ()); |
| Lookup.Item<ActionMap> i = res.allItems ().iterator ().next (); |
| assertNotNull (i); |
| |
| maps.add (i.getInstance ()); |
| |
| assertNode (); |
| |
| if (recursive && cnt++ == 0) { |
| GlobalActionContextImpl.blickActionMap(new ActionMap()); |
| } |
| } |
| |
| public void assertNode () { |
| assertEquals ("The node is available", n, lookup.lookup (Node.class)); |
| } |
| } |
| L myListener = new L (); |
| assertEquals ("One action map", 1, myListener.res.allItems ().size ()); |
| myListener.assertNode (); |
| |
| ActionMap m1, m2; |
| myListener.res.addLookupListener (myListener); |
| try { |
| if (requestVisible) { |
| my.requestVisible (); |
| } else { |
| my.getActionMap().setParent(new ActionMap()); |
| } |
| waitEQ(); |
| if (recursive) { |
| return; |
| } |
| |
| if (myListener.maps.size () != 2) { |
| fail ("Expected two changes in the ActionMaps: " + myListener.maps); |
| } |
| |
| myListener.assertNode (); |
| |
| m1 = myListener.maps.get(0); |
| m2 = myListener.maps.get(1); |
| |
| assertNull ("Our action is not in first map", m1.get (KEY)); |
| assertEquals ("Our action is in second map", sampleAction, m2.get (KEY)); |
| |
| assertActionMap (); |
| } finally { |
| myListener.res.removeLookupListener(myListener); |
| } |
| |
| my.close(); |
| |
| // new TopComponent ().open(); |
| |
| Reference<Object> ref = new WeakReference<Object>(my); |
| my = null; |
| m1 = null; |
| m2 = null; |
| myListener.maps.clear(); |
| |
| //this.tc = null; |
| //this.lookup = null; |
| //this.result = null; |
| //myListener.res = null; |
| //myListener = null; |
| //this.sampleAction = null; |
| |
| assertGC("Can be GCed", ref); |
| } |
| |
| private static class OwnTopComponent extends TopComponent { |
| public OwnTopComponent() { |
| getActionMap().put("ahoj", new OwnAction()); |
| } |
| |
| class OwnAction extends AbstractAction { |
| |
| public void actionPerformed(ActionEvent e) { |
| OwnTopComponent.this.open(); |
| } |
| |
| } |
| } |
| |
| public void testRequestVisibleBlinksTheActionMapForAWhileWithOwnComponentAndAction() throws Exception { |
| doRequestVisibleBlinksTheActionMapForAWhile(new OwnTopComponent(), true,false); |
| } |
| |
| public void testActionMapSetParentWithOwnComponentAndAction() throws Exception { |
| doRequestVisibleBlinksTheActionMapForAWhile(new OwnTopComponent(), false,false); |
| } |
| |
| public void testComponentChangeActionMapIsPropagatedToGlobalLookup() throws Exception { |
| assertEquals("test1", 0, cnt); |
| |
| |
| InstanceContent ic = new InstanceContent(); |
| AbstractLookup al = new AbstractLookup(ic); |
| tc = new TopComponent (al); |
| |
| assertEquals("test2", 0, cnt); |
| |
| |
| ActionMap myMap = new ActionMap(); |
| myMap.put (KEY, sampleAction); |
| assertEquals("test3", 0, cnt); |
| |
| tc.requestActive(); |
| |
| assertEquals("test4", 1, cnt); |
| |
| result = lookup.lookup (new Lookup.Template<ActionMap> (ActionMap.class)); |
| result.addLookupListener (this); |
| result.allItems(); |
| |
| assertEquals("test5", 1, cnt); |
| |
| ic.set(Collections.singleton(new ActionMap()), null); |
| |
| assertEquals("One change in ActiomMap delivered", 2, cnt); |
| } |
| |
| |
| public void resultChanged(org.openide.util.LookupEvent ev) { |
| cnt++; |
| } |
| |
| private void waitEQ() throws Exception { |
| EventQueue.invokeAndWait(new Runnable() { |
| public void run() { |
| } |
| }); |
| } |
| |
| private static class AbstractActionImpl extends AbstractAction { |
| |
| private AbstractActionImpl() { |
| } |
| |
| public void actionPerformed(java.awt.event.ActionEvent ev) { |
| } |
| } |
| |
| private static final class MyNode extends AbstractNode { |
| public MyNode() { |
| super(Children.LEAF); |
| } |
| } |
| } |