blob: 78bd5a20747e66d04be971a20afa50c72ade068e [file] [log] [blame]
/*
* 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);
}
}
}