This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 53058
Collapse All | Expand All

(-)openide/src/org/openide/util/lookup/ExcludingLookup.java (-42 / +95 lines)
Lines 53-59 Link Here
53
            // empty result
53
            // empty result
54
            return Lookup.EMPTY.lookup (template);
54
            return Lookup.EMPTY.lookup (template);
55
        }
55
        }
56
        return new R (delegate.lookup (template));
56
        return new R (template.getType (), delegate.lookup (template));
57
    }
57
    }
58
    
58
    
59
    public Object lookup(Class clazz) {
59
    public Object lookup(Class clazz) {
Lines 62-92 Link Here
62
        }
62
        }
63
        
63
        
64
        Object res = delegate.lookup (clazz);
64
        Object res = delegate.lookup (clazz);
65
        if (res == null) {
65
        if (isObjectAccessible (clazz, res, 0)) {
66
            return res;
67
        } else {
66
            return null;
68
            return null;
67
        }
69
        }
68
        
69
        Class[] arr = classes();
70
        for (int i = 0; i < arr.length; i++) {
71
            if (arr[i].isInstance (res)) {
72
                return null;
73
            }
74
        }
75
        return res;
76
    }
70
    }
77
71
78
    public org.openide.util.Lookup.Item lookupItem (org.openide.util.Lookup.Template template) {
72
    public org.openide.util.Lookup.Item lookupItem (org.openide.util.Lookup.Template template) {
73
        if (areSubclassesOfThisClassAlwaysExcluded (template.getType ())) {
74
            return null;
75
        }
79
        org.openide.util.Lookup.Item retValue = delegate.lookupItem (template);
76
        org.openide.util.Lookup.Item retValue = delegate.lookupItem (template);
80
        if (retValue == null) return null;
77
        if (isObjectAccessible (template.getType (), retValue, 2)) {
81
        
78
            return retValue;
82
        Class[] arr = classes();
79
        } else {
83
        for (int i = 0; i < arr.length; i++) {
80
            return null;
84
            if (acceptFilter (arr[i], retValue, 2)) {
85
                return null;
86
            }
87
        }
81
        }
88
        
89
        return retValue;
90
    }
82
    }
91
    
83
    
92
    /** @return true if the instance of class c shall never be returned from this lookup
84
    /** @return true if the instance of class c shall never be returned from this lookup
Lines 103-109 Link Here
103
    
95
    
104
    /** Returns the array of classes this lookup filters.
96
    /** Returns the array of classes this lookup filters.
105
     */
97
     */
106
    private Class[] classes () {
98
    final Class[] classes () {
107
        if (classes instanceof Class[]) {
99
        if (classes instanceof Class[]) {
108
            return (Class[])classes;
100
            return (Class[])classes;
109
        } else {
101
        } else {
Lines 111-125 Link Here
111
        }
103
        }
112
    }
104
    }
113
    
105
    
106
    /** Does a check whether two classes are accessible (in the super/sub class)
107
     * releation ship without walking thru any of the classes mentioned in the 
108
     * barrier.
109
     */
110
    private static boolean isAccessible (Class[] barriers, Class from, Class to) {
111
       if (to == null || !from.isAssignableFrom (to)) { 
112
           // no way to reach each other by walking up
113
           return false;
114
       }
115
       
116
       for (int i = 0; i < barriers.length; i++) {
117
           if (to == barriers[i]) {
118
               return false;
119
           }
120
       }
121
       
122
       if (from == to) {
123
           return true;
124
       }
125
       
126
       //
127
       // depth first search
128
       //
129
       
130
       if (isAccessible (barriers, from, to.getSuperclass ())) {
131
           return true;
132
       }
133
       
134
       Class[] interfaces = to.getInterfaces ();
135
       for (int i = 0; i < interfaces.length; i++) {
136
           if (isAccessible (barriers, from, interfaces[i])) {
137
               return true;
138
           }
139
       }
140
       
141
       return false;
142
    }
143
    
114
    /** based on type decides whether the class accepts or not anObject
144
    /** based on type decides whether the class accepts or not anObject
145
     * @param from the base type of the query
146
     * @param to depending on value of type either Object, Class or Item
147
     * @param type 0,1,2 for Object, Class or Item
148
     * @return true if we can access the to from from by walking around the bariers
115
     */
149
     */
116
    static boolean acceptFilter (Class filter, Object anObject, int type) {
150
    private final boolean isObjectAccessible (Class from, Object to, int type) {
151
        if (to == null) {
152
            return false;
153
        }
154
        return isObjectAccessible (classes(), from, to, type);
155
    }
156
    
157
    /** based on type decides whether the class accepts or not anObject
158
     * @param barriers classes to avoid when testing reachability
159
     * @param from the base type of the query
160
     * @param to depending on value of type either Object, Class or Item
161
     * @param type 0,1,2 for Object, Class or Item
162
     * @return true if we can access the to from from by walking around the bariers
163
     */
164
    static final boolean isObjectAccessible (Class[] barriers, Class from, Object to, int type) {
165
        if (to == null) {
166
            return false;
167
        }
168
        
117
        switch (type) {
169
        switch (type) {
118
            case 0: return filter.isInstance (anObject);
170
            case 0: return isAccessible (barriers, from, to.getClass ());
119
            case 1: return filter.isAssignableFrom ((Class)anObject);
171
            case 1: return isAccessible (barriers, from, (Class)to);
120
            case 2: {
172
            case 2: {
121
                Item item = (Item)anObject;
173
                Item item = (Item)to;
122
                return filter.isAssignableFrom (item.getType ());
174
                return isAccessible (barriers, from, item.getType ());
123
            }
175
            }
124
            default: throw new IllegalStateException ("Type: " + type);
176
            default: throw new IllegalStateException ("Type: " + type);
125
        }
177
        }
Lines 127-153 Link Here
127
179
128
    /** Filters collection accroding to set of given filters.
180
    /** Filters collection accroding to set of given filters.
129
     */
181
     */
130
    static java.util.Collection filter (Class[] arr, java.util.Collection c, int type) {
182
    final java.util.Collection filter (Class[] arr, Class from, java.util.Collection c, int type) {
131
        java.util.Collection ret = null;
183
        java.util.Collection ret = null;
132
184
185
        // optimistic strategy expecting we will not need to filter
133
        TWICE: for (;;) {
186
        TWICE: for (;;) {
134
            Iterator it = c.iterator ();
187
            Iterator it = c.iterator ();
135
            BIG: while (it.hasNext ()) {
188
            BIG: while (it.hasNext ()) {
136
                Object res = it.next ();
189
                Object res = it.next ();
137
                for (int i = 0; i < arr.length; i++) {
190
                if (!isObjectAccessible (arr, from, res, type)) {
138
                    if (acceptFilter (arr[i], res, type)) {
191
                    if (ret == null) {
139
                        if (ret == null) {
192
                        // we need to restart the scanning again 
140
                            // we need to restart the scanning again 
193
                        // as there is an active filter
141
                            // as there is an active filter
194
                        if (type == 1) {
142
                            if (type == 1) {
195
                            ret = new java.util.HashSet ();
143
                                ret = new java.util.HashSet ();
196
                        } else {
144
                            } else {
197
                            ret = new ArrayList (c.size ());
145
                                ret = new ArrayList (c.size ());
146
                            }
147
                            continue TWICE;
148
                        }
198
                        }
149
                        continue BIG;
199
                        continue TWICE;
150
                    }
200
                    }
201
                    continue BIG;
151
                }
202
                }
152
                if (ret != null) {
203
                if (ret != null) {
153
                    // if we are running the second round from TWICE
204
                    // if we are running the second round from TWICE
Lines 167-174 Link Here
167
    private final class R extends WaitableResult implements LookupListener {
218
    private final class R extends WaitableResult implements LookupListener {
168
        private Result result;
219
        private Result result;
169
        private Object listeners;
220
        private Object listeners;
221
        private Class from;
170
        
222
        
171
        R (Result delegate) {
223
        R (Class from, Result delegate) {
224
            this.from = from;
172
            this.result = delegate;
225
            this.result = delegate;
173
        }
226
        }
174
        
227
        
Lines 201-215 Link Here
201
        }    
254
        }    
202
        
255
        
203
        public java.util.Collection allInstances() {
256
        public java.util.Collection allInstances() {
204
            return filter (classes (), result.allInstances (), 0);
257
            return filter (classes (), from, result.allInstances (), 0);
205
        }
258
        }
206
        
259
        
207
        public Set allClasses () {
260
        public Set allClasses () {
208
            return (Set)filter (classes (), result.allClasses (), 1);
261
            return (Set)filter (classes (), from, result.allClasses (), 1);
209
        }
262
        }
210
        
263
        
211
        public Collection allItems () {
264
        public Collection allItems () {
212
            return filter (classes (), result.allItems (), 2);
265
            return filter (classes (), from, result.allItems (), 2);
213
        }
266
        }
214
267
215
        public void resultChanged (org.openide.util.LookupEvent ev) {
268
        public void resultChanged (org.openide.util.LookupEvent ev) {
(-)openide/test/unit/src/org/openide/util/lookup/ExcludingLookupTest.java (-3 / +54 lines)
Lines 51-58 Link Here
51
    public void testFunWithInterfaces () throws Exception {
51
    public void testFunWithInterfaces () throws Exception {
52
        doBasicFilteringTest (java.io.Serializable.class, Integer.class, 0);
52
        doBasicFilteringTest (java.io.Serializable.class, Integer.class, 0);
53
    }
53
    }
54
    public void testFunWithInterfaces2 () throws Exception {
54
    
55
        doBasicFilteringTest (java.io.Serializable.class, Object.class, 1);
55
    public void testWeCanGetInstanceOfSerializableEvenItIsExcludedIfWeAskForClassNotExtendingIt () throws Exception {
56
        Lookup lookup = Lookups.exclude (this.instanceLookup, new Class[] { java.io.Serializable.class });
57
        Lookup.Template t = new Lookup.Template (Object.class);
58
        Lookup.Result res = lookup.lookup (t);
59
        
60
        LL ll = new LL ();
61
        res.addLookupListener (ll);
62
        assertEquals ("Nothing is there", 0, res.allItems ().size ());
63
        
64
        Object inst = new Integer (3);
65
        ic.add (inst);
66
        
67
        assertEquals ("Not Filtered out", inst, lookup.lookup (Object.class));
68
        assertEquals ("Not Filtered out2", inst, lookup.lookupItem (t).getInstance ());
69
        assertEquals ("One is there - 2", 1, res.allItems ().size ());
70
        assertEquals ("One is there - 2a", 1, res.allInstances ().size ());
71
        assertEquals ("One is there - 2b", 1, res.allClasses ().size ());
72
        assertEquals ("Right # of events", 1, ll.getCount ());
73
        
74
        ic.remove (inst);
75
        assertEquals ("Filtered out3", null, lookup.lookupItem (t));
76
        assertEquals ("Nothing is there - 3", 0, res.allItems ().size ());
77
        assertEquals ("Nothing is there - 3a", 0, res.allInstances ().size ());
78
        assertEquals ("Nothing is there - 3b", 0, res.allClasses ().size ());
79
        assertEquals ("Of course it is not there", null, lookup.lookup (Object.class));
80
        assertEquals ("Right # of events", 1, ll.getCount ());
56
    }
81
    }
57
    
82
    
58
    public void testIntegersQueriedThruObject () throws Exception {
83
    public void testIntegersQueriedThruObject () throws Exception {
Lines 150-154 Link Here
150
        assertEquals ("Of course it is not there", null, lookup.lookup (theQuery));
175
        assertEquals ("Of course it is not there", null, lookup.lookup (theQuery));
151
        assertEquals ("Right # of events", numberOfExcpectedEventsAfterOneChange, ll.getCount ());
176
        assertEquals ("Right # of events", numberOfExcpectedEventsAfterOneChange, ll.getCount ());
152
    }
177
    }
153
    
178
179
    public void testTheBehaviourAsRequestedByDavidAndDescribedByJesse () throws Exception {
180
        class C implements Runnable, java.io.Serializable {
181
            public void run () {}
182
        }
183
        Object c = new C();
184
        Lookup l1 = Lookups.singleton(c);
185
        Lookup l2 = Lookups.exclude(l1, new Class[] {Runnable.class});
186
        assertNull(l2.lookup(Runnable.class));
187
        assertEquals(c, l2.lookup(java.io.Serializable.class));
188
    }
189
    
190
    public void testTheBehaviourAsRequestedByDavidAndDescribedByJesseWithUsageOfResult () throws Exception {
191
        class C implements Runnable, java.io.Serializable {
192
            public void run () {}
193
        }
194
        Object c = new C();
195
        Lookup l1 = Lookups.singleton(c);
196
        Lookup l2 = Lookups.exclude(l1, new Class[] {Runnable.class});
197
        
198
        Lookup.Result run = l2.lookup (new Lookup.Template (Runnable.class));
199
        Lookup.Result ser = l2.lookup (new Lookup.Template (java.io.Serializable.class));
200
        
201
        assertEquals ("Runnables filtered out", 0, run.allItems ().size ());
202
        assertEquals ("One serialiazble", 1, ser.allItems ().size ());
203
        assertEquals ("And it is c", c, ser.allInstances ().iterator ().next ());
204
    }
154
}
205
}

Return to bug 53058