openide.util/test/unit/src/org/openide/util/lookup/AbstractLookupBaseHid.java
author Jesse Glick <jglick@netbeans.org>
Fri, 09 Oct 2009 15:11:13 -0400
changeset 833 0e00857c5827
parent 700 e4c18aa9c111
child 712 140de5cbeb24
permissions -rw-r--r--
Warnings.
jtulach@9
     1
/*
jtulach@302
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jtulach@189
     3
 *
mzlamal@700
     4
 * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
jtulach@189
     5
 *
jtulach@302
     6
 * The contents of this file are subject to the terms of either the GNU
jtulach@302
     7
 * General Public License Version 2 only ("GPL") or the Common
jtulach@302
     8
 * Development and Distribution License("CDDL") (collectively, the
jtulach@302
     9
 * "License"). You may not use this file except in compliance with the
jtulach@302
    10
 * License. You can obtain a copy of the License at
jtulach@302
    11
 * http://www.netbeans.org/cddl-gplv2.html
jtulach@302
    12
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jtulach@302
    13
 * specific language governing permissions and limitations under the
jtulach@302
    14
 * License.  When distributing the software, include this License Header
jtulach@302
    15
 * Notice in each file and include the License file at
jtulach@302
    16
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
jtulach@302
    17
 * particular file as subject to the "Classpath" exception as provided
jtulach@302
    18
 * by Sun in the GPL Version 2 section of the License file that
jtulach@302
    19
 * accompanied this code. If applicable, add the following below the
jtulach@302
    20
 * License Header, with the fields enclosed by brackets [] replaced by
jtulach@302
    21
 * your own identifying information:
jtulach@189
    22
 * "Portions Copyrighted [year] [name of copyright owner]"
jtulach@189
    23
 *
jtulach@302
    24
 * Contributor(s):
jtulach@302
    25
 *
jtulach@189
    26
 * The Original Software is NetBeans. The Initial Developer of the Original
jtulach@189
    27
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
jtulach@9
    28
 * Microsystems, Inc. All Rights Reserved.
jtulach@302
    29
 *
jtulach@302
    30
 * If you wish your version of this file to be governed by only the CDDL
jtulach@302
    31
 * or only the GPL Version 2, indicate your decision by adding
jtulach@302
    32
 * "[Contributor] elects to include this software in this distribution
jtulach@302
    33
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
jtulach@302
    34
 * single choice of license, a recipient has the option to distribute
jtulach@302
    35
 * your version of this file under either the CDDL, the GPL Version 2 or
jtulach@302
    36
 * to extend the choice of license to its licensees as provided above.
jtulach@302
    37
 * However, if you add GPL Version 2 code and therefore, elected the GPL
jtulach@302
    38
 * Version 2 license, then the option applies only if the new code is
jtulach@302
    39
 * made subject to such option by the copyright holder.
jtulach@9
    40
 */
jtulach@9
    41
jtulach@9
    42
package org.openide.util.lookup;
jtulach@9
    43
jtulach@551
    44
import java.io.ByteArrayInputStream;
jtulach@551
    45
import java.io.ByteArrayOutputStream;
jtulach@551
    46
import java.io.ObjectInputStream;
jtulach@551
    47
import java.io.ObjectOutputStream;
jglick@705
    48
import java.io.Serializable;
jglick@705
    49
import java.lang.ref.WeakReference;
jglick@705
    50
import java.lang.ref.Reference;
jglick@705
    51
import java.util.ArrayList;
jglick@705
    52
import java.util.Arrays;
jglick@705
    53
import java.util.Collection;
jglick@705
    54
import java.util.Collections;
jglick@705
    55
import java.util.Iterator;
jglick@705
    56
import java.util.LinkedList;
jglick@705
    57
import java.util.List;
jglick@705
    58
import java.util.concurrent.Executors;
jglick@705
    59
import java.util.concurrent.TimeUnit;
jtulach@85
    60
import javax.swing.ActionMap;
jtulach@85
    61
import javax.swing.InputMap;
jglick@705
    62
import org.netbeans.junit.NbTestCase;
jtulach@550
    63
import org.openide.util.Lookup;
jtulach@85
    64
import org.openide.util.Lookup.Template;
jtulach@550
    65
import org.openide.util.LookupEvent;
jtulach@550
    66
import org.openide.util.LookupListener;
jtulach@9
    67
jglick@705
    68
@SuppressWarnings("unchecked") // XXX ought to be corrected, just a lot of them
jtulach@9
    69
public class AbstractLookupBaseHid extends NbTestCase {
jtulach@9
    70
    private static AbstractLookupBaseHid running;
jtulach@189
    71
jtulach@9
    72
    /** instance content to work with */
jtulach@9
    73
    InstanceContent ic;
jtulach@9
    74
    /** the lookup to work on */
jtulach@9
    75
    protected Lookup instanceLookup;
jtulach@9
    76
    /** the lookup created to work with */
jtulach@9
    77
    private Lookup lookup;
jtulach@9
    78
    /** implementation of methods that can influence the behaviour */
jtulach@9
    79
    Impl impl;
jtulach@9
    80
    
jglick@705
    81
    protected AbstractLookupBaseHid(String testName, Impl impl) {
jtulach@9
    82
        super(testName);
jtulach@9
    83
        if (impl == null && (this instanceof Impl)) {
jtulach@9
    84
            impl = (Impl)this;
jtulach@9
    85
        }
jtulach@9
    86
        this.impl = impl;
jtulach@9
    87
    }
jtulach@9
    88
    
jglick@705
    89
    protected @Override void setUp() {
jtulach@9
    90
        this.ic = new InstanceContent ();
jtulach@296
    91
        
jtulach@296
    92
        beforeActualTest(getName());
jtulach@296
    93
        
jtulach@9
    94
        this.instanceLookup = createInstancesLookup (ic);
jtulach@9
    95
        this.lookup = createLookup (instanceLookup);
jtulach@9
    96
        running = this;
jtulach@9
    97
    }        
jtulach@9
    98
    
jglick@705
    99
    protected @Override void tearDown() {
jtulach@9
   100
        running = null;
jtulach@9
   101
    }
jtulach@9
   102
    
jtulach@9
   103
    /** The methods to influence test behaviour */
jtulach@9
   104
    public static interface Impl {
jtulach@9
   105
        /** Creates the initial abstract lookup.
jtulach@9
   106
         */
jtulach@9
   107
        public Lookup createInstancesLookup (InstanceContent ic);
jtulach@9
   108
        /** Creates an lookup for given lookup. This class just returns 
jtulach@9
   109
         * the object passed in, but subclasses can be different.
jtulach@9
   110
         * @param lookup in lookup
jtulach@9
   111
         * @return a lookup to use
jtulach@9
   112
         */
jtulach@9
   113
        public Lookup createLookup (Lookup lookup);
jtulach@9
   114
        
jtulach@9
   115
        /** If the impl has any caches that would prevent the system
jtulach@9
   116
         * to not garbage collect correctly, then clear them now.
jtulach@9
   117
         */
jtulach@9
   118
        public void clearCaches ();
jtulach@9
   119
    }
jtulach@9
   120
    
jtulach@9
   121
    private Lookup createInstancesLookup (InstanceContent ic) {
jtulach@9
   122
        return impl.createInstancesLookup (ic);
jtulach@9
   123
    }
jtulach@9
   124
    
jtulach@9
   125
    private Lookup createLookup (Lookup lookup) {
jtulach@9
   126
        return impl.createLookup (lookup);
jtulach@9
   127
    }
jtulach@9
   128
    
jtulach@9
   129
    /** instances that we register */
jtulach@9
   130
    private static Object[] INSTANCES = new Object[] {
jtulach@9
   131
        new Integer (10), 
jtulach@9
   132
        new Object ()
jtulach@9
   133
    };
jtulach@9
   134
    
jtulach@9
   135
    /** Test if first is really first.
jtulach@9
   136
     */
jtulach@9
   137
    public void testFirst () {
jglick@705
   138
        Integer i1 = 1;
jglick@705
   139
        Integer i2 = 2;
jtulach@9
   140
        
jtulach@9
   141
        ic.add (i1);
jtulach@9
   142
        ic.add (i2);
jtulach@9
   143
        
jglick@705
   144
        Integer found = lookup.lookup(Integer.class);
jtulach@9
   145
        if (found != i1) {
jtulach@9
   146
            fail ("First object is not first: " + found + " != " + i1);
jtulach@9
   147
        }
jtulach@9
   148
        
jglick@705
   149
        List<Integer> list = new ArrayList<Integer>();
jtulach@9
   150
        list.add (i2);
jtulach@9
   151
        list.add (i1);
jtulach@9
   152
        ic.set (list, null);
jtulach@9
   153
        
jtulach@9
   154
        found = lookup.lookup (Integer.class);
jtulach@9
   155
        if (found != i2) {
jtulach@9
   156
            fail ("Second object is not first after reorder: " + found + " != " + i2);
jtulach@9
   157
        }
jtulach@9
   158
        
jtulach@9
   159
    }
jtulach@346
   160
jtulach@346
   161
    public void testToString() {
jtulach@346
   162
        String txt = lookup.toString();
jtulach@346
   163
        assertNotNull("Something is there", txt);
jtulach@346
   164
        assertTrue("Something2: " + txt, txt.length() > 0);
jtulach@346
   165
    }
jtulach@9
   166
jtulach@9
   167
jtulach@9
   168
    /** Tests ordering of items in the lookup.
jtulach@9
   169
    */
jtulach@9
   170
    public void testOrder () {
jtulach@9
   171
        addInstances (INSTANCES);
jtulach@9
   172
jtulach@9
   173
        if (INSTANCES[0] != lookup.lookup (INSTANCES[0].getClass ())) {
jtulach@9
   174
            fail ("First object in intances not found");
jtulach@9
   175
        }
jtulach@9
   176
jglick@705
   177
        Iterator<?> all = lookup.lookupAll(Object.class).iterator();
jtulach@9
   178
        checkIterator ("Difference between instances added and found", all, Arrays.asList (INSTANCES));
jtulach@9
   179
    }
jtulach@9
   180
    
jtulach@9
   181
    /** Checks the reorder of items in lookup reflects the result.
jtulach@9
   182
     * Testing both classes and interfaces, because they are often treated
jtulach@9
   183
     * especially.
jtulach@9
   184
     */
jtulach@9
   185
    public void testReorder () {
jtulach@9
   186
        String s1 = "s2";
jtulach@9
   187
        String s2 = "s1";
jtulach@9
   188
        Runnable r1 = new Runnable () {
jtulach@9
   189
            public void run () {}
jtulach@9
   190
        };
jtulach@9
   191
        Runnable r2 = new Runnable () {
jtulach@9
   192
            public void run () {}
jtulach@9
   193
        };
jglick@705
   194
        List<Object> l = new ArrayList<Object>();
jtulach@9
   195
jtulach@9
   196
        l.add (s1);
jtulach@9
   197
        l.add (s2);
jtulach@9
   198
        l.add (r1);
jtulach@9
   199
        l.add (r2);
jtulach@9
   200
        ic.set (l, null);
jtulach@9
   201
     
jtulach@9
   202
        assertEquals ("s1 is found", s1, lookup.lookup (String.class));
jtulach@9
   203
        assertEquals ("r1 is found", r1, lookup.lookup (Runnable.class));
jtulach@9
   204
        
jtulach@9
   205
        Collections.reverse (l);
jtulach@9
   206
        
jtulach@9
   207
        ic.set (l, null);
jtulach@9
   208
        
jtulach@9
   209
        assertEquals ("s2 is found", s2, lookup.lookup (String.class));
jtulach@9
   210
        assertEquals ("r2 is found", r2, lookup.lookup (Runnable.class));
jtulach@9
   211
    }
jtulach@9
   212
    
jtulach@9
   213
    /** Tries to set empty collection to the lookup.
jtulach@9
   214
     */
jtulach@9
   215
    public void testSetEmpty () {
jtulach@9
   216
        ic.add ("A serializable string");
jtulach@9
   217
        lookup.lookup (Serializable.class);
jtulach@9
   218
        
jglick@705
   219
        ic.set (Collections.emptyList(), null);
jtulach@9
   220
    }
jtulach@9
   221
    
jtulach@9
   222
    /** Tests a more complex reorder on nodes.
jtulach@9
   223
     */
jtulach@9
   224
    public void testComplexReorder () {
jglick@705
   225
        Integer i1 = 1;
jglick@705
   226
        Long i2 = 2L;
jtulach@9
   227
        
jglick@705
   228
        List<Object> l = new ArrayList<Object>();
jtulach@9
   229
        l.add (i1);
jtulach@9
   230
        l.add (i2);
jtulach@9
   231
        ic.set (l, null);
jtulach@9
   232
        
jtulach@9
   233
        assertEquals ("Find integer", i1, lookup.lookup (Integer.class));
jtulach@9
   234
        assertEquals ("Find long", i2, lookup.lookup (Long.class));
jtulach@9
   235
        assertEquals ("Find number", i1, lookup.lookup (Number.class));
jtulach@9
   236
        
jtulach@9
   237
        Collections.reverse (l);
jtulach@9
   238
        
jtulach@9
   239
        ic.set (l, null);
jtulach@9
   240
        
jtulach@9
   241
        assertEquals ("Find integer", i1, lookup.lookup (Integer.class));
jtulach@9
   242
        assertEquals ("Find long", i2, lookup.lookup (Long.class));
jtulach@9
   243
        assertEquals ("Find number", i2, lookup.lookup (Number.class));
jtulach@9
   244
    }
jtulach@9
   245
    
jtulach@9
   246
    /** Checks whether setPairs keeps the order.
jtulach@9
   247
     */
jtulach@9
   248
    public void testSetPairs () {
jtulach@9
   249
        // test setPairs method
jglick@705
   250
        List<Object> li = new ArrayList<Object>();
jtulach@9
   251
        li.addAll (Arrays.asList (INSTANCES));
jtulach@9
   252
        ic.set (li, null);
jtulach@9
   253
        
jglick@705
   254
        Lookup.Result<Object> res = lookup.lookupResult(Object.class);
jglick@705
   255
        Iterator<?> all = res.allInstances().iterator();
jtulach@9
   256
        checkIterator ("Original order not kept", all, li);
jtulach@9
   257
        
jtulach@9
   258
        // reverse the order
jtulach@9
   259
        Collections.reverse (li);
jtulach@9
   260
        
jtulach@9
   261
        // change the pairs
jtulach@9
   262
        LL listener = new LL (res);
jtulach@9
   263
        res.addLookupListener (listener);
jtulach@9
   264
        ic.set (li, null);
jtulach@9
   265
        if (listener.getCount () != 1) {
jtulach@9
   266
            fail ("Result has not changed even we set reversed order");
jtulach@9
   267
        }
jtulach@9
   268
        
jtulach@9
   269
        all = res.allInstances ().iterator ();
jtulach@9
   270
        checkIterator ("Reversed order not kept", all, li);
jtulach@9
   271
    }
jtulach@9
   272
jtulach@9
   273
    /** Checks whether setPairs fires correct events.
jtulach@9
   274
     */
jtulach@9
   275
    public void testSetPairsFire () {
jtulach@9
   276
        // test setPairs method
jglick@705
   277
        List<Object> li = new ArrayList<Object>();
jtulach@9
   278
        li.addAll (Arrays.asList (INSTANCES));
jtulach@9
   279
        ic.set (li, null);
jtulach@9
   280
        
jglick@705
   281
        Lookup.Result<Integer> res = lookup.lookupResult(Integer.class);
jglick@705
   282
        Iterator<?> all = res.allInstances().iterator();
jtulach@9
   283
        checkIterator ("Integer is not there", all, Collections.nCopies (1, INSTANCES[0]));
jtulach@9
   284
        
jtulach@9
   285
        // change the pairs
jtulach@9
   286
        LL listener = new LL (res);
jtulach@9
   287
        res.addLookupListener (listener);
jtulach@9
   288
jglick@705
   289
        List<Object> l2 = new ArrayList<Object>(li);
jtulach@9
   290
        l2.remove (INSTANCES[0]);
jtulach@9
   291
        ic.set (l2, null);
jtulach@9
   292
jglick@705
   293
        all = lookup.lookupAll(Object.class).iterator();
jtulach@9
   294
        checkIterator ("The removed integer is not noticed", all, l2);
jtulach@9
   295
jtulach@9
   296
        if (listener.getCount () != 1) {
jtulach@9
   297
            fail ("Nothing has not been fired");
jtulach@9
   298
        }
jtulach@9
   299
    }
jtulach@9
   300
jtulach@9
   301
    /** Checks whether set pairs does not fire when they should not.
jtulach@9
   302
    */
jtulach@9
   303
    public void testSetPairsDoesNotFire () {
jtulach@9
   304
        Object tmp = new Object ();
jtulach@9
   305
jglick@705
   306
        List<Object> li = new ArrayList<Object>();
jtulach@9
   307
        li.add (tmp);
jtulach@9
   308
        li.addAll (Arrays.asList (INSTANCES));
jtulach@9
   309
        ic.set (li, null);
jtulach@9
   310
        
jglick@705
   311
        Lookup.Result<Integer> res = lookup.lookupResult(Integer.class);
jglick@705
   312
        Iterator<?> all = res.allInstances ().iterator ();
jtulach@9
   313
        checkIterator ("Integer is not there", all, Collections.nCopies (1, INSTANCES[0]));
jtulach@9
   314
        
jtulach@9
   315
        // change the pairs
jtulach@9
   316
        LL listener = new LL (res);
jtulach@9
   317
        res.addLookupListener (listener);
jtulach@9
   318
jglick@705
   319
        List<Object> l2 = new ArrayList<Object>(li);
jtulach@9
   320
        l2.remove (tmp);
jtulach@9
   321
        ic.set (l2, null);
jtulach@9
   322
jglick@705
   323
        all = lookup.lookupAll(Object.class).iterator();
jtulach@9
   324
        checkIterator ("The removed integer is not noticed", all, l2);
jtulach@9
   325
jtulach@9
   326
        if (listener.getCount () != 0) {
jtulach@9
   327
            fail ("Something has been fired");
jtulach@9
   328
        }
jtulach@9
   329
    }
jtulach@9
   330
    
jtulach@9
   331
    /** Test whether after registration it is possible to find registered objects
jtulach@9
   332
    * 
jtulach@9
   333
     */
jtulach@9
   334
    public void testLookupAndAdd () throws Exception {
jtulach@9
   335
        addInstances (INSTANCES);
jtulach@9
   336
jtulach@9
   337
        for (int i = 0; i < INSTANCES.length; i++) {
jtulach@9
   338
            Object obj = INSTANCES[i];
jtulach@9
   339
            findAll (lookup, obj.getClass (), true);
jtulach@9
   340
        }
jtulach@9
   341
    }
jtulach@9
   342
jtulach@9
   343
    /** Tries to find all classes and superclasses in the lookup.
jtulach@9
   344
    */
jglick@705
   345
    private void findAll(Lookup lookup, Class<?> clazz, boolean shouldBeThere) {
jtulach@9
   346
        if (clazz == null) return;
jtulach@9
   347
jtulach@9
   348
        Object found = lookup.lookup (clazz);
jtulach@9
   349
        if (found == null) {
jtulach@9
   350
            if (shouldBeThere) {
jtulach@9
   351
                // should find at either instance or something else, but must
jtulach@9
   352
                // find at least something
jtulach@9
   353
                fail ("Lookup (" + clazz.getName () + ") found nothing");
jtulach@9
   354
            }
jtulach@9
   355
        } else {
jtulach@9
   356
            if (!shouldBeThere) {
jtulach@9
   357
                // should find at either instance or something else, but must
jtulach@9
   358
                // find at least something
jtulach@9
   359
                fail ("Lookup (" + clazz.getName () + ") found " + found);
jtulach@9
   360
            }
jtulach@9
   361
        }
jtulach@9
   362
jglick@705
   363
        Lookup.Result<?> res = lookup.lookupResult(clazz);
jglick@705
   364
        Collection<?> collection = res.allInstances();
jtulach@9
   365
jtulach@9
   366
        for (int i = 0; i < INSTANCES.length; i++) {
jtulach@9
   367
            boolean isSubclass = clazz.isInstance (INSTANCES[i]);
jtulach@9
   368
            boolean isThere = collection.contains (INSTANCES[i]);
jtulach@9
   369
jtulach@9
   370
            if (isSubclass != isThere) {
jtulach@9
   371
                // a problem found
jtulach@9
   372
                // should find at either instance or something else, but must
jtulach@9
   373
                // find at least something
jtulach@9
   374
                fail ("Lookup.Result (" + clazz.getName () + ") for " + INSTANCES[i] + " is subclass: " + isSubclass + " isThere: " + isThere);
jtulach@9
   375
            }
jtulach@9
   376
        }
jtulach@9
   377
jtulach@9
   378
        // go on for superclasses
jtulach@9
   379
jtulach@9
   380
        findAll (lookup, clazz.getSuperclass (), shouldBeThere);
jtulach@9
   381
jtulach@9
   382
        Class[] ies = clazz.getInterfaces ();
jtulach@9
   383
        for (int i = 0; i < ies.length; i++) {
jtulach@9
   384
            findAll (lookup, ies[i], shouldBeThere);
jtulach@9
   385
        }
jtulach@9
   386
    }
jtulach@9
   387
    
jtulach@9
   388
    /** Test if it is possible to remove a registered object. */
jtulach@9
   389
    public void testRemoveRegisteredObject() {
jtulach@9
   390
        Integer inst = new Integer(10);
jtulach@9
   391
        
jtulach@9
   392
        ic.add(inst);
jtulach@9
   393
        if (lookup.lookup(inst.getClass()) == null) {
jtulach@9
   394
            // should find an instance
jtulach@9
   395
            fail("Lookup (" + inst.getClass().getName () + ") found nothing");
jtulach@9
   396
        }
jtulach@9
   397
        
jtulach@9
   398
        ic.remove(inst);
jtulach@9
   399
        if (lookup.lookup(inst.getClass()) != null) {
jtulach@9
   400
            // should NOT find an instance
jtulach@9
   401
            fail("Lookup (" + inst.getClass().getName () +
jtulach@9
   402
                ") found an instance after remove operation");
jtulach@9
   403
        }
jtulach@9
   404
    }
jtulach@9
   405
    
jtulach@9
   406
    public void testCanReturnReallyStrangeResults () throws Exception {
jglick@705
   407
        class QueryingPair extends AbstractLookup.Pair<Object> {
jglick@705
   408
            private Integer i = 434;
jtulach@9
   409
            
jtulach@9
   410
            //
jtulach@9
   411
            // do the test
jtulach@9
   412
            //
jtulach@9
   413
            
jtulach@9
   414
            public void doTest () throws Exception {
jtulach@9
   415
                ic.add (i);
jtulach@9
   416
                ic.addPair (this);
jtulach@9
   417
                
jtulach@9
   418
                Object found = lookup.lookup (QueryingPair.class);
jtulach@9
   419
                assertEquals ("This object is found", this, found);
jtulach@9
   420
            }
jtulach@9
   421
            
jtulach@9
   422
            
jtulach@9
   423
            //
jtulach@9
   424
            // Implementation of pair
jtulach@9
   425
            // 
jtulach@9
   426
        
jglick@705
   427
            public String getId() {
jtulach@9
   428
                return getType ().toString();
jtulach@9
   429
            }
jtulach@9
   430
jglick@705
   431
            public String getDisplayName() {
jtulach@9
   432
                return getId ();
jtulach@9
   433
            }
jtulach@9
   434
jglick@705
   435
            public Class<?> getType() {
jtulach@9
   436
                return getClass ();
jtulach@9
   437
            }
jtulach@9
   438
jglick@705
   439
            protected boolean creatorOf(Object obj) {
jtulach@9
   440
                return obj == this;
jtulach@9
   441
            }
jtulach@9
   442
jglick@705
   443
            protected boolean instanceOf(Class<?> c) {
jtulach@9
   444
                assertEquals ("Integer found or exception is thrown", i, lookup.lookup (Integer.class));
jtulach@9
   445
                return c.isAssignableFrom(getType ());
jtulach@9
   446
            }
jtulach@9
   447
jglick@705
   448
            public Object getInstance() {
jtulach@9
   449
                return this;
jtulach@9
   450
            }
jtulach@9
   451
            
jtulach@9
   452
            
jtulach@9
   453
        }
jtulach@9
   454
        
jtulach@9
   455
        
jtulach@9
   456
        QueryingPair qp = new QueryingPair ();
jtulach@9
   457
        qp.doTest ();
jtulach@9
   458
    }
jtulach@9
   459
    
jtulach@9
   460
    /** Test of firing events. */
jtulach@9
   461
    public void testLookupListener() {
jglick@705
   462
        Object inst = 10;
jglick@705
   463
        Lookup.Result<?> res = lookup.lookupResult(inst.getClass());
jtulach@9
   464
        res.allInstances ();
jtulach@9
   465
        
jtulach@9
   466
        LL listener = new LL(res);
jtulach@9
   467
        res.addLookupListener(listener);
jtulach@9
   468
        
jtulach@9
   469
        ic.add(inst);
jtulach@9
   470
        if (listener.getCount() == 0) {
jtulach@9
   471
            fail("None event fired during NbLookup.addPair()");
jtulach@9
   472
        }
jtulach@9
   473
        
jtulach@9
   474
        ic.remove(inst);
jtulach@9
   475
        if (listener.getCount() == 0) {
jtulach@9
   476
            fail("None event fired during NbLookup.removePair()");
jtulach@9
   477
        }
jtulach@9
   478
        
jtulach@9
   479
        ic.add(inst);
jtulach@9
   480
        if (listener.getCount() == 0) {
jtulach@9
   481
            fail("None event fired during second NbLookup.addPair()");
jtulach@9
   482
        }
jtulach@9
   483
        
jtulach@9
   484
        ic.remove(inst);
jtulach@9
   485
        if (listener.getCount() == 0) {
jtulach@9
   486
            fail("None event fired during second NbLookup.removePair()");
jtulach@9
   487
        }
jtulach@9
   488
    }
jtulach@9
   489
    
jtulach@9
   490
    /** Testing identity of the lookup.
jtulach@9
   491
     */
jtulach@9
   492
    public void testId () {
jglick@705
   493
        Lookup.Template<?> templ;
jtulach@9
   494
        int cnt;
jtulach@9
   495
        
jtulach@9
   496
        addInstances (INSTANCES);
jtulach@9
   497
        
jglick@705
   498
        Lookup.Result<?> res = lookup.lookupResult(Object.class);
jglick@705
   499
        for (AbstractLookup.Item<?> item : res.allItems()) {
jtulach@9
   500
            
jglick@705
   501
            templ = new Lookup.Template<Object>(null, item.getId(), null);
jtulach@9
   502
            cnt = lookup.lookup (templ).allInstances ().size ();
jtulach@9
   503
            if (cnt != 1) {
jtulach@9
   504
                fail ("Identity lookup failed. Instances = " + cnt);
jtulach@9
   505
            }
jtulach@9
   506
jglick@705
   507
            templ = makeTemplate(item.getType(), item.getId());
jtulach@9
   508
            cnt = lookup.lookup (templ).allInstances ().size ();
jtulach@9
   509
            if (cnt != 1) {
jtulach@9
   510
                fail ("Identity lookup with type failed. Instances = " + cnt);
jtulach@9
   511
            }
jtulach@9
   512
            
jglick@705
   513
            templ = makeTemplate(this.getClass(), item.getId());
jtulach@9
   514
            cnt = lookup.lookup (templ).allInstances ().size ();
jtulach@9
   515
            if (cnt != 0) {
jtulach@9
   516
                fail ("Identity lookup with wrong type failed. Instances = " + cnt);
jtulach@9
   517
            }
jtulach@9
   518
            
jglick@705
   519
            templ = new Lookup.Template<Object>(null, null, item.getInstance());
jtulach@9
   520
            cnt = lookup.lookup (templ).allInstances ().size ();
jtulach@9
   521
            if (cnt != 1) {
jtulach@9
   522
                fail ("Instance lookup failed. Instances = " + cnt);
jtulach@9
   523
            }
jtulach@9
   524
jglick@705
   525
            templ = new Lookup.Template<Object>(null, item.getId(), item.getInstance());
jtulach@9
   526
            cnt = lookup.lookup (templ).allInstances ().size ();
jtulach@9
   527
            if (cnt != 1) {
jtulach@9
   528
                fail ("Instance & identity lookup failed. Instances = " + cnt);
jtulach@9
   529
            }
jtulach@9
   530
            
jtulach@9
   531
        }
jtulach@9
   532
    }
jglick@705
   533
    private static <T> Lookup.Template<T> makeTemplate(Class<T> clazz, String id) { // captures type parameter
jglick@705
   534
        return new Lookup.Template<T>(clazz, id, null);
jglick@705
   535
    }
jtulach@9
   536
    
jtulach@9
   537
    /** Tests adding and removing.
jtulach@9
   538
     */
jtulach@9
   539
    public void testAddAndRemove () throws Exception {
jtulach@9
   540
        Object map = new javax.swing.ActionMap ();
jtulach@9
   541
        LL ll = new LL ();
jtulach@9
   542
        
jglick@705
   543
        Lookup.Result<?> res = lookup.lookupResult(map.getClass());
jtulach@9
   544
        res.allItems();
jtulach@9
   545
        res.addLookupListener (ll);
jtulach@9
   546
        ll.source = res;
jtulach@9
   547
        
jtulach@9
   548
        ic.add (map);
jtulach@9
   549
        
jtulach@9
   550
        assertEquals ("First change when adding", ll.getCount (), 1);
jtulach@9
   551
        
jtulach@9
   552
        ic.remove (map);
jtulach@9
   553
        
jtulach@9
   554
        assertEquals ("Second when removing", ll.getCount (), 1);
jtulach@9
   555
        
jtulach@9
   556
        ic.add (map);
jtulach@9
   557
        
jtulach@9
   558
        assertEquals ("Third when readding", ll.getCount (), 1);
jtulach@9
   559
        
jtulach@9
   560
        ic.remove (map);
jtulach@9
   561
        
jtulach@9
   562
        assertEquals ("Forth when reremoving", ll.getCount (), 1);
jtulach@9
   563
        
jtulach@9
   564
    }
jtulach@9
   565
    
jtulach@9
   566
    /** Will a class garbage collect even it is registered in lookup.
jtulach@9
   567
     */
jtulach@9
   568
    public void testGarbageCollect () throws Exception {
jtulach@9
   569
        ClassLoader l = new CL ();
jglick@705
   570
        Class<?> c = l.loadClass(Garbage.class.getName());
jglick@705
   571
        Reference<?> ref = new WeakReference<Object>(c);
jtulach@9
   572
jtulach@9
   573
        lookup.lookup (c);
jtulach@9
   574
        
jtulach@9
   575
        // now test garbage collection
jtulach@9
   576
        c = null;
jtulach@9
   577
        l = null;
jtulach@9
   578
        impl.clearCaches ();
jtulach@9
   579
        assertGC ("The classloader has not been garbage collected!", ref);
jtulach@9
   580
    }
jtulach@9
   581
                
jtulach@9
   582
    /** Items are the same as results.
jtulach@9
   583
     */
jtulach@9
   584
    public void testItemsAndIntances () {
jtulach@9
   585
        addInstances (INSTANCES);
jtulach@9
   586
        
jglick@705
   587
        Lookup.Result<Object> r = lookup.lookupResult(Object.class);
jglick@705
   588
        Collection<? extends Lookup.Item<?>> items = r.allItems();
jglick@705
   589
        Collection<?> insts = r.allInstances();
jtulach@9
   590
        
jtulach@9
   591
        if (items.size () != insts.size ()) {
jtulach@9
   592
            fail ("Different size of sets");
jtulach@9
   593
        }
jglick@705
   594
jglick@705
   595
        for (Lookup.Item<?> item : items) {
jtulach@9
   596
            if (!insts.contains (item.getInstance ())) {
jtulach@9
   597
                fail ("Intance " + item.getInstance () + " is missing in " + insts);
jtulach@9
   598
            }
jtulach@9
   599
        }
jtulach@9
   600
    }
jtulach@9
   601
    
jtulach@9
   602
    /** Checks search for interface.
jtulach@9
   603
     */
jtulach@9
   604
    public void testSearchForInterface () {
jglick@705
   605
        Lookup.Template<Serializable> t = new Lookup.Template<Serializable>(Serializable.class, null, null);
jtulach@9
   606
        
jtulach@9
   607
        assertNull("Nothing to find", lookup.lookupItem (t));
jtulach@9
   608
        
jtulach@9
   609
        Serializable s = new Serializable () {};
jtulach@9
   610
        ic.add (s);
jtulach@9
   611
        
jtulach@9
   612
        Lookup.Item item = lookup.lookupItem (t);
jtulach@9
   613
        assertNotNull ("Something found", item);
jtulach@9
   614
    }
jtulach@9
   615
jtulach@9
   616
    /** Test to add broken item if it incorrectly answers instanceOf questions.
jtulach@9
   617
     */
jtulach@9
   618
    public void testIncorectInstanceOf40364 () {
jtulach@9
   619
        final Long sharedLong = new Long (0);
jtulach@9
   620
        
jglick@705
   621
        class P extends AbstractLookup.Pair<Object> {
jtulach@9
   622
            public boolean isLong;
jtulach@9
   623
            
jtulach@9
   624
            P (boolean b) {
jtulach@9
   625
                isLong = b;
jtulach@9
   626
            }
jtulach@9
   627
            
jtulach@9
   628
            protected boolean creatorOf (Object obj) {
jtulach@9
   629
                return obj == sharedLong;
jtulach@9
   630
            }
jtulach@9
   631
            
jtulach@9
   632
            public String getDisplayName () {
jtulach@9
   633
                return "";
jtulach@9
   634
            }
jtulach@9
   635
            
jtulach@9
   636
            public String getId () {
jtulach@9
   637
                return "";
jtulach@9
   638
            }
jtulach@9
   639
            
jtulach@9
   640
            public Object getInstance () {
jtulach@9
   641
                return sharedLong;
jtulach@9
   642
            }
jtulach@9
   643
            
jglick@705
   644
            public Class<?> getType() {
jtulach@9
   645
                return isLong ? Long.class : Number.class;
jtulach@9
   646
            }
jtulach@9
   647
            
jglick@705
   648
            protected boolean instanceOf(Class<?> c) {
jtulach@9
   649
                return c.isAssignableFrom (getType ());
jtulach@9
   650
            }
jtulach@9
   651
    
jglick@705
   652
            public @Override int hashCode() {
jtulach@9
   653
                return getClass ().hashCode ();
jtulach@9
   654
            }    
jtulach@9
   655
jglick@705
   656
            public @Override boolean equals(Object obj) {
jtulach@9
   657
                return obj != null && getClass ().equals (obj.getClass ());
jtulach@9
   658
            }
jtulach@9
   659
        }
jtulach@9
   660
        
jtulach@9
   661
        // to create the right structure in the lookup
jtulach@9
   662
        lookup.lookup (Object.class);
jtulach@9
   663
        lookup.lookup (Long.class);
jtulach@9
   664
        lookup.lookup (Number.class);
jtulach@9
   665
        
jtulach@9
   666
        P lng1 = new P (true);
jtulach@9
   667
        ic.addPair (lng1);
jtulach@9
   668
jtulach@9
   669
        P lng2 = new P (false);
jtulach@9
   670
        ic.setPairs (Collections.singleton (lng2));
jtulach@9
   671
        
jglick@705
   672
        Collection<? extends Lookup.Item<?>> res = lookup.lookupResult(Object.class).allItems();
jtulach@9
   673
        assertEquals ("Just one pair", 1, res.size ());
jtulach@9
   674
    }
jtulach@9
   675
jtulach@9
   676
    public void testAbsolutelyCrazyWayToSimulateIssue48590ByChangingTheBehaviourOfEqualOnTheFly () throws Exception {
jglick@705
   677
        class X implements TestInterfaceInheritanceA, TestInterfaceInheritanceB {
jtulach@9
   678
        }
jtulach@9
   679
        final X shared = new X ();
jtulach@9
   680
        
jglick@705
   681
        class P extends AbstractLookup.Pair<Object> {
jtulach@9
   682
            public int howLong;
jtulach@9
   683
            
jtulach@9
   684
            P (int b) {
jtulach@9
   685
                howLong = b;
jtulach@9
   686
            }
jtulach@9
   687
            
jtulach@9
   688
            protected boolean creatorOf (Object obj) {
jtulach@9
   689
                return obj == shared;
jtulach@9
   690
            }
jtulach@9
   691
            
jtulach@9
   692
            public String getDisplayName () {
jtulach@9
   693
                return "";
jtulach@9
   694
            }
jtulach@9
   695
            
jtulach@9
   696
            public String getId () {
jtulach@9
   697
                return "";
jtulach@9
   698
            }
jtulach@9
   699
            
jtulach@9
   700
            public Object getInstance () {
jtulach@9
   701
                return shared;
jtulach@9
   702
            }
jtulach@9
   703
            
jglick@705
   704
            public Class<?> getType() {
jglick@705
   705
                return howLong == 0 ? TestInterfaceInheritanceB.class : TestInterfaceInheritanceA.class;
jtulach@9
   706
            }
jtulach@9
   707
            
jglick@705
   708
            protected boolean instanceOf(Class<?> c) {
jtulach@9
   709
                return c.isAssignableFrom (getType ());
jtulach@9
   710
            }
jtulach@9
   711
    
jglick@705
   712
            public @Override int hashCode() {
jtulach@9
   713
                return getClass ().hashCode ();
jtulach@9
   714
            }    
jtulach@9
   715
jglick@705
   716
            public @Override boolean equals(Object obj) {
jtulach@9
   717
                if (obj instanceof P) {
jtulach@9
   718
                    P p = (P)obj;
jtulach@9
   719
                    if (this.howLong > 0) {
jtulach@9
   720
                        this.howLong--;
jtulach@9
   721
                        return false;
jtulach@9
   722
                    }
jtulach@9
   723
                    if (p.howLong > 0) {
jtulach@9
   724
                        p.howLong--;
jtulach@9
   725
                        return false;
jtulach@9
   726
                    }
jtulach@9
   727
                    return getClass ().equals (p.getClass ());
jtulach@9
   728
                }
jtulach@9
   729
                return false;
jtulach@9
   730
            }
jtulach@9
   731
        }
jtulach@9
   732
        
jtulach@9
   733
        // to create the right structure in the lookup
jglick@705
   734
        Lookup.Result<?> a = lookup.lookupResult(TestInterfaceInheritanceA.class);
jglick@705
   735
        Lookup.Result<?> b = lookup.lookupResult(TestInterfaceInheritanceB.class);
jtulach@9
   736
        
jtulach@9
   737
        P lng1 = new P (0);
jtulach@9
   738
        ic.addPair (lng1);
jtulach@9
   739
        
jtulach@9
   740
        assertEquals ("One in a", 1, a.allItems ().size ());
jtulach@9
   741
        assertEquals ("One in b", 1, b.allItems ().size ());
jtulach@9
   742
jtulach@9
   743
        P lng2 = new P (1);
jtulach@9
   744
        
jtulach@9
   745
jtulach@9
   746
        /* Following call used to generate this exception:
jtulach@9
   747
    java.lang.IllegalStateException: Duplicate pair in treePair1:  pair2:  index1: 0 index2: 0 item1: org.openide.util.lookup.AbstractLookupBaseHid$1X@1a457b6 item2: org.openide.util.lookup.AbstractLookupBaseHid$1X@1a457b6 id1: 7a78d3 id2: 929206
jtulach@9
   748
	at org.openide.util.lookup.ALPairComparator.compare(ALPairComparator.java:52)
jtulach@9
   749
	at java.util.Arrays.mergeSort(Arrays.java:1284)
jtulach@9
   750
	at java.util.Arrays.sort(Arrays.java:1223)
jtulach@9
   751
	at java.util.Collections.sort(Collections.java:159)
jtulach@9
   752
	at org.openide.util.lookup.InheritanceTree.retainAllInterface(InheritanceTree.java:753)
jtulach@9
   753
	at org.openide.util.lookup.InheritanceTree.retainAll(InheritanceTree.java:183)
jtulach@9
   754
	at org.openide.util.lookup.DelegatingStorage.retainAll(DelegatingStorage.java:83)
jtulach@9
   755
	at org.openide.util.lookup.AbstractLookup.setPairsAndCollectListeners(AbstractLookup.java:238)
jtulach@9
   756
	at org.openide.util.lookup.AbstractLookup.setPairs(AbstractLookup.java:203)
jtulach@9
   757
	at org.openide.util.lookup.AbstractLookup$Content.setPairs(AbstractLookup.java:885)
jtulach@9
   758
	at org.openide.util.lookup.AbstractLookupBaseHid.testAbsolutelyCrazyWayToSimulateIssue48590ByChangingTheBehaviourOfEqualOnTheFly(AbstractLookupBaseHid.java:696)
jtulach@9
   759
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
jtulach@9
   760
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
jtulach@9
   761
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
jtulach@9
   762
	at org.netbeans.junit.NbTestCase.run(NbTestCase.java:119)
jtulach@9
   763
    */  
jtulach@9
   764
        ic.setPairs (Collections.singleton (lng2));
jtulach@9
   765
jtulach@9
   766
        
jtulach@9
   767
    }
jtulach@9
   768
    
jtulach@9
   769
    public void testInstancesArePreservedFoundWhenFixing48590 () throws Exception {
jtulach@9
   770
        class X implements Runnable, Serializable {
jtulach@9
   771
            public void run () {
jtulach@9
   772
                
jtulach@9
   773
            }
jtulach@9
   774
            
jglick@705
   775
            public void assertOnlyMe (String msg, Lookup.Result<?> res) {
jglick@705
   776
                Collection<?> col = res.allInstances();
jtulach@9
   777
                assertEquals (msg + " just one", 1, col.size ());
jtulach@9
   778
                assertSame (msg + " and it is me", this, col.iterator ().next ());
jtulach@9
   779
            }
jtulach@9
   780
        }
jtulach@9
   781
        
jglick@705
   782
        Lookup.Result<?> runnable = lookup.lookupResult(Runnable.class);
jglick@705
   783
        Lookup.Result<?> serial = lookup.lookupResult(Serializable.class);
jtulach@9
   784
        
jtulach@9
   785
        
jtulach@9
   786
        X x = new X ();
jtulach@9
   787
        ic.add (x);
jtulach@9
   788
        
jtulach@9
   789
        
jtulach@9
   790
        x.assertOnlyMe ("x implements it (1)", runnable);
jtulach@9
   791
        x.assertOnlyMe ("x implements it (2)", serial);
jtulach@9
   792
        
jtulach@9
   793
        ic.set (Collections.singleton (x), null);
jtulach@9
   794
        
jtulach@9
   795
        x.assertOnlyMe ("x implements it (3)", runnable);
jtulach@9
   796
        x.assertOnlyMe ("x implements it (4)", serial);
jtulach@9
   797
    }
jtulach@9
   798
    
jtulach@9
   799
    /** Testing lookup of inherited classes. */
jtulach@9
   800
    public void testInheritance() {
jtulach@9
   801
        class A {}
jtulach@9
   802
        class B extends A implements java.rmi.Remote {}
jtulach@9
   803
        class BB extends B {}
jtulach@9
   804
        class C extends A implements java.rmi.Remote {}
jtulach@9
   805
        class D extends A {}
jtulach@9
   806
        
jtulach@9
   807
        A[] types = {new B(), new BB(), new C(), new D()};
jtulach@9
   808
        
jtulach@9
   809
        for (int i = 0; i < types.length; i++) {
jtulach@9
   810
            ic.add(types[i]);
jtulach@9
   811
            if (lookup.lookup(types[i].getClass()) == null) {
jtulach@9
   812
                // should find an instance
jtulach@9
   813
                fail("Lookup (" + types[i].getClass().getName () + ") found nothing");
jtulach@9
   814
            }
jtulach@9
   815
        }
jtulach@9
   816
        
jtulach@9
   817
        int size1, size2;
jtulach@9
   818
        
jtulach@9
   819
        //interface query
jglick@705
   820
        size1 = lookup.lookupAll(java.rmi.Remote.class).size();
jtulach@9
   821
        size2 = countInstances(types, java.rmi.Remote.class);
jtulach@9
   822
        
jtulach@9
   823
        if (size1 != size2) fail("Lookup with interface failed: " + size1 + " != " + size2);
jtulach@9
   824
        
jtulach@9
   825
        // superclass query
jglick@705
   826
        size1 = lookup.lookupAll(A.class).size();
jtulach@9
   827
        size2 = countInstances(types, A.class);
jtulach@9
   828
        
jtulach@9
   829
        if (size1 != size2) fail("Lookup with superclass failed: " + size1 + " != " + size2);
jtulach@9
   830
    }
jtulach@9
   831
    
jtulach@9
   832
    /** Test interface inheritance.
jtulach@9
   833
     */
jtulach@9
   834
    public void testInterfaceInheritance() {
jglick@705
   835
        TestInterfaceInheritanceA[] types = {
jglick@705
   836
            new TestInterfaceInheritanceB() {},
jglick@705
   837
            new TestInterfaceInheritanceBB() {},
jglick@705
   838
            new TestInterfaceInheritanceC() {},
jglick@705
   839
            new TestInterfaceInheritanceD() {}
jtulach@9
   840
        };
jtulach@9
   841
        
jtulach@9
   842
        for (int i = 0; i < types.length; i++) {
jtulach@9
   843
            ic.add(types[i]);
jtulach@9
   844
            if (lookup.lookup(types[i].getClass()) == null) {
jtulach@9
   845
                // should find an instance
jtulach@9
   846
                fail("Lookup (" + types[i].getClass().getName () + ") found nothing");
jtulach@9
   847
            }
jtulach@9
   848
        }
jtulach@9
   849
        
jtulach@9
   850
        int size1, size2;
jtulach@9
   851
        
jtulach@9
   852
        //interface query
jtulach@9
   853
        LL l = new LL ();
jglick@705
   854
        Lookup.Result<?> res = lookup.lookupResult(java.rmi.Remote.class);
jtulach@9
   855
        l.source = res;
jtulach@9
   856
        size1 = res.allInstances().size();
jtulach@9
   857
        size2 = countInstances(types, java.rmi.Remote.class);
jtulach@9
   858
        
jtulach@9
   859
        if (size1 != size2) fail("Lookup with interface failed: " + size1 + " != " + size2);
jtulach@9
   860
        
jtulach@9
   861
        // superclass query
jglick@705
   862
        size1 = lookup.lookupAll(TestInterfaceInheritanceA.class).size();
jglick@705
   863
        size2 = countInstances(types, TestInterfaceInheritanceA.class);
jtulach@9
   864
        
jtulach@9
   865
        if (size1 != size2) fail("Lookup with superclass failed: " + size1 + " != " + size2);
jtulach@9
   866
        
jtulach@9
   867
        res.addLookupListener (l);
jtulach@9
   868
        ic.remove (types[0]);
jtulach@9
   869
        
jtulach@9
   870
        if (l.getCount () != 1) {
jtulach@9
   871
            fail ("No notification that a Remote is removed");
jtulach@9
   872
        }
jtulach@9
   873
    }
jtulach@9
   874
    
jtulach@9
   875
    /** Checks whether the AbstractLookup is guarded against modifications
jtulach@9
   876
     * while doing some kind of modification.
jtulach@9
   877
     */
jtulach@9
   878
    public void testModificationArePreventedWhenDoingModifications () throws Exception {
jtulach@9
   879
        BrokenPair broken = new BrokenPair (true, false);
jtulach@9
   880
        ic.addPair (broken);
jtulach@9
   881
        
jglick@705
   882
        Lookup.Template<BrokenPair> templ = new Lookup.Template<BrokenPair>(BrokenPair.class);
jglick@705
   883
        Lookup.Item<BrokenPair> item = lookup.lookupItem (templ);
jtulach@9
   884
        assertEquals ("Broken is found", broken, item);
jtulach@9
   885
    }
jtulach@9
   886
    
jtulach@9
   887
    public void testModificationArePreventedWhenDoingModificationsResult () throws Exception {
jtulach@9
   888
        BrokenPair broken = new BrokenPair (false, true);
jtulach@9
   889
        ic.addPair (broken);
jtulach@9
   890
        
jglick@705
   891
        Lookup.Template<BrokenPair> templ = new Lookup.Template<BrokenPair>(BrokenPair.class);
jtulach@9
   892
        
jglick@705
   893
        Collection<? extends BrokenPair> c = lookup.lookup (templ).allInstances();
jtulach@9
   894
        assertEquals ("One item", 1, c.size ());
jtulach@9
   895
        assertEquals ("Broken is found again", broken, c.iterator().next ());
jtulach@9
   896
    }
jtulach@9
   897
    
jtulach@9
   898
    public void testModificationArePreventedWhenDoingModificationsItemAndResult () throws Exception {
jtulach@9
   899
        BrokenPair broken = new BrokenPair (false, true);
jtulach@9
   900
        ic.addPair (broken);
jtulach@9
   901
        
jglick@705
   902
        Lookup.Template<BrokenPair> templ = new Lookup.Template<BrokenPair>(BrokenPair.class);
jglick@705
   903
        Lookup.Item<BrokenPair> item = lookup.lookupItem (templ);
jtulach@9
   904
        assertEquals ("Broken is found", broken, item);
jtulach@9
   905
        
jglick@705
   906
        Collection<? extends BrokenPair> c = lookup.lookup(templ).allInstances();
jtulach@9
   907
        assertEquals ("One item", 1, c.size ());
jtulach@9
   908
        assertEquals ("Broken is found again", broken, c.iterator().next ());
jtulach@9
   909
    }
jtulach@9
   910
jtulach@9
   911
    public void testModificationArePreventedWhenDoingModificationsResultAndItem () throws Exception {
jtulach@9
   912
        BrokenPair broken = new BrokenPair (false, true);
jtulach@9
   913
        ic.addPair (broken);
jtulach@9
   914
        
jglick@705
   915
        Lookup.Template<BrokenPair> templ = new Lookup.Template<BrokenPair>(BrokenPair.class);
jglick@705
   916
        Collection<? extends BrokenPair> c = lookup.lookup(templ).allInstances();
jtulach@9
   917
        assertEquals ("One item", 1, c.size ());
jtulach@9
   918
        assertEquals ("Broken is found again", broken, c.iterator().next ());
jtulach@9
   919
        
jtulach@9
   920
        Object item = lookup.lookupItem (templ);
jtulach@9
   921
        assertEquals ("Broken is found", broken, item);
jtulach@9
   922
    }
jtulach@9
   923
    
jtulach@9
   924
    public void testAddALotOfPairsIntoTheLookupOneByOne () throws Exception {
jglick@705
   925
        Lookup.Result<Integer> res = lookup.lookupResult(Integer.class);
jtulach@9
   926
        for (int i = 0; i < 1000; i++) {
jglick@705
   927
            ic.add(i);
jtulach@9
   928
        }
jtulach@9
   929
        assertEquals (
jtulach@9
   930
            "there is the right count", 
jtulach@9
   931
            1000, 
jtulach@9
   932
            res.allItems().size ()
jtulach@9
   933
        );
jtulach@9
   934
    }
jtulach@9
   935
    
jtulach@9
   936
    public void testAddALotOfPairsIntoTheLookup () throws Exception {
jglick@705
   937
        List<Integer> arr = new ArrayList<Integer>();
jtulach@9
   938
        for (int i = 0; i < 1000; i++) {
jglick@705
   939
            arr.add(i);
jtulach@9
   940
        }
jtulach@9
   941
        ic.set (arr, null);
jtulach@9
   942
        
jtulach@9
   943
        assertEquals (
jtulach@9
   944
            "there is the right count", 
jtulach@9
   945
            1000, 
jglick@705
   946
            lookup.lookupResult(Integer.class).allItems().size()
jtulach@9
   947
        );
jtulach@9
   948
    }
jtulach@9
   949
jtulach@9
   950
    
jtulach@9
   951
    public void testDoubleAddIssue35274 () throws Exception {
jglick@705
   952
        class P extends AbstractLookup.Pair<Object> {
jtulach@9
   953
            protected boolean creatorOf(Object obj) { return false; }
jtulach@9
   954
            public String getDisplayName() { return ""; }
jtulach@9
   955
            public String getId() { return ""; }
jtulach@9
   956
            public Object getInstance() { return null; }
jglick@705
   957
            public Class<?> getType() { return Object.class; }
jglick@705
   958
            protected boolean instanceOf(Class<?> c) { return c.isAssignableFrom(getType ()); }
jglick@705
   959
            public @Override int hashCode() {return getClass().hashCode();}
jglick@705
   960
            public @Override boolean equals(Object obj) {return getClass() == obj.getClass();}
jtulach@9
   961
        }
jtulach@9
   962
        
jtulach@9
   963
        P p = new P ();
jtulach@9
   964
        
jtulach@9
   965
        ic.addPair (p);
jtulach@9
   966
        ic.addPair (p);
jtulach@9
   967
        
jglick@705
   968
        Lookup.Result<Object> result = lookup.lookupResult(Object.class);
jtulach@9
   969
        Collection res = result.allItems ();
jtulach@9
   970
        assertEquals ("One item there", 1, res.size ());
jtulach@9
   971
        assertTrue ("It is the p", p == res.iterator ().next ());
jtulach@9
   972
        
jtulach@9
   973
        P p2 = new P ();
jtulach@9
   974
        ic.addPair (p2);
jtulach@9
   975
        
jglick@705
   976
        Reference<?> ref = new WeakReference<Object>(result);
jtulach@9
   977
        result = null;
jtulach@9
   978
        assertGC ("The result can disappear", ref);
jtulach@9
   979
        
jtulach@9
   980
        impl.clearCaches ();
jtulach@9
   981
        
jglick@705
   982
        result = lookup.lookupResult(Object.class);
jtulach@9
   983
        res = result.allItems ();
jtulach@9
   984
        assertEquals ("One item is still there", 1, res.size ());
jtulach@9
   985
        assertTrue ("But the p2 replaced p", p2 == res.iterator ().next ());
jtulach@9
   986
        
jtulach@9
   987
    }
jtulach@9
   988
    
jtulach@9
   989
    /** Test for proper serialization.
jtulach@9
   990
     */
jtulach@9
   991
    public void testSerializationSupport () throws Exception {
jtulach@9
   992
        doSerializationSupport (1);
jtulach@9
   993
    }
jtulach@9
   994
    public void testDoubleSerializationSupport () throws Exception {
jtulach@9
   995
        doSerializationSupport (2);
jtulach@9
   996
    }
jtulach@9
   997
jtulach@9
   998
    private void doSerializationSupport (int count) throws Exception {
jtulach@9
   999
        if (lookup instanceof Serializable) {
jtulach@9
  1000
            ic.addPair (new SerialPair ("1"));
jtulach@9
  1001
            ic.addPair (new SerialPair ("2"));
jtulach@9
  1002
            ic.addPair (new SerialPair ("3"));
jtulach@9
  1003
jtulach@551
  1004
            Lookup l = (Lookup)reserialize(lookup);
jtulach@9
  1005
jtulach@9
  1006
            assertEquals ("Able to answer simple query", "1", l.lookup (String.class));
jtulach@9
  1007
jtulach@9
  1008
            assertEquals ("Three objects there", 3, l.lookup (new Lookup.Template (String.class)).allInstances().size ());
jtulach@9
  1009
jtulach@9
  1010
            while (count-- > 0) {
jtulach@551
  1011
                l = (Lookup)reserialize(l);
jtulach@9
  1012
            }
jtulach@9
  1013
jtulach@9
  1014
            assertEquals ("Able to answer simple query", "1", l.lookup (String.class));
jtulach@9
  1015
jtulach@9
  1016
            assertEquals ("Three objects there", 3, l.lookup (new Lookup.Template (String.class)).allInstances().size ());
jtulach@9
  1017
        }
jtulach@9
  1018
    }
jtulach@9
  1019
jtulach@9
  1020
    /** When a lookup with two different versions of the same class 
jtulach@9
  1021
     * get's serialized, the results may be very bad. 
jtulach@9
  1022
     */
jtulach@9
  1023
    public void testSerializationOfTwoClassesWithTheSameName () throws Exception {
jtulach@9
  1024
        if (lookup instanceof Serializable) {
jtulach@9
  1025
            doTwoSerializedClasses (false, false);
jtulach@9
  1026
        }
jtulach@9
  1027
    }
jtulach@9
  1028
    public void testSerializationOfTwoClassesWithTheSameNameButQueryBeforeSave () throws Exception {
jtulach@9
  1029
        if (lookup instanceof Serializable) {
jtulach@9
  1030
            doTwoSerializedClasses (true, false);
jtulach@9
  1031
        }
jtulach@9
  1032
    }
jtulach@9
  1033
    public void testSerializationOfTwoClassesWithTheSameNameWithBroken () throws Exception {
jtulach@9
  1034
        if (lookup instanceof Serializable) {
jtulach@9
  1035
            doTwoSerializedClasses (false, true);
jtulach@9
  1036
        }
jtulach@9
  1037
    }
jtulach@9
  1038
    public void testSerializationOfTwoClassesWithTheSameNameButQueryBeforeSaveWithBroken () throws Exception {
jtulach@9
  1039
        if (lookup instanceof Serializable) {
jtulach@9
  1040
            doTwoSerializedClasses (true, true);
jtulach@9
  1041
        }
jtulach@9
  1042
    }
jtulach@9
  1043
   
jtulach@9
  1044
    private void doTwoSerializedClasses (boolean queryBeforeSerialization, boolean useBroken) throws Exception {
jtulach@9
  1045
        ClassLoader loader = new CL ();
jtulach@9
  1046
        Class c = loader.loadClass (Garbage.class.getName ());
jtulach@9
  1047
jtulach@9
  1048
        // in case of InheritanceTree it creates a slot for class Garbage
jtulach@9
  1049
        lookup.lookup(c);
jtulach@9
  1050
jtulach@9
  1051
        // but creates new instance and adds it into the lookup
jtulach@9
  1052
        // without querying for it
jtulach@9
  1053
        loader = new CL ();
jtulach@9
  1054
        c = loader.loadClass (Garbage.class.getName ());
jtulach@9
  1055
jtulach@9
  1056
        Object theInstance = c.newInstance ();
jtulach@9
  1057
jtulach@9
  1058
        ic.addPair (new SerialPair (theInstance));
jtulach@9
  1059
jtulach@9
  1060
        Broken2Pair broken = null;
jtulach@9
  1061
        if (useBroken) {
jtulach@9
  1062
            broken = new Broken2Pair ();
jtulach@9
  1063
            ic.addPair (broken);
jtulach@9
  1064
            
jtulach@9
  1065
            assertNull (
jtulach@9
  1066
                "We need to create the slot for the List as " +
jtulach@9
  1067
                "the Broken2Pair will ask for it after deserialization", 
jtulach@9
  1068
                lookup.lookup (java.awt.List.class)
jtulach@9
  1069
            );
jtulach@9
  1070
        }
jtulach@9
  1071
jtulach@9
  1072
        if (queryBeforeSerialization) {
jtulach@9
  1073
            assertEquals ("Instance is found", theInstance, lookup.lookup (c));
jtulach@9
  1074
        }
jtulach@9
  1075
        
jtulach@9
  1076
        // replace the old lookup with new one
jtulach@551
  1077
        lookup = (Lookup)reserialize(lookup);
jtulach@9
  1078
        
jtulach@9
  1079
        Lookup.Result result = lookup.lookup (new Lookup.Template (Garbage.class));
jtulach@9
  1080
        assertEquals ("One item is the result", 1, result.allInstances ().size ());
jtulach@9
  1081
        Object r = result.allInstances ().iterator ().next ();
jtulach@9
  1082
        assertNotNull("A value is found", r);
jtulach@9
  1083
        assertEquals ("It is of the right class", Garbage.class, r.getClass());
jtulach@9
  1084
    }
jtulach@9
  1085
   
jtulach@9
  1086
    /** Test of reorder and item change which used to fail on interfaces.
jtulach@9
  1087
     */
jtulach@9
  1088
    public void testReoderingIssue13779 () throws Exception {
jtulach@9
  1089
        LinkedList arr = new LinkedList ();
jtulach@9
  1090
        
jtulach@9
  1091
        class R extends Exception implements Cloneable {
jtulach@9
  1092
        }
jtulach@9
  1093
        Object o1 = new R ();
jtulach@9
  1094
        Object o2 = new R ();
jtulach@9
  1095
        Object o3 = new R ();
jtulach@9
  1096
        
jtulach@9
  1097
        arr.add (o1);
jtulach@9
  1098
        arr.add (o2);
jtulach@9
  1099
        
jtulach@9
  1100
        ic.set (arr, null);
jtulach@9
  1101
        
jtulach@9
  1102
        Lookup.Result objectResult = lookup.lookup (new Lookup.Template (Exception.class));
jtulach@9
  1103
        Lookup.Result interfaceResult = lookup.lookup (new Lookup.Template (Cloneable.class));
jtulach@9
  1104
        objectResult.allItems ();
jtulach@9
  1105
        interfaceResult.allItems ();
jtulach@9
  1106
        
jtulach@9
  1107
        LL l1 = new LL (objectResult);
jtulach@9
  1108
        LL l2 = new LL (interfaceResult);
jtulach@9
  1109
        
jtulach@9
  1110
        objectResult.addLookupListener(l1);
jtulach@9
  1111
        interfaceResult.addLookupListener(l2);
jtulach@9
  1112
        
jtulach@9
  1113
        arr.addFirst (o3);
jtulach@9
  1114
        
jtulach@9
  1115
        ic.set (arr, null);
jtulach@9
  1116
        
jtulach@9
  1117
        assertEquals ("One change on objects", 1, l1.getCount ());
jtulach@9
  1118
        assertEquals ("One change on interfaces", 1, l2.getCount ());
jtulach@9
  1119
        
jtulach@9
  1120
        arr.addFirst (new Cloneable () { });
jtulach@9
  1121
        ic.set (arr, null);
jtulach@9
  1122
        
jtulach@9
  1123
        assertEquals ("No change on objects", 0, l1.getCount ());
jtulach@9
  1124
        assertEquals ("But one change on interfaces", 1, l2.getCount ());
jtulach@9
  1125
        
jtulach@9
  1126
    }
jtulach@9
  1127
    
jtulach@9
  1128
    public void testDeadlockBetweenProxyResultAndLookupIssue47772 () throws Exception {
jtulach@9
  1129
        final String myModule = "My Module";
jtulach@9
  1130
        ic.add (myModule);
jtulach@9
  1131
        
jtulach@9
  1132
        class MyProxy extends ProxyLookup {
jtulach@9
  1133
            public MyProxy () {
jtulach@9
  1134
                super (new Lookup[] { lookup });
jtulach@9
  1135
            }
jtulach@9
  1136
        }
jtulach@9
  1137
        final MyProxy my = new MyProxy ();
jtulach@9
  1138
        
jtulach@9
  1139
        final Lookup.Result allModules = my.lookup (new Lookup.Template (String.class));
jtulach@9
  1140
        
jtulach@9
  1141
        class PairThatNeedsInfoAboutModules extends AbstractLookup.Pair {
jtulach@9
  1142
            public String getDisplayName () {
jtulach@9
  1143
                return "Need a module";
jtulach@9
  1144
            }
jtulach@9
  1145
            public String getId () {
jtulach@9
  1146
                return getDisplayName ();
jtulach@9
  1147
            }
jtulach@9
  1148
            public Class getType () {
jtulach@9
  1149
                return Integer.class;
jtulach@9
  1150
            }
jtulach@9
  1151
            protected boolean instanceOf (Class c) {
jtulach@9
  1152
                if (c == Integer.class) {
jtulach@9
  1153
                    synchronized (this) {
jtulach@9
  1154
                        notifyAll ();
jtulach@9
  1155
                        try {
jtulach@9
  1156
                            wait (1000);
jtulach@9
  1157
                        } catch (InterruptedException ex) {
jtulach@9
  1158
                            fail (ex.getMessage ());
jtulach@9
  1159
                        }
jtulach@9
  1160
                    }
jtulach@9
  1161
                    java.util.Collection coll = allModules.allInstances ();
jtulach@9
  1162
                    assertEquals ("Size is 1", 1, coll.size ());
jtulach@9
  1163
                    assertEquals ("My module is there", myModule, coll.iterator ().next ());
jtulach@9
  1164
                }
jtulach@9
  1165
                return c.isAssignableFrom (Integer.class);
jtulach@9
  1166
            }
jtulach@9
  1167
            
jtulach@9
  1168
            public Object getInstance () {
jtulach@9
  1169
                return new Integer (10);
jtulach@9
  1170
            }
jtulach@9
  1171
            
jtulach@9
  1172
            protected boolean creatorOf (Object obj) {
jtulach@9
  1173
                return new Integer (10).equals (obj);
jtulach@9
  1174
            }
jtulach@9
  1175
        }
jtulach@9
  1176
        
jtulach@9
  1177
        PairThatNeedsInfoAboutModules pair = new PairThatNeedsInfoAboutModules ();
jtulach@9
  1178
        ic.addPair (pair);
jtulach@9
  1179
        
jtulach@9
  1180
        synchronized (pair) {
jtulach@9
  1181
            class BlockInInstanceOf implements Runnable {
jtulach@9
  1182
                public void run () {
jglick@705
  1183
                    Integer i = my.lookup(Integer.class);
jtulach@9
  1184
                    assertEquals (new Integer (10), i);
jtulach@9
  1185
                }
jtulach@9
  1186
            }
jtulach@9
  1187
            BlockInInstanceOf blk = new BlockInInstanceOf ();
jtulach@545
  1188
            Executors.newSingleThreadScheduledExecutor().schedule(blk, 0, TimeUnit.MICROSECONDS);
jtulach@9
  1189
            pair.wait ();
jtulach@9
  1190
        }
jtulach@9
  1191
        
jtulach@9
  1192
        java.util.Collection coll = allModules.allInstances ();
jtulach@9
  1193
        assertEquals ("Size is 1", 1, coll.size ());
jtulach@9
  1194
        assertEquals ("My module is there", myModule, coll.iterator ().next ());
jtulach@9
  1195
    }
jtulach@9
  1196
jtulach@9
  1197
    public void testAWayToGenerateProblem13779 () {
jtulach@9
  1198
        ic.add (new Integer (1));
jtulach@9
  1199
        ic.add (new Integer (2));
jtulach@9
  1200
        ic.add (new Integer (1));
jtulach@9
  1201
        ic.add (new Integer (2));
jtulach@9
  1202
        
jtulach@9
  1203
        Collection c = lookup.lookup (new Lookup.Template (Integer.class)).allInstances ();
jtulach@9
  1204
        assertEquals ("There are two objects", 2, c.size ());
jtulach@9
  1205
        
jtulach@9
  1206
    }
jtulach@9
  1207
    
jtulach@9
  1208
    /** Replacing items with different objects.
jtulach@9
  1209
     */
jtulach@9
  1210
    public void testReplacingObjectsDoesNotGenerateException () throws Exception {
jtulach@9
  1211
        LinkedList arr = new LinkedList ();
jtulach@9
  1212
        
jtulach@9
  1213
        class R extends Exception implements Cloneable {
jtulach@9
  1214
        }
jtulach@9
  1215
        arr.add (new R ());
jtulach@9
  1216
        arr.add (new R ());
jtulach@9
  1217
        
jtulach@9
  1218
        ic.set (arr, null);
jtulach@9
  1219
        
jtulach@9
  1220
        arr.clear();
jtulach@9
  1221
        
jtulach@9
  1222
        arr.add (new R ());
jtulach@9
  1223
        arr.add (new R ());
jtulach@9
  1224
        
jtulach@9
  1225
        ic.set (arr, null);
jtulach@9
  1226
    }
jtulach@9
  1227
jtulach@9
  1228
    public void testAfterDeserializationNoQueryIsPeformedOnAlreadyQueriedObjects() throws Exception {
jtulach@9
  1229
        if (! (lookup instanceof Serializable)) {
jtulach@9
  1230
            // well this test works only for serializable lookups
jtulach@9
  1231
            return;
jtulach@9
  1232
        }
jtulach@9
  1233
        
jtulach@9
  1234
        SerialPair my = new SerialPair ("no");
jtulach@9
  1235
        ic.addPair (my);
jtulach@9
  1236
        
jtulach@9
  1237
        Lookup.Result res = lookup.lookup (new Lookup.Template (String.class));
jtulach@9
  1238
        assertEquals ("One instance", 1, res.allInstances().size ());
jtulach@9
  1239
        assertEquals ("my.instanceOf called once", 1, my.countInstanceOf);
jtulach@9
  1240
        
jtulach@551
  1241
        Lookup serial = (Lookup)reserialize(lookup);
jtulach@9
  1242
        
jtulach@9
  1243
        Lookup.Result r2 = serial.lookup(new Lookup.Template(String.class));
jtulach@9
  1244
        
jtulach@9
  1245
        assertEquals ("One item", 1, r2.allItems ().size ());
jtulach@9
  1246
        Object one = r2.allItems().iterator().next ();
jtulach@9
  1247
        assertEquals ("The right class", SerialPair.class, one.getClass());
jtulach@9
  1248
        SerialPair p = (SerialPair)one;
jtulach@9
  1249
        
jtulach@9
  1250
        assertEquals ("p.instanceOf has not been queried", 0, p.countInstanceOf);
jtulach@9
  1251
    }
jtulach@9
  1252
    
jtulach@9
  1253
    /** Checks the iterator */
jglick@705
  1254
    private <T> void checkIterator(String msg, Iterator<? extends T> it1, List<? extends T> list) {
jtulach@9
  1255
        int cnt = 0;
jglick@705
  1256
        Iterator<? extends T> it2 = list.iterator();
jtulach@9
  1257
        while (it1.hasNext () && it2.hasNext ()) {
jglick@705
  1258
            T n1 = it1.next();
jglick@705
  1259
            T n2 = it2.next();
jtulach@9
  1260
            
jtulach@9
  1261
            if (n1 != n2) {
jtulach@9
  1262
                fail (msg + " iterator[" + cnt + "] = " + n1 + " but list[" + cnt + "] = " + n2);
jtulach@9
  1263
            }
jtulach@9
  1264
            
jtulach@9
  1265
            cnt++;
jtulach@9
  1266
        }
jtulach@9
  1267
        
jtulach@9
  1268
        if (it1.hasNext ()) {
jtulach@9
  1269
            fail ("Iterator has more elements than list");
jtulach@9
  1270
        }
jtulach@9
  1271
        
jtulach@9
  1272
        if (it2.hasNext ()) {
jtulach@9
  1273
            fail ("List has more elements than iterator");
jtulach@9
  1274
        }
jtulach@9
  1275
    }
jtulach@9
  1276
    
jtulach@85
  1277
    
jtulach@85
  1278
    public void testResultsAreUnmodifyableOrAtLeastTheyDoNotPropagateToCache() throws Exception {
jtulach@85
  1279
        String s = "Ahoj";
jtulach@85
  1280
        
jtulach@85
  1281
        ic.add(s);
jtulach@85
  1282
        
jtulach@85
  1283
        Lookup.Result res = lookup.lookup(new Template(String.class));
jtulach@85
  1284
        
jtulach@85
  1285
        for (int i = 1; i < 5; i++) {
jtulach@85
  1286
            Collection c1 = res.allInstances();
jtulach@85
  1287
            Collection c2 = res.allClasses();
jtulach@85
  1288
            Collection c3 = res.allItems();
jtulach@85
  1289
jtulach@85
  1290
            assertTrue(i + ": c1 has it", c1.contains(s));
jtulach@85
  1291
            assertTrue(i + ": c2 has it", c2.contains(s.getClass()));
jtulach@85
  1292
            assertEquals(i + ": c3 has one", 1, c3.size());
jtulach@85
  1293
            Lookup.Item item = (Lookup.Item) c3.iterator().next();
jtulach@85
  1294
            assertEquals(i + ": c3 has it", s, item.getInstance());
jtulach@85
  1295
jtulach@85
  1296
            try {
jtulach@85
  1297
                c1.remove(s);
jtulach@85
  1298
                assertEquals("No elements now", 0, c1.size());
jtulach@85
  1299
            } catch (UnsupportedOperationException ex) {
jtulach@85
  1300
                // ok, this need not be supported
jtulach@85
  1301
            }
jtulach@85
  1302
            try {
jtulach@85
  1303
                c2.remove(s.getClass());
jtulach@85
  1304
                assertEquals("No elements now", 0, c2.size());
jtulach@85
  1305
            } catch (UnsupportedOperationException ex) {
jtulach@85
  1306
                // ok, this need not be supported
jtulach@85
  1307
            }
jtulach@85
  1308
            try {
jtulach@85
  1309
                c3.remove(item);
jtulach@85
  1310
                assertEquals("No elements now", 0, c3.size());
jtulach@85
  1311
            } catch (UnsupportedOperationException ex) {
jtulach@85
  1312
                // ok, this need not be supported
jtulach@85
  1313
            }
jtulach@85
  1314
        }
jtulach@85
  1315
    }
jtulach@107
  1316
    
jtulach@107
  1317
    public void testSomeProblemWithDVBFrameworkSeemsToBeInLookup() {
jtulach@107
  1318
        for (int i = 0; i < 5; i++) {
jtulach@107
  1319
            ic.add(lookup);
jtulach@107
  1320
            assertEquals("Can be found", lookup, lookup.lookup(lookup.getClass()));
jtulach@107
  1321
            ic.set(Collections.EMPTY_LIST, null);
jtulach@107
  1322
        }        
jtulach@107
  1323
    }
jtulach@94
  1324
jtulach@94
  1325
    public void testListeningAndQueryingByTwoListenersInstances() {
jtulach@94
  1326
        doListeningAndQueryingByTwoListeners(0);
jtulach@94
  1327
    }
jtulach@94
  1328
    public void testListeningAndQueryingByTwoListenersClasses() {
jtulach@94
  1329
        doListeningAndQueryingByTwoListeners(1);        
jtulach@94
  1330
    }
jtulach@94
  1331
    public void testListeningAndQueryingByTwoListenersItems() {
jtulach@94
  1332
        doListeningAndQueryingByTwoListeners(2);
jtulach@94
  1333
    }
jtulach@85
  1334
    
jtulach@85
  1335
    
jtulach@94
  1336
    private void doListeningAndQueryingByTwoListeners(final int type) {
jtulach@94
  1337
        class L implements LookupListener {
jtulach@94
  1338
            Lookup.Result integer = lookup.lookup(new Template(Integer.class));
jtulach@94
  1339
            Lookup.Result number = lookup.lookup(new Template(Number.class));
jtulach@94
  1340
            Lookup.Result serial = lookup.lookup(new Template(Serializable.class));
jtulach@94
  1341
            
jtulach@94
  1342
            {
jtulach@94
  1343
                integer.addLookupListener(this);
jtulach@94
  1344
                number.addLookupListener(this);
jtulach@94
  1345
                serial.addLookupListener(this);
jtulach@94
  1346
            }
jtulach@94
  1347
            
jtulach@94
  1348
            int round;
jtulach@94
  1349
            
jtulach@94
  1350
            public void resultChanged(LookupEvent ev) {
jtulach@94
  1351
                Collection c1 = get(type, integer);
jtulach@94
  1352
                Collection c2 = get(type, number);
jtulach@94
  1353
                Collection c3 = get(type, serial);
jtulach@94
  1354
                
jtulach@94
  1355
                assertEquals("round " + round + " c1 vs. c2", c1, c2);
jtulach@94
  1356
                assertEquals("round " + round + " c1 vs. c3", c1, c3);
jtulach@94
  1357
                assertEquals("round " + round + " c2 vs. c3", c2, c3);
jtulach@94
  1358
                
jtulach@94
  1359
                round++;
jtulach@94
  1360
            }            
jtulach@94
  1361
jtulach@94
  1362
            private Collection get(int type, Lookup.Result res) {
jtulach@94
  1363
                Collection c;
jtulach@94
  1364
                switch(type) {
jtulach@94
  1365
                    case 0: c = res.allInstances(); break;
jtulach@94
  1366
                    case 1: c = res.allClasses(); break;
jtulach@94
  1367
                    case 2: c = res.allItems(); break;
jtulach@94
  1368
                    default: c = null; fail("Type: " + type); break;
jtulach@94
  1369
                }
jtulach@94
  1370
                
jtulach@94
  1371
                assertNotNull(c);
jtulach@94
  1372
                return new ArrayList(c);
jtulach@94
  1373
            }
jtulach@94
  1374
        }
jtulach@94
  1375
        
jtulach@94
  1376
        L listener = new L();
jtulach@94
  1377
        listener.resultChanged(null);
jtulach@94
  1378
        
jtulach@94
  1379
        for(int i = 0; i < 100; i++) {
jtulach@94
  1380
            ic.add(new Integer(i));
jtulach@94
  1381
        }
jtulach@94
  1382
        
jtulach@94
  1383
        assertEquals("3x100+1 checks", 301, listener.round);
jtulach@94
  1384
    }
jtulach@94
  1385
    
jtulach@85
  1386
    public void testChangeOfNodeDoesNotFireChangeInActionMap() {
jtulach@85
  1387
        ActionMap am = new ActionMap();
jtulach@85
  1388
        Lookup s = Lookups.singleton(am);
jtulach@91
  1389
        doChangeOfNodeDoesNotFireChangeInActionMap(am, s, false);
jtulach@91
  1390
    }
jtulach@91
  1391
    public void testChangeOfNodeDoesNotFireChangeInActionMapSimple() {
jtulach@91
  1392
        ActionMap am = new ActionMap();
jtulach@91
  1393
        Lookup s = Lookups.singleton(am);
jtulach@91
  1394
        doChangeOfNodeDoesNotFireChangeInActionMap(am, s, true);
jtulach@85
  1395
    }
jtulach@85
  1396
jtulach@91
  1397
    public void testChangeOfNodeDoesNotFireChangeInActionMapWithBeforeLookupSimple() {
jtulach@91
  1398
        doChangeOfNodeDoesNotFireChangeInActionMapWithBeforeLookup(true);
jtulach@91
  1399
    }
jtulach@91
  1400
    
jtulach@85
  1401
    public void testChangeOfNodeDoesNotFireChangeInActionMapWithBeforeLookup() {
jtulach@91
  1402
        doChangeOfNodeDoesNotFireChangeInActionMapWithBeforeLookup(false);
jtulach@91
  1403
    }
jtulach@91
  1404
    private void doChangeOfNodeDoesNotFireChangeInActionMapWithBeforeLookup(boolean wrapBySimple) {
jtulach@85
  1405
        final ActionMap am = new ActionMap();
jtulach@85
  1406
        
jtulach@85
  1407
        class Before extends AbstractLookup {
jtulach@85
  1408
            public InstanceContent ic;
jtulach@85
  1409
            public Before() {
jtulach@85
  1410
                this(new InstanceContent());
jtulach@85
  1411
            }
jtulach@85
  1412
            
jtulach@85
  1413
            private Before(InstanceContent ic) {
jtulach@85
  1414
                super(ic);
jtulach@85
  1415
                this.ic = ic;
jtulach@85
  1416
            }
jtulach@85
  1417
jglick@705
  1418
            protected @Override void beforeLookup(Template template) {
jtulach@85
  1419
                if (ic != null) {
jtulach@85
  1420
                    ic.add(am);
jtulach@85
  1421
                    ic = null;
jtulach@85
  1422
                }
jtulach@85
  1423
            }
jtulach@85
  1424
        }
jtulach@85
  1425
        
jtulach@85
  1426
        Before s = new Before();
jtulach@91
  1427
        doChangeOfNodeDoesNotFireChangeInActionMap(am, s, wrapBySimple);
jtulach@85
  1428
        
jtulach@85
  1429
        assertNull("beforeLookup called once", s.ic);
jtulach@85
  1430
    }
jtulach@85
  1431
    
jtulach@91
  1432
    private void doChangeOfNodeDoesNotFireChangeInActionMap(final ActionMap am, Lookup actionMapLookup, final boolean wrapBySimple) {
jtulach@85
  1433
        Lookup[] lookups = { lookup, actionMapLookup };
jtulach@91
  1434
        
jtulach@91
  1435
        class Provider implements Lookup.Provider {
jtulach@91
  1436
            ProxyLookup delegate;
jtulach@91
  1437
            Lookup query;
jtulach@91
  1438
            
jtulach@91
  1439
            public Provider(Lookup[] arr) {
jtulach@91
  1440
                if (wrapBySimple) {
jtulach@91
  1441
                    delegate = new ProxyLookup(arr);
jtulach@91
  1442
                    query = Lookups.proxy(this);
jtulach@91
  1443
                } else {
jtulach@91
  1444
                    query = delegate = new ProxyLookup(arr);
jtulach@91
  1445
                }
jtulach@91
  1446
            }
jtulach@91
  1447
            
jtulach@91
  1448
            public Lookup getLookup() {
jtulach@91
  1449
                return delegate;
jtulach@91
  1450
            }
jtulach@91
  1451
            
jglick@705
  1452
            public void setLookups(Lookup... arr) {
jtulach@91
  1453
                if (wrapBySimple) {
jtulach@91
  1454
                    delegate = new ProxyLookup(arr);                    
jtulach@91
  1455
                } else {
jtulach@91
  1456
                    delegate.setLookups(arr);
jtulach@91
  1457
                }
jtulach@91
  1458
            }
jtulach@91
  1459
        }
jtulach@91
  1460
        
jtulach@91
  1461
        Provider p = new Provider(lookups);
jtulach@91
  1462
        
jtulach@91
  1463
        Lookup.Result res = p.query.lookup(new Lookup.Template(ActionMap.class));
jtulach@85
  1464
        LL ll = new LL();
jtulach@85
  1465
        res.addLookupListener(ll);
jtulach@85
  1466
jtulach@85
  1467
        Collection c = res.allInstances();
jtulach@85
  1468
        assertFalse("Has next", c.isEmpty());
jtulach@85
  1469
        
jtulach@85
  1470
        ActionMap am1 = (ActionMap)c.iterator().next();
jtulach@85
  1471
        assertEquals("Am is there", am, am1);
jtulach@85
  1472
        
jtulach@85
  1473
        assertEquals("No change in first get", 0, ll.getCount());
jtulach@85
  1474
        
jtulach@85
  1475
        Object m1 = new InputMap();
jtulach@85
  1476
        Object m2 = new InputMap();
jtulach@85
  1477
        
jtulach@85
  1478
        ic.add(m1);
jtulach@85
  1479
        assertEquals("No change in ActionMap 1", 0, ll.getCount());
jtulach@85
  1480
        ic.set(Collections.singletonList(m2), null);
jtulach@85
  1481
        assertEquals("No change in ActionMap 2", 0, ll.getCount());
jtulach@85
  1482
        ic.add(m2);
jtulach@85
  1483
        assertEquals("No change in ActionMap 3", 0, ll.getCount());
jglick@705
  1484
        p.setLookups(lookup, actionMapLookup, Lookup.EMPTY);
jtulach@85
  1485
        assertEquals("No change in ActionMap 4", 0, ll.getCount());
jtulach@85
  1486
        
jglick@705
  1487
        ActionMap am2 = p.query.lookup(ActionMap.class);
jtulach@85
  1488
        assertEquals("Still the same action map", am, am2);
jtulach@85
  1489
        
jtulach@85
  1490
        
jtulach@85
  1491
        class Before extends AbstractLookup {
jtulach@85
  1492
            public InstanceContent ic;
jtulach@85
  1493
            public Before() {
jtulach@85
  1494
                this(new InstanceContent());
jtulach@85
  1495
            }
jtulach@85
  1496
            
jtulach@85
  1497
            private Before(InstanceContent ic) {
jtulach@85
  1498
                super(ic);
jtulach@85
  1499
                this.ic = ic;
jtulach@85
  1500
            }
jtulach@85
  1501
jglick@705
  1502
            protected @Override void beforeLookup(Template template) {
jtulach@85
  1503
                if (ic != null) {
jtulach@85
  1504
                    ic.add(am);
jtulach@85
  1505
                    ic = null;
jtulach@85
  1506
                }
jtulach@85
  1507
            }
jtulach@85
  1508
        }
jtulach@85
  1509
        
jtulach@85
  1510
        Before s = new Before();
jtulach@85
  1511
        
jtulach@85
  1512
        // adding different Before, but returning the same instance
jtulach@85
  1513
        // this happens with metaInfServices lookup often, moreover
jtulach@85
  1514
        // it adds the instance in beforeLookup, which confuses a lot
jtulach@91
  1515
        p.setLookups(new Lookup[]{ lookup, new Before() });
jtulach@85
  1516
        assertEquals("No change in ActionMap 5", 0, ll.getCount());
jtulach@85
  1517
        
jtulach@85
  1518
        
jtulach@85
  1519
    }
jtulach@199
  1520
jtulach@271
  1521
    public void testTasklistsCase() throws Exception {
jtulach@271
  1522
        ic.remove(new Object());
jtulach@271
  1523
    }
jtulach@271
  1524
    
jtulach@199
  1525
    
jtulach@199
  1526
jtulach@199
  1527
    public void testMultipleListeners() {
jtulach@199
  1528
        Object object = new ImplementationObject();
jtulach@199
  1529
        ic.add(object);
jtulach@199
  1530
        
jtulach@199
  1531
        Listener[] listeners = new Listener[4];
jtulach@199
  1532
        Lookup.Result result = lookup.lookup(new Lookup.Template(LookupObject.class));
jtulach@199
  1533
        for(int i = 0; i < listeners.length; ++i) {
jtulach@199
  1534
            listeners[i] = new Listener();
jtulach@199
  1535
            result.addLookupListener(listeners[i]);
jtulach@199
  1536
        }
jtulach@199
  1537
        // initialize listening
jtulach@199
  1538
        result.allItems();
jtulach@199
  1539
        
jtulach@199
  1540
        ic.remove(object);
jtulach@199
  1541
        
jtulach@199
  1542
        // Apparently, only odd-numbered listeners get called when there are multiple LookupListeners on a result
jtulach@199
  1543
        //for(int i = 0; i < listeners.length; ++i) {
jtulach@199
  1544
        //    System.out.println("Listener " + i + ": " + listeners[i].wasCalled());            
jtulach@199
  1545
        //}
jtulach@199
  1546
        for(int i = 0; i < listeners.length; ++i) {
jtulach@199
  1547
            assertTrue("Listener " + i + " called", listeners[i].wasCalled());
jtulach@199
  1548
        }
jtulach@199
  1549
    }
jtulach@551
  1550
jtulach@551
  1551
    static Object reserialize(Object o) throws Exception {
jtulach@551
  1552
        ByteArrayOutputStream os = new ByteArrayOutputStream();
jtulach@551
  1553
        ObjectOutputStream oos = new ObjectOutputStream(os);
jtulach@551
  1554
        oos.writeObject(o);
jtulach@551
  1555
        oos.close();
jtulach@551
  1556
jtulach@551
  1557
        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
jtulach@551
  1558
        ObjectInputStream ois = new ObjectInputStream(is);
jtulach@551
  1559
        return ois.readObject();
jtulach@551
  1560
    }
jtulach@199
  1561
    
jtulach@199
  1562
    private class Listener implements LookupListener {
jtulach@199
  1563
        private boolean listenerCalled = false;
jtulach@199
  1564
        
jtulach@199
  1565
        public void resultChanged(LookupEvent ev) {
jtulach@199
  1566
            listenerCalled = true;
jtulach@199
  1567
        }
jtulach@199
  1568
        
jtulach@199
  1569
        public boolean wasCalled() {
jtulach@199
  1570
            return listenerCalled;
jtulach@199
  1571
        }
jtulach@199
  1572
        
jtulach@199
  1573
        public void reset() {
jtulach@199
  1574
            listenerCalled = false;
jtulach@199
  1575
        }
jtulach@199
  1576
    }
jtulach@199
  1577
    
jtulach@199
  1578
    private interface LookupObject {}
jtulach@199
  1579
    private class ImplementationObject implements LookupObject {}
jtulach@199
  1580
    private class NullObject implements LookupObject {}
jtulach@199
  1581
    
jtulach@85
  1582
    
jtulach@113
  1583
    public void testReturnSomethingElseThenYouClaimYouWillReturn() {
jtulach@113
  1584
        class Liar extends AbstractLookup.Pair {
jtulach@113
  1585
            public Object obj;
jtulach@113
  1586
            
jtulach@113
  1587
            protected boolean instanceOf(Class c) {
jtulach@113
  1588
                return c.isAssignableFrom(String.class);
jtulach@113
  1589
            }
jtulach@113
  1590
jtulach@113
  1591
            protected boolean creatorOf(Object obj) {
jtulach@113
  1592
                return this.obj == obj;
jtulach@113
  1593
            }
jtulach@113
  1594
jtulach@113
  1595
            public Object getInstance() {
jtulach@113
  1596
                return this.obj;
jtulach@113
  1597
            }
jtulach@113
  1598
jtulach@113
  1599
            public Class getType() {
jtulach@113
  1600
                return String.class;
jtulach@113
  1601
            }
jtulach@113
  1602
jtulach@113
  1603
            public String getId() {
jtulach@113
  1604
                return String.class.getName();
jtulach@113
  1605
            }
jtulach@113
  1606
jtulach@113
  1607
            public String getDisplayName() {
jtulach@113
  1608
                return getId();
jtulach@113
  1609
            }
jtulach@113
  1610
        }
jtulach@113
  1611
        
jtulach@113
  1612
        
jtulach@113
  1613
        Liar l = new Liar();
jtulach@113
  1614
        l.obj = new Integer(5);
jtulach@113
  1615
        
jtulach@113
  1616
        this.ic.addPair(l);
jtulach@113
  1617
        
jtulach@113
  1618
        Collection c = lookup.lookup(new Lookup.Template(String.class)).allInstances();
jtulach@113
  1619
        assertTrue("It is empty: " + c, c.isEmpty());
jtulach@113
  1620
    }
jtulach@290
  1621
jtulach@568
  1622
    public void testCanProxyLookupHaveWrongResults() {
jtulach@568
  1623
        class L implements LookupListener {
jtulach@568
  1624
            ProxyLookup pl;
jtulach@568
  1625
            Lookup.Result<String> original;
jtulach@568
  1626
            Lookup.Result<String> wrapped;
jtulach@568
  1627
            boolean ok;
jtulach@568
  1628
jtulach@568
  1629
            public void test() {
jtulach@568
  1630
                pl = new ProxyLookup(lookup);
jtulach@568
  1631
                original = lookup.lookupResult(String.class);
jtulach@568
  1632
jtulach@568
  1633
                original.addLookupListener(this);
jtulach@568
  1634
jtulach@568
  1635
                wrapped = pl.lookupResult(String.class);
jtulach@568
  1636
jtulach@568
  1637
                assertEquals("Original empty", 0, original.allInstances().size());
jtulach@568
  1638
                assertEquals("Wrapped empty", 0, wrapped.allInstances().size());
jtulach@568
  1639
jtulach@568
  1640
                ic.add("Hello!");
jtulach@568
  1641
            }
jtulach@568
  1642
jtulach@568
  1643
            public void resultChanged(LookupEvent ev) {
jtulach@568
  1644
                ok = true;
jtulach@568
  1645
jtulach@568
  1646
                assertEquals("Original has hello", 1, original.allInstances().size());
jtulach@568
  1647
                assertEquals("Wrapped has hello", 1, wrapped.allInstances().size());
jtulach@568
  1648
            }
jtulach@568
  1649
jtulach@568
  1650
        }
jtulach@568
  1651
        L listener = new L();
jtulach@568
  1652
        listener.test();
jtulach@568
  1653
        assertTrue("Listener called", listener.ok);
jtulach@568
  1654
    }
jtulach@568
  1655
jtulach@598
  1656
    public void testObjectFromInstanceContentConverterDisappearsIfNotReferenced() {
jtulach@598
  1657
        Conv converter = new Conv("foo");
jtulach@598
  1658
        ic.add (converter, converter);
jtulach@598
  1659
        Lookup lkp = instanceLookup;
jtulach@598
  1660
        StringBuilder sb = lookup.lookup (StringBuilder.class);
jtulach@598
  1661
        assertNotNull (sb);
jtulach@598
  1662
        int hash = System.identityHashCode(sb);
jtulach@598
  1663
        assertEquals ("foo", sb.toString());
jtulach@598
  1664
        Reference<StringBuilder> r = new WeakReference<StringBuilder>(sb);
jtulach@598
  1665
        sb = null;
jtulach@598
  1666
        assertGC("Lookup held onto object", r);
jtulach@598
  1667
        sb = lookup.lookup (StringBuilder.class);
jtulach@598
  1668
        assertNotSame(hash, System.identityHashCode(sb));
jtulach@598
  1669
        r = new WeakReference<StringBuilder>(sb);
jtulach@598
  1670
        sb = null;
jtulach@598
  1671
        assertGC("Lookup held onto object", r);
jtulach@598
  1672
        ic.remove (converter, converter);
jtulach@598
  1673
        Reference <InstanceContent.Convertor> cref = new WeakReference<InstanceContent.Convertor>(converter);
jtulach@598
  1674
        converter = null;
jtulach@598
  1675
        assertGC("Converter still referenced", cref); 
jtulach@598
  1676
jtulach@598
  1677
        sb = lkp.lookup(StringBuilder.class);
jtulach@598
  1678
        assertNull ("Converter removed from lookup, but object it " +
jtulach@598
  1679
                "created still present:'" + sb +"'", sb);
jtulach@598
  1680
        converter = new Conv("bar");
jtulach@598
  1681
        ic.add (converter, converter);
jtulach@598
  1682
        assertNotNull (lkp.lookup(StringBuilder.class));
jtulach@598
  1683
        assertEquals ("bar", lkp.lookup(StringBuilder.class).toString());
jtulach@598
  1684
    }
jtulach@598
  1685
jtulach@598
  1686
    private static class Conv implements InstanceContent.Convertor<Conv, StringBuilder> {
jtulach@598
  1687
        private final String str;
jtulach@598
  1688
        private Conv (String str) {
jtulach@598
  1689
            this.str = str;
jtulach@598
  1690
        }
jtulach@598
  1691
jtulach@598
  1692
        public StringBuilder convert(Conv obj) {
jtulach@598
  1693
            return new StringBuilder (str);
jtulach@598
  1694
        }
jtulach@598
  1695
jtulach@598
  1696
        public Class<? extends StringBuilder> type(Conv obj) {
jtulach@598
  1697
            return StringBuilder.class;
jtulach@598
  1698
        }
jtulach@598
  1699
jtulach@598
  1700
        public String id(Conv obj) {
jtulach@598
  1701
            return "Foo";
jtulach@598
  1702
        }
jtulach@598
  1703
jtulach@598
  1704
        public String displayName(Conv obj) {
jtulach@598
  1705
            return "Foo";
jtulach@598
  1706
        }
jtulach@598
  1707
    } // end of Conv
jtulach@598
  1708
jtulach@290
  1709
    public void testCanGCResults() throws Exception {
jtulach@290
  1710
        class L implements LookupListener {
jtulach@290
  1711
            int cnt;
jtulach@290
  1712
            
jtulach@290
  1713
            public void resultChanged(LookupEvent ev) {
jtulach@290
  1714
                cnt++;
jtulach@290
  1715
            }
jtulach@290
  1716
            
jtulach@290
  1717
        }
jtulach@290
  1718
        L listener1 = new L();
jtulach@290
  1719
        L listener2 = new L();
jtulach@290
  1720
        
jtulach@290
  1721
        Lookup.Result<String> res1 = this.instanceLookup.lookupResult(String.class);
jtulach@290
  1722
        Lookup.Result<String> res2 = this.lookup.lookupResult(String.class);
jtulach@290
  1723
        
jtulach@290
  1724
        assertEquals("Empty1", 0, res1.allItems().size());
jtulach@290
  1725
        assertEquals("Empty2", 0, res2.allItems().size());
jtulach@290
  1726
        
jtulach@290
  1727
        res1.addLookupListener(listener1);
jtulach@290
  1728
        res2.addLookupListener(listener2);
jtulach@290
  1729
        
jtulach@290
  1730
        addInstances(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
jtulach@290
  1731
        this.ic.add("Ahoj");
jtulach@290
  1732
        
jtulach@290
  1733
        assertEquals("Change1", 1, listener1.cnt);
jtulach@290
  1734
        assertEquals("Change2", 1, listener2.cnt);
jtulach@290
  1735
        
jtulach@290
  1736
        assertEquals("Full1", 1, res1.allItems().size());
jtulach@290
  1737
        assertEquals("Full2", 1, res2.allItems().size());
jtulach@290
  1738
        
jtulach@290
  1739
        
jtulach@290
  1740
        Reference<Object> ref2 = new WeakReference<Object>(res2);
jtulach@290
  1741
        res2 = null;
jtulach@290
  1742
        assertGC("Result can disappear", ref2);
jtulach@290
  1743
    }
jtulach@113
  1744
    
jtulach@296
  1745
    void beforeActualTest(String n) {
jtulach@296
  1746
        if (n.equals("testEqualsIsNotCalledTooMuch")) {
jtulach@296
  1747
            CntPair.cnt = 0;
jtulach@560
  1748
            CntPair.hashCnt = 0;
jtulach@296
  1749
            CntPair.instances = 0;
jtulach@296
  1750
            int how = 1000;
jtulach@296
  1751
jtulach@296
  1752
            for(int i = 0; i < how; i++) {
jtulach@296
  1753
                this.ic.addPair(new CntPair("x" + i));
jtulach@296
  1754
            }
jtulach@296
  1755
jtulach@296
  1756
            assertEquals("No equals called", 0, CntPair.cnt);
jtulach@296
  1757
            assertEquals("1000 instances ", how, CntPair.instances);
jtulach@296
  1758
        }
jtulach@296
  1759
    }
jtulach@296
  1760
    
jtulach@296
  1761
    public void testEqualsIsNotCalledTooMuch() throws Exception {
jtulach@296
  1762
        // most of the work done in beforeActualTest
jtulach@296
  1763
jtulach@296
  1764
        // desirable: assertEquals("no comparitions", 0, CntPair.cnt);
jtulach@296
  1765
        // works for InheritanceTree, but not for ArrayStorage, but array
jtulach@296
  1766
        // storages are generally small
jtulach@296
  1767
        
jtulach@296
  1768
        if (CntPair.cnt > 12000) {
jtulach@296
  1769
            fail("Too much comparitions " + CntPair.cnt);
jtulach@296
  1770
        }
jtulach@296
  1771
        if (CntPair.hashCnt > 40000) {
jtulach@296
  1772
            fail("Too much hashes: " + CntPair.hashCnt);
jtulach@296
  1773
        }
jtulach@296
  1774
        
jtulach@296
  1775
        assertEquals("instaces is enough", 1000, CntPair.instances);
jtulach@296
  1776
    }
jtulach@296
  1777
    
jtulach@9
  1778
    /** Adds instances to the instance lookup.
jtulach@9
  1779
     */
jtulach@290
  1780
    private void addInstances (Object... instances) {
jtulach@9
  1781
        for (int i = 0; i < instances.length; i++) {
jtulach@9
  1782
            ic.add(instances[i]);
jtulach@9
  1783
        }
jtulach@9
  1784
    }
jtulach@9
  1785
    
jtulach@9
  1786
    /** Count instances of clazz in an array. */
jtulach@9
  1787
    private int countInstances (Object[] objs, Class clazz) {
jtulach@9
  1788
        int count = 0;
jtulach@9
  1789
        for (int i = 0; i < objs.length; i++) {
jtulach@9
  1790
            if (clazz.isInstance(objs[i])) count++;
jtulach@9
  1791
        }
jtulach@9
  1792
        return count;
jtulach@9
  1793
    }
jtulach@9
  1794
    
jtulach@9
  1795
    /** Counting listener */
jtulach@9
  1796
    protected static class LL implements LookupListener {
jtulach@9
  1797
        private int count = 0;
jtulach@9
  1798
        public Object source;
jtulach@401
  1799
        public Thread changesIn;
jtulach@9
  1800
        
jtulach@9
  1801
        public LL () {
jtulach@9
  1802
            this (null);
jtulach@9
  1803
        }
jtulach@9
  1804
        
jtulach@9
  1805
        public LL (Object source) {
jtulach@9
  1806
            this.source = source;
jtulach@9
  1807
        }
jtulach@9
  1808
        
jtulach@9
  1809
        public void resultChanged(LookupEvent ev) {
jtulach@401
  1810
            if (changesIn != null) {
jtulach@401
  1811
                assertEquals("Changes in the same thread", changesIn, Thread.currentThread());
jtulach@401
  1812
            } else {
jtulach@401
  1813
                changesIn = Thread.currentThread();
jtulach@401
  1814
            }
jtulach@9
  1815
            ++count;
jtulach@9
  1816
            if (source != null) {
jtulach@9
  1817
                assertSame ("Source is the same", source, ev.getSource ());
jtulach@9
  1818
//                assertSame ("Result is the same", source, ev.getResult ());
jtulach@9
  1819
            }
jtulach@9
  1820
        }
jtulach@9
  1821
jtulach@9
  1822
        public int getCount() {
jtulach@9
  1823
            int i = count;
jtulach@9
  1824
            count = 0;
jtulach@9
  1825
            return i;
jtulach@9
  1826
        }
jtulach@9
  1827
    };
jtulach@9
  1828
jtulach@9
  1829
    /** A set of interfaces for testInterfaceInheritance
jtulach@9
  1830
     */
jglick@705
  1831
    interface TestInterfaceInheritanceA {}
jglick@705
  1832
    interface TestInterfaceInheritanceB extends TestInterfaceInheritanceA, java.rmi.Remote {}
jglick@705
  1833
    interface TestInterfaceInheritanceBB extends TestInterfaceInheritanceB {}
jglick@705
  1834
    interface TestInterfaceInheritanceC extends TestInterfaceInheritanceA, java.rmi.Remote {}
jglick@705
  1835
    interface TestInterfaceInheritanceD extends TestInterfaceInheritanceA {}
jtulach@9
  1836
    
jtulach@9
  1837
    /** A special class for garbage test */
jtulach@9
  1838
    public static final class Garbage extends Object implements Serializable {
jtulach@9
  1839
        static final long serialVersionUID = 435340912534L;
jtulach@9
  1840
    }
jtulach@9
  1841
    
jtulach@9
  1842
jtulach@9
  1843
    /* A classloader that can load one class in a special way */
jtulach@9
  1844
    private static class CL extends ClassLoader {
jtulach@9
  1845
        public CL () {
jtulach@9
  1846
            super (null);
jtulach@9
  1847
        }
jtulach@9
  1848
jglick@705
  1849
        public @Override Class findClass(String name) throws ClassNotFoundException {
jtulach@9
  1850
            if (name.equals (Garbage.class.getName ())) {
jtulach@9
  1851
                String n = name.replace ('.', '/');
jtulach@9
  1852
                java.io.InputStream is = getClass ().getResourceAsStream ("/" + n + ".class");
jtulach@9
  1853
                byte[] arr = new byte[8096];
jtulach@9
  1854
                try {
jtulach@9
  1855
                    int cnt = is.read (arr);
jtulach@9
  1856
                    if (cnt == arr.length) {
jtulach@9
  1857
                        fail ("Buffer to load the class is not big enough");
jtulach@9
  1858
                    }
jtulach@9
  1859
jtulach@9
  1860
                    return defineClass (name, arr, 0, cnt);
jtulach@9
  1861
                } catch (java.io.IOException ex) {
jtulach@9
  1862
                        ex.printStackTrace();
jtulach@9
  1863
                        fail ("IO Exception");
jtulach@9
  1864
                        return null;
jtulach@9
  1865
                }
jtulach@9
  1866
            } else {
jtulach@9
  1867
                return null;
jtulach@9
  1868
            }
jtulach@9
  1869
        }
jtulach@9
  1870
jtulach@9
  1871
        /** Convert obj to other object. There is no need to implement
jtulach@9
  1872
         * cache mechanism. It is provided by AbstractLookup.Item.getInstance().
jtulach@9
  1873
         * Method should be called more than once because Lookup holds
jtulach@9
  1874
         * just weak reference.
jtulach@9
  1875
         */
jtulach@9
  1876
        public Object convert(Object obj) {
jtulach@9
  1877
            return null;
jtulach@9
  1878
        }
jtulach@9
  1879
jtulach@9
  1880
        /** Return type of converted object. */
jtulach@9
  1881
        public Class type(Object obj) {
jtulach@9
  1882
            try {
jtulach@9
  1883
                return loadClass (Garbage.class.getName ());
jtulach@9
  1884
            } catch (ClassNotFoundException ex) {
jtulach@9
  1885
                fail ("Class not found");
jtulach@9
  1886
                throw new InternalError ();
jtulach@9
  1887
            }
jtulach@9
  1888
        }
jtulach@9
  1889
    }
jtulach@296
  1890
    
jtulach@296
  1891
    private static final class CntPair extends AbstractLookup.Pair {
jtulach@296
  1892
        private static int instances;
jtulach@296
  1893
        private String txt;
jtulach@296
  1894
        
jtulach@296
  1895
        public CntPair(String txt) {
jtulach@296
  1896
            this.txt = txt;
jtulach@296
  1897
            instances++;
jtulach@296
  1898
        }
jtulach@296
  1899
jtulach@296
  1900
        public static int hashCnt;
jtulach@296
  1901
        @Override
jtulach@296
  1902
        public int hashCode() {
jtulach@296
  1903
            hashCnt++;
jtulach@296
  1904
            return txt.hashCode() + 3777;
jtulach@296
  1905
        }
jtulach@296
  1906
jtulach@296
  1907
        public static int cnt;
jtulach@296
  1908
        @Override
jtulach@296
  1909
        public boolean equals(Object obj) {
jtulach@296
  1910
            cnt++;
jtulach@296
  1911
            
jtulach@296
  1912
            if (obj == null) {
jtulach@296
  1913
                return false;
jtulach@296
  1914
            }
jtulach@296
  1915
            if (getClass() != obj.getClass()) {
jtulach@296
  1916
                return false;
jtulach@296
  1917
            }
jtulach@296
  1918
            final CntPair other = (CntPair) obj;
jtulach@296
  1919
            if (this.txt != other.txt && (this.txt == null || !this.txt.equals(other.txt))) {
jtulach@296
  1920
                return false;
jtulach@296
  1921
            }
jtulach@296
  1922
            return true;
jtulach@296
  1923
        }
jtulach@296
  1924
jtulach@296
  1925
        protected boolean instanceOf(Class c) {
jtulach@296
  1926
            return c.isAssignableFrom(String.class);
jtulach@296
  1927
        }
jtulach@296
  1928
jtulach@296
  1929
        protected boolean creatorOf(Object obj) {
jtulach@296
  1930
            return obj == txt;
jtulach@296
  1931
        }
jtulach@296
  1932
jtulach@296
  1933
        public Object getInstance() {
jtulach@296
  1934
            return txt;
jtulach@296
  1935
        }
jtulach@296
  1936
jtulach@296
  1937
        public Class getType() {
jtulach@296
  1938
            return String.class;
jtulach@296
  1939
        }
jtulach@296
  1940
jtulach@296
  1941
        public String getId() {
jtulach@296
  1942
            return txt;
jtulach@296
  1943
        }
jtulach@296
  1944
jtulach@296
  1945
        public String getDisplayName() {
jtulach@296
  1946
            return txt;
jtulach@296
  1947
        }
jtulach@296
  1948
        
jtulach@296
  1949
    }
jtulach@9
  1950
jtulach@9
  1951
    public static final class SerialPair extends AbstractLookup.Pair
jtulach@9
  1952
    implements java.io.Serializable {
jtulach@9
  1953
        static final long serialVersionUID = 54305834L;
jtulach@9
  1954
        private Object value;
jtulach@9
  1955
        public transient int countInstanceOf;
jtulach@9
  1956
        
jtulach@9
  1957
        public SerialPair (Object value) {
jtulach@9
  1958
            this.value = value;
jtulach@9
  1959
        }
jtulach@9
  1960
        
jtulach@9
  1961
        protected boolean creatorOf(Object obj) {
jtulach@9
  1962
            return obj == value;
jtulach@9
  1963
        }
jtulach@9
  1964
        
jtulach@9
  1965
        public String getDisplayName() {
jtulach@9
  1966
            return getId ();
jtulach@9
  1967
        }
jtulach@9
  1968
        
jtulach@9
  1969
        public String getId() {
jtulach@9
  1970
            return value.toString();
jtulach@9
  1971
        }
jtulach@9
  1972
        
jtulach@9
  1973
        public Object getInstance() {
jtulach@9
  1974
            return value;
jtulach@9
  1975
        }
jtulach@9
  1976
        
jtulach@9
  1977
        public Class getType() {
jtulach@9
  1978
            return value.getClass ();
jtulach@9
  1979
        }
jtulach@9
  1980
        
jtulach@9
  1981
        protected boolean instanceOf(Class c) {
jtulach@9
  1982
            countInstanceOf++;
jtulach@9
  1983
            return c.isInstance(value);
jtulach@9
  1984
        }
jtulach@9
  1985
    } // end of SerialPair
jtulach@9
  1986
    
jtulach@9
  1987
    private static class BrokenPair extends AbstractLookup.Pair {
jtulach@9
  1988
        private transient ThreadLocal IN = new ThreadLocal ();
jtulach@9
  1989
        private boolean checkModify;
jtulach@9
  1990
        private boolean checkQuery;
jtulach@9
  1991
        
jtulach@9
  1992
        public BrokenPair (boolean checkModify, boolean checkQuery) {
jtulach@9
  1993
            this.checkModify = checkModify;
jtulach@9
  1994
            this.checkQuery = checkQuery;
jtulach@9
  1995
        }
jtulach@9
  1996
        
jtulach@9
  1997
        protected boolean creatorOf(Object obj) { return this == obj; }
jtulach@9
  1998
        public String getDisplayName() { return "Broken"; }
jtulach@9
  1999
        public String getId() { return "broken"; }
jtulach@9
  2000
        public Object getInstance() { return this; }
jtulach@9
  2001
        public Class getType() { return getClass (); }
jtulach@9
  2002
        protected boolean instanceOf(Class c) { 
jtulach@9
  2003
            
jtulach@9
  2004
            if (checkQuery) {
jtulach@9
  2005
                if (IN.get () == null) {
jtulach@9
  2006
                    try {
jtulach@9
  2007
                        IN.set (this);
jtulach@9
  2008
                        // broken behaviour, tries to modify the lookup
jtulach@9
  2009
                        // queries have to survive
jtulach@9
  2010
jtulach@9
  2011
                        running.lookup.lookup (java.awt.List.class);
jtulach@9
  2012
jtulach@9
  2013
                        // 
jtulach@9
  2014
                        // creation of new result has to survive as well
jtulach@9
  2015
                        Lookup.Result myQuery = running.lookup.lookup (new Lookup.Template (java.awt.Button.class));
jtulach@9
  2016
                        Collection all = myQuery.allItems ();
jtulach@9
  2017
                    } finally {
jtulach@9
  2018
                        IN.set (null);
jtulach@9
  2019
                    }
jtulach@9
  2020
                }
jtulach@9
  2021
            }
jtulach@9
  2022
                
jtulach@9
  2023
jtulach@9
  2024
            if (checkModify) {
jtulach@9
  2025
                //
jtulach@9
  2026
                // modifications should fail
jtulach@9
  2027
                //
jtulach@9
  2028
jtulach@9
  2029
                try {
jtulach@9
  2030
                    running.ic.addPair (new SerialPair (""));
jtulach@9
  2031
                    fail ("Modification from a query should be prohibited");
jtulach@9
  2032
                } catch (IllegalStateException ex) {
jtulach@9
  2033
                }
jtulach@9
  2034
                
jtulach@9
  2035
                try {
jtulach@9
  2036
                    running.ic.removePair (this);
jtulach@9
  2037
                    fail ("This has to throw the exception");
jtulach@9
  2038
                } catch (IllegalStateException ex) {
jtulach@9
  2039
                }
jtulach@9
  2040
                try {
jtulach@9
  2041
                    running.ic.setPairs (Collections.EMPTY_SET);
jtulach@9
  2042
                    fail ("This has to throw the exception as well");
jtulach@9
  2043
                } catch (IllegalStateException ex) {
jtulach@9
  2044
                }
jtulach@9
  2045
            }
jtulach@9
  2046
            
jtulach@9
  2047
            return c.isAssignableFrom(getType ()); 
jtulach@9
  2048
        }
jtulach@9
  2049
    } // end of BrokenPair
jtulach@9
  2050
    
jtulach@9
  2051
    private static class Broken2Pair extends AbstractLookup.Pair {
jtulach@9
  2052
        static final long serialVersionUID = 4532587018501L;
jtulach@9
  2053
        public transient ThreadLocal IN;
jtulach@9
  2054
        
jtulach@9
  2055
        public Broken2Pair () {
jtulach@9
  2056
        }
jtulach@9
  2057
        
jtulach@9
  2058
        private void writeObject (java.io.ObjectOutputStream oos) throws java.io.IOException {
jtulach@9
  2059
        }
jtulach@9
  2060
        
jtulach@9
  2061
        private void readObject (java.io.ObjectInputStream ois) throws java.io.IOException, ClassNotFoundException {
jtulach@9
  2062
            IN = new ThreadLocal ();
jtulach@9
  2063
        }
jtulach@9
  2064
        
jtulach@9
  2065
        protected boolean creatorOf(Object obj) { return this == obj; }
jtulach@9
  2066
        public String getDisplayName() { return "Broken"; }
jtulach@9
  2067
        public String getId() { return "broken"; }
jtulach@9
  2068
        public Object getInstance() { return this; }
jtulach@9
  2069
        public Class getType() { return getClass (); }
jtulach@9
  2070
        protected boolean instanceOf(Class c) { 
jtulach@9
  2071
            
jtulach@9
  2072
            // behaviour gets broken only after deserialization
jtulach@9
  2073
            if (IN != null && IN.get () == null) {
jtulach@9
  2074
                try {
jtulach@9
  2075
                    IN.set (this);
jtulach@9
  2076
jtulach@9
  2077
                    // creation of new result has to survive as well
jtulach@9
  2078
                    Lookup.Result myQuery = running.lookup.lookup (new Lookup.Template (java.awt.List.class));
jtulach@9
  2079
                    Collection all = myQuery.allItems ();
jtulach@9
  2080
                } finally {
jtulach@9
  2081
                    IN.set (null);
jtulach@9
  2082
                }
jtulach@9
  2083
            }
jtulach@9
  2084
            
jtulach@9
  2085
            return c.isAssignableFrom(getType ()); 
jtulach@9
  2086
        }
jtulach@9
  2087
    } // end of Broken2Pair    
jtulach@9
  2088
}