blob: df0823da0e23dff89304582bac0b27e40812134c [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.netbeans.modules.viewmodel;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.SwingUtilities;
import org.netbeans.junit.NbTestCase;
import org.netbeans.spi.viewmodel.*;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.util.RequestProcessor;
/**
* Tests the JPDABreakpointEvent.resume() functionality.
*
* @author Maros Sandor, Jan Jancura
*/
public class BasicTest extends NbTestCase {
private String helpID = "A test help ID"; // NOI18N
public BasicTest (String s) {
super (s);
}
static OutlineTable createView(final Models.CompoundModel mcm) {
final OutlineTable[] ttPtr = new OutlineTable[] { null };
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
ttPtr[0] = (OutlineTable) Models.createView(mcm);
}
});
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
} catch (InvocationTargetException ex) {
Exceptions.printStackTrace(ex.getTargetException());
}
assertNotNull(ttPtr[0]);
return ttPtr[0];
}
public void testBasic () throws Exception {
ArrayList l = new ArrayList ();
CompoundModel cm = new CompoundModel ();
l.add (cm);
Models.CompoundModel mcm = Models.createCompoundModel(l, helpID);
OutlineTable tt = createView(mcm);
RequestProcessor rp = tt.currentTreeModelRoot.getRootNode().getRequestProcessor();
cm.setRPUsed(rp);
waitFinished (rp);
Node n = tt.getExplorerManager ().
getRootContext ();
checkNode (n, "", rp);
if (cm.exception != null)
cm.exception.printStackTrace ();
assertNull ("Threading problem", cm.exception);
// TODO: Expansion test does not work - probably written in a bad way...
//assertEquals ("nodeExpanded notification number", 3, cm.expandedTest.size ());
//assertEquals ("nodeExpanded ", cm.toBeExpandedTest, cm.expandedTest);
assertEquals(n.getValue("propertiesHelpID"), helpID);
}
private void checkNode (Node n, String name, RequestProcessor rp) {
// init
//assertEquals (null, n.getShortDescription ());
Node[] ns = n.getChildren ().getNodes ();
waitFinished (rp);
ns = n.getChildren ().getNodes ();
if (name.length () < 4) {
assertEquals (name, 3, ns.length);
checkNode (ns [0], name + "a", rp);
checkNode (ns [1], name + "b", rp);
checkNode (ns [2], name + "c", rp);
} else
assertEquals (ns.length, 0);
if (name.length () > 0) {
//assertEquals (name, n.getName ());
n.getDisplayName ();
String sd = n.getShortDescription ();
n.getActions (false);
waitFinished (rp);
assertEquals (name, n.getDisplayName ());
assertEquals (name + "WWW", sd);
assertEquals (1, n.getActions (false).length);
}
}
static void waitFinished (RequestProcessor rp) {
rp.post (new Runnable () {
public void run () {}
}).waitFinished ();
}
public void testMnemonics() throws Exception {
ArrayList l = new ArrayList ();
CompoundModel cm = new CompoundModel ();
l.add (cm);
TestColumnModel tcm = new TestColumnModel();
l.add(tcm);
Models.CompoundModel mcm = Models.createCompoundModel(l);
OutlineTable tt = createView(mcm);
cm.setRPUsed(tt.currentTreeModelRoot.getRootNode().getRequestProcessor());
Node.Property[] columns = tt.columns;
assertEquals(2, columns.length);
assertEquals(new Character('e'), columns[1].getValue("ColumnMnemonicCharTTV"));
}
public static class CompoundModel implements TreeModel,
NodeModel, NodeActionsProvider, TableModel, TreeExpansionModel {
private final Set<ModelListener> listeners = new HashSet<ModelListener>();
private Throwable exception;
private Map callNumbers = new HashMap ();
private RequestProcessor rp;
void setRPUsed(RequestProcessor rp) {
this.rp = rp;
}
protected synchronized void addCall (String methodName, Object node) {
Map m = (Map) callNumbers.get (methodName);
if (m == null)
callNumbers.put (methodName, m = new HashMap ());
if (m.containsKey (node)) {
Object info = m.get(node);
if (info instanceof Exception) {
System.err.println ("Second call of " + methodName + " method for the same node " + node);
System.err.println("First was at:");
((Exception) info).printStackTrace();
System.err.println("Second is:");
Thread.dumpStack();
m.put (node, new Integer(2));
} else {
int numCalls = ((Integer) info).intValue() + 1;
System.err.println (numCalls+". call of " + methodName + " method for the same node " + node);
Thread.dumpStack();
m.put (node, new Integer(numCalls));
}
} else {
m.put (node, new Exception());
}
}
void checkThread () {
try {
assertTrue ("The right thread", rp.isRequestProcessorThread ());
} catch (Throwable t) {
exception = t;
}
/*;
Thread t = Thread.currentThread ();
if ( t.getClass ().getName ().startsWith
(RequestProcessor.class.getName ())
) exception = new Exception ();
*/
}
// TreeModel ...............................................................
/**
* Returns the root node of the tree or null, if the tree is empty.
*
* @return the root node of the tree or null
*/
public Object getRoot () {
//addCall ("getRoot", null);
return ROOT;
}
/**
* Returns children for given parent on given indexes.
*
* @param parent a parent of returned nodes
* @throws UnknownTypeException if this TreeModel implementation is not
* able to resolve dchildren for given node type
*
* @return children for given parent on given indexes
*/
public Object[] getChildren (Object parent, int from, int to)
throws UnknownTypeException {
addCall ("getChildren", parent);
if (parent == ROOT)
return new Object[] {"a", "b", "c"};
if (parent instanceof String)
return new Object[] {parent + "a", parent + "b", parent + "c"};
throw new UnknownTypeException (parent);
}
/**
* Returns number of children for given node.
*
* @param node the parent node
* @throws UnknownTypeException if this TreeModel implementation is not
* able to resolve children for given node type
*
* @return true if node is leaf
*/
public int getChildrenCount (Object node) throws UnknownTypeException {
addCall ("getChildrenCount", node);
if (node == ROOT)
return 3;
if (node instanceof String)
return 3;
throw new UnknownTypeException (node);
}
/**
* Returns true if node is leaf.
*
* @throws UnknownTypeException if this TreeModel implementation is not
* able to resolve dchildren for given node type
* @return true if node is leaf
*/
public boolean isLeaf (Object node) throws UnknownTypeException {
addCall ("isLeaf", node);
if (node == ROOT)
return false;
if (node instanceof String)
return ((String) node).length () > 3;
throw new UnknownTypeException (node);
}
// NodeModel ...........................................................
/**
* Returns display name for given node.
*
* @throws UnknownTypeException if this NodeModel implementation is not
* able to resolve display name for given node type
* @return display name for given node
*/
public String getDisplayName (Object node) throws UnknownTypeException {
addCall ("getDisplayName", node);
//checkThread ();
if (node instanceof String)
return (String) node;
throw new UnknownTypeException (node);
}
/**
* Returns tooltip for given node.
*
* @throws UnknownTypeException if this NodeModel implementation is not
* able to resolve tooltip for given node type
* @return tooltip for given node
*/
public String getShortDescription (Object node)
throws UnknownTypeException {
addCall ("getShortDescription", node);
//checkThread (); Short description is called on AWT! How else we could display a tooltip?
if (node == ROOT)
return "";
if (node instanceof String)
return node + "WWW";
throw new UnknownTypeException (node);
}
/**
* Returns icon for given node.
*
* @throws UnknownTypeException if this NodeModel implementation is not
* able to resolve icon for given node type
* @return icon for given node
*/
public String getIconBase (Object node)
throws UnknownTypeException {
addCall ("getIconBase", node);
//checkThread ();
if (node instanceof String)
return node + "XXX";
throw new UnknownTypeException (node);
}
// NodeActionsProvider .....................................................
/**
* Performs default action for given node.
*
* @throws UnknownTypeException if this NodeActionsProvider implementation
* is not able to resolve actions for given node type
* @return display name for given node
*/
public void performDefaultAction (Object node) throws UnknownTypeException {
}
/**
* Returns set of actions for given node.
*
* @throws UnknownTypeException if this NodeActionsProvider implementation
* is not able to resolve actions for given node type
* @return display name for given node
*/
public Action[] getActions (Object node) throws UnknownTypeException {
//checkThread ();
if (node == ROOT)
return new Action [0];
if (node instanceof String)
return new Action[] {
new AbstractAction ((String) node) {
public void actionPerformed (ActionEvent ev) {
}
},
};
throw new UnknownTypeException (node);
}
// ColumnsModel ............................................................
/**
* Returns sorted array of
* {@link org.netbeans.spi.viewmodel.ColumnModel}s.
*
* @return sorted array of ColumnModels
*/
public ColumnModel[] getColumns () {
return new ColumnModel [0];
}
// TableModel ..............................................................
public Object getValueAt (Object node, String columnID) throws
UnknownTypeException {
addCall ("getValueAt", node);
checkThread ();
if (node instanceof String) {
if (columnID.equals ("1"))
return node + "1";
if (columnID.equals ("2"))
return node + "2";
}
throw new UnknownTypeException (node);
}
public boolean isReadOnly (Object node, String columnID) throws
UnknownTypeException {
addCall ("isReadOnly", node);
checkThread ();
if (node instanceof String) {
if (columnID.equals ("1"))
return true;
if (columnID.equals ("2"))
return true;
}
throw new UnknownTypeException (node);
}
public void setValueAt (Object node, String columnID, Object value) throws
UnknownTypeException {
throw new UnknownTypeException (node);
}
// TreeExpansionModel ......................................................
private Set toBeExpandedTest = new HashSet ();
private Set expandedTest = new HashSet ();
{
toBeExpandedTest.add (getRoot());
toBeExpandedTest.add ("a");
toBeExpandedTest.add ("ab");
toBeExpandedTest.add ("abc");
}
/**
* Defines default state (collapsed, expanded) of given node.
*
* @param node a node
* @return default state (collapsed, expanded) of given node
*/
public boolean isExpanded (Object node) throws UnknownTypeException {
if (node instanceof String)
return toBeExpandedTest.contains (node);
throw new UnknownTypeException (node);
}
/**
* Called when given node is expanded.
*
* @param node a expanded node
*/
public void nodeExpanded (Object node) {
if (!toBeExpandedTest.contains (node)) {
System.err.println("This node should not be expanded: " + node);
Thread.dumpStack();
}
expandedTest.add (node);
}
/**
* Called when given node is collapsed.
*
* @param node a collapsed node
*/
public void nodeCollapsed (Object node) {
System.err.println("nodeCollapsed " + node);
Thread.dumpStack();
}
// listeners ...............................................................
/**
* Registers given listener.
*
* @param l the listener to add
*/
public void addModelListener (ModelListener l) {
synchronized (listeners) {
listeners.add (l);
}
}
/**
* Unregisters given listener.
*
* @param l the listener to remove
*/
public void removeModelListener (ModelListener l) {
synchronized (listeners) {
listeners.remove (l);
}
}
public void fire () {
List<ModelListener> v;
synchronized (listeners) {
v = new ArrayList<ModelListener>(listeners);
}
int i, k = v.size ();
for (i = 0; i < k; i++)
((ModelListener) v.get (i)).modelChanged (null);
}
public void fire (ModelEvent event) {
List<ModelListener> v;
synchronized (listeners) {
v = new ArrayList<ModelListener>(listeners);
}
int i, k = v.size ();
for (i = 0; i < k; i++) {
((ModelListener) v.get (i)).modelChanged (event);
}
}
}
private static class TestColumnModel extends ColumnModel {
public Class getType() {
return String.class;
}
public String getDisplayName() {
return "Test";
}
@Override
public Character getDisplayedMnemonic() {
return new Character('e');
}
public String getID() {
return "xx";
}
}
}