Warnings.
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common
8 * Development and Distribution License("CDDL") (collectively, the
9 * "License"). You may not use this file except in compliance with the
10 * License. You can obtain a copy of the License at
11 * http://www.netbeans.org/cddl-gplv2.html
12 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13 * specific language governing permissions and limitations under the
14 * License. When distributing the software, include this License Header
15 * Notice in each file and include the License file at
16 * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17 * particular file as subject to the "Classpath" exception as provided
18 * by Sun in the GPL Version 2 section of the License file that
19 * accompanied this code. If applicable, add the following below the
20 * License Header, with the fields enclosed by brackets [] replaced by
21 * your own identifying information:
22 * "Portions Copyrighted [year] [name of copyright owner]"
26 * The Original Software is NetBeans. The Initial Developer of the Original
27 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28 * Microsystems, Inc. All Rights Reserved.
30 * If you wish your version of this file to be governed by only the CDDL
31 * or only the GPL Version 2, indicate your decision by adding
32 * "[Contributor] elects to include this software in this distribution
33 * under the [CDDL or GPL Version 2] license." If you do not indicate a
34 * single choice of license, a recipient has the option to distribute
35 * your version of this file under either the CDDL, the GPL Version 2 or
36 * to extend the choice of license to its licensees as provided above.
37 * However, if you add GPL Version 2 code and therefore, elected the GPL
38 * Version 2 license, then the option applies only if the new code is
39 * made subject to such option by the copyright holder.
42 package org.openide.util.lookup;
44 import java.util.concurrent.ExecutionException;
46 import java.lang.ref.WeakReference;
48 import java.util.concurrent.Executors;
49 import java.util.concurrent.TimeUnit;
50 import org.netbeans.junit.*;
51 import org.openide.util.Lookup;
52 import org.openide.util.lookup.AbstractLookup.Pair;
54 @SuppressWarnings("unchecked") // XXX ought to be corrected, just a lot of them
55 public class AbstractLookupTest extends AbstractLookupBaseHid implements AbstractLookupBaseHid.Impl {
56 public AbstractLookupTest(java.lang.String testName) {
57 super(testName, null);
61 // Impl of AbstractLookupBaseHid.Impl
64 /** Creates the initial abstract lookup.
66 public Lookup createInstancesLookup (InstanceContent ic) {
67 return new AbstractLookup (ic, new InheritanceTree ());
70 /** Creates an lookup for given lookup. This class just returns
71 * the object passed in, but subclasses can be different.
72 * @param lookup in lookup
73 * @return a lookup to use
75 public Lookup createLookup (Lookup lookup) {
79 public void clearCaches () {
82 public static void main(java.lang.String[] args) {
83 junit.textui.TestRunner.run(new NbTestSuite(AbstractLookupTest.class));
86 static class LkpResultCanBeGargageCollectedAndClearsTheResult extends AbstractLookup {
90 synchronized @Override boolean cleanUpResult(Template t) {
91 boolean res = super.cleanUpResult (t);
103 public void testResultCanBeGargageCollectedAndClearsTheResult () throws Exception {
104 LkpResultCanBeGargageCollectedAndClearsTheResult lkp = new LkpResultCanBeGargageCollectedAndClearsTheResult ();
105 assertSize ("24 for AbstractLookup, 8 for two ints", 32, lkp);
107 Lookup.Result res = lkp.lookup (new Lookup.Template (getClass ()));
110 WeakReference ref = new WeakReference (res);
112 assertGC ("Reference can get cleared", ref);
115 while (lkp.cleared == 0 && lkp.dirty == 0) {
119 assertEquals ("No dirty cleanups", 0, lkp.dirty);
120 assertEquals ("One final cleanup", 1, lkp.cleared);
122 //assertSize ("Everything has been cleaned to original size", 32, lkp);
126 public void testPairCannotBeUsedInMoreThanOneLookupAtOnce () throws Exception {
127 /** Simple pair with no data */
128 class EmptyPair extends AbstractLookup.Pair {
129 protected boolean creatorOf(Object obj) { return false; }
130 public String getDisplayName() { return "Empty"; }
131 public String getId() { return "empty"; }
132 public Object getInstance() { return null; }
133 public Class getType() { return Object.class; }
134 protected boolean instanceOf(Class c) { return c == getType (); }
135 } // end of EmptyPair
137 AbstractLookup.Content c1 = new AbstractLookup.Content ();
138 AbstractLookup.Content c2 = new AbstractLookup.Content ();
139 AbstractLookup l1 = new AbstractLookup (c1);
140 AbstractLookup l2 = new AbstractLookup (c2);
142 EmptyPair empty = new EmptyPair ();
144 Lookup.Result res = l1.lookup (new Lookup.Template (Object.class));
146 "Pair is really found", empty,
147 res.allItems ().iterator().next ()
151 fail ("It should not be possible to add pair to two lookups");
152 } catch (IllegalStateException ex) {
153 // ok, exception is fine
156 "L2 is still empty", Collections.EMPTY_LIST,
157 new ArrayList (l2.lookup (new Lookup.Template (Object.class)).allItems ())
161 public void testInitializationCanBeDoneFromAnotherThread () {
162 class MyLkp extends AbstractLookup implements Runnable {
163 private InstanceContent ic;
164 private boolean direct;
166 public MyLkp (boolean direct) {
167 this (direct, new InstanceContent ());
170 private MyLkp (boolean direct, InstanceContent ic) {
172 this.direct = direct;
176 protected @Override void initialize() {
181 Executors.newSingleThreadScheduledExecutor().schedule(this, 0, TimeUnit.MICROSECONDS).get();
182 } catch (InterruptedException ex) {
183 ex.printStackTrace();
184 } catch (ExecutionException ex) {
185 ex.printStackTrace();
193 ic.set (Collections.nCopies(10, this), null);
194 ic.set (Collections.EMPTY_LIST, null);
195 ic.add (AbstractLookupTest.this);
199 assertEquals ("The test should be there", this, new MyLkp (true).lookup (Object.class));
200 assertEquals ("and in async mode as well", this, new MyLkp (false).lookup (Object.class));
203 public void testBeforeLookupIsCalled () {
204 class BeforeL extends AbstractLookup {
205 public ArrayList list = new ArrayList ();
207 public InstanceContent ic;
210 this (new InstanceContent ());
213 private BeforeL (InstanceContent c) {
218 protected @Override void beforeLookup(Template t) {
220 list.add (0, new SerialPair (toAdd));
223 ic.add (new Integer (1));
228 BeforeL lookup = new BeforeL ();
230 lookup.toAdd = "First";
231 assertEquals ("First if found", "First", lookup.lookup (String.class));
234 assertEquals ("2 is not first", "2", lookup.lookup (String.class));
236 Lookup.Result res = lookup.lookup (new Lookup.Template (Object.class));
237 for (int i = 3; i < 20; i++) {
238 lookup.toAdd = String.valueOf (i);
239 assertEquals (i + " items are now there", i, res.allInstances ().size ());
241 for (int i = 20; i < 35; i++) {
242 lookup.toAdd = String.valueOf (i);
243 assertEquals (i + " items are now there", i, res.allItems ().size ());
246 assertEquals ("Just strings are there now", 1, res.allClasses ().size ());
247 lookup.toAdd = null; // this will add integer
248 assertEquals ("Two classes now", 2, res.allClasses ().size ());
251 public void testInconsistentAfterDeserIssue71744() throws Exception {
252 InheritanceTree inhTree = new InheritanceTree();
254 AbstractLookup al = new AbstractLookup(new AbstractLookup.Content(), inhTree);
257 Collection r = al.lookup(new Lookup.Template(Integer.class)).allInstances();
258 assertEquals("None", 0, r.size());
261 ICP item = new ICP(new Integer(10));
265 AbstractLookup newLookup = (AbstractLookup)reserialize(al);
267 newLookup.lookup(Number.class);
270 newLookup.addPair(new ICP(new Long(20)));
274 Collection r = newLookup.lookup(new Lookup.Template(Number.class)).allInstances();
275 assertEquals("one", 1, r.size());
277 Iterator it = r.iterator();
278 assertEquals(new Integer(10), it.next());
279 assertEquals(new Long(20), it.next());*/
283 public void testMatchesIssue130673() {
284 class BrokenPairReturningNullID extends Pair<Object> {
286 protected boolean instanceOf(Class<?> c) {
291 protected boolean creatorOf(Object obj) {
296 public Object getInstance() {
301 public Class<? extends Object> getType() {
306 public String getId() {
311 public String getDisplayName() {
315 BrokenPairReturningNullID broken = new BrokenPairReturningNullID();
318 Lookup.Template<String> t = new Lookup.Template<String>(String.class, "ID", null);
319 boolean not = AbstractLookup.matches(t, broken, true);
320 assertFalse("Does not match the template, but throws no exception", not);
323 private static final class ICP extends AbstractLookup.Pair {
326 public ICP (Number s) {
331 protected boolean instanceOf(Class c) {
332 return c.isInstance(s);
335 protected boolean creatorOf(Object obj) {
339 public Object getInstance() {
343 public Class getType() {
347 public String getId() {
351 public String getDisplayName() {