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 204645
Collapse All | Expand All

(-)a/openide.explorer/src/org/netbeans/modules/openide/explorer/ExplorerActionsImpl.java (-1 / +1 lines)
Lines 91-97 Link Here
91
 */
91
 */
92
public final class ExplorerActionsImpl {
92
public final class ExplorerActionsImpl {
93
    /** background updater of actions */
93
    /** background updater of actions */
94
    private static final RequestProcessor RP = new RequestProcessor("Explorer Actions"); // NOI18N
94
    private static final RequestProcessor RP = new RequestProcessor("Explorer Actions", 1, false, false); // NOI18N
95
95
96
    private static final Logger LOG = Logger.getLogger(ExplorerActionsImpl.class.getName());
96
    private static final Logger LOG = Logger.getLogger(ExplorerActionsImpl.class.getName());
97
    
97
    
(-)a/openide.explorer/src/org/openide/explorer/DefaultEMLookup.java (-2 / +9 lines)
Lines 54-59 Link Here
54
import java.beans.*;
54
import java.beans.*;
55
55
56
import java.util.*;
56
import java.util.*;
57
import org.openide.util.RequestProcessor;
57
58
58
59
59
/**
60
/**
Lines 161-169 Link Here
161
        }
162
        }
162
    }
163
    }
163
164
164
    public void propertyChange(PropertyChangeEvent evt) {
165
    public void propertyChange(final PropertyChangeEvent evt) {
165
        if (ExplorerManager.PROP_SELECTED_NODES == evt.getPropertyName()) {
166
        if (ExplorerManager.PROP_SELECTED_NODES == evt.getPropertyName()) {
166
            updateLookups((Node[]) evt.getNewValue());
167
            RequestProcessor.getDefault().post(new Runnable() {
168
169
                @Override
170
                public void run() {
171
                    updateLookups((Node[]) evt.getNewValue());
172
                }
173
            });
167
        }
174
        }
168
    }
175
    }
169
176
(-)a/openide.loaders/src/org/openide/loaders/DataNode.java (+6 lines)
Lines 973-978 Link Here
973
973
974
        public void beforeLookup(Class<?> clazz) {
974
        public void beforeLookup(Class<?> clazz) {
975
            if (clazz.isAssignableFrom(FileObject.class)) {
975
            if (clazz.isAssignableFrom(FileObject.class)) {
976
                Exception e = new Exception();
977
                final int len = e.getStackTrace().length;
978
                System.err.println("depth: " + len);
979
                if (len > 300) {
980
                    System.err.println("too deep");
981
                }
976
                updateFilesInCookieSet(obj.files());
982
                updateFilesInCookieSet(obj.files());
977
            }
983
            }
978
        }
984
        }
(-)a/openide.util.lookup/src/org/openide/util/lookup/ProxyLookup.java (-7 / +120 lines)
Lines 46-55 Link Here
46
46
47
import java.lang.ref.Reference;
47
import java.lang.ref.Reference;
48
import java.lang.ref.WeakReference;
48
import java.lang.ref.WeakReference;
49
import java.lang.reflect.Array;
49
import java.util.ArrayList;
50
import java.util.ArrayList;
50
import java.util.Arrays;
51
import java.util.Arrays;
51
import java.util.Collection;
52
import java.util.Collection;
52
import java.util.Collections;
53
import java.util.Collections;
54
import java.util.EventListener;
53
import java.util.HashMap;
55
import java.util.HashMap;
54
import java.util.HashSet;
56
import java.util.HashSet;
55
import java.util.IdentityHashMap;
57
import java.util.IdentityHashMap;
Lines 560-566 Link Here
560
        /** When the result changes, fire the event.
562
        /** When the result changes, fire the event.
561
         */
563
         */
562
        public void resultChanged(LookupEvent ev) {
564
        public void resultChanged(LookupEvent ev) {
563
            collectFires(null);
565
            CoaleasingListener ca = installCoaleasingListener();
566
            try {
567
                collectFires(null);
568
            } finally {
569
                uninstallCoaleasingListener(ca);
570
            }
564
        }
571
        }
565
        
572
        
566
        protected void collectFires(Collection<Object> evAndListeners) {
573
        protected void collectFires(Collection<Object> evAndListeners) {
Lines 649-660 Link Here
649
            Lookup.Result<T>[] arr = initResults();
656
            Lookup.Result<T>[] arr = initResults();
650
657
651
            if (callBeforeOnWait) {
658
            if (callBeforeOnWait) {
652
                // invoke update on the results
659
                CoaleasingListener l = installCoaleasingListener();
653
                for (int i = 0; i < arr.length; i++) {
660
                try {
654
                    if (arr[i] instanceof WaitableResult) {
661
                    // invoke update on the results
655
                        WaitableResult w = (WaitableResult) arr[i];
662
                    for (int i = 0; i < arr.length; i++) {
656
                        w.beforeLookup(template);
663
                        if (arr[i] instanceof WaitableResult) {
664
                            WaitableResult w = (WaitableResult) arr[i];
665
                            w.beforeLookup(template);
666
                        }
657
                    }
667
                    }
668
                } finally {
669
                    uninstallCoaleasingListener(l);
658
                }
670
                }
659
            }
671
            }
660
672
Lines 700-706 Link Here
700
            }
712
            }
701
            
713
            
702
        }
714
        }
715
716
        private CoaleasingListener installCoaleasingListener() {
717
            synchronized (proxy()) {
718
                if (listeners == null) {
719
                    return null;
720
                }
721
                if (listeners instanceof CoaleasingListener) {
722
                    CoaleasingListener ca = (CoaleasingListener)listeners;
723
                    ca.changeUsage(1);
724
                    return ca;
725
                }
726
                
727
                final CoaleasingListener ca = new CoaleasingListener(listeners);
728
                listeners = ca;
729
                return ca;
730
            }
731
        }
732
        
733
        private void uninstallCoaleasingListener(CoaleasingListener l) {
734
            if (l == null) {
735
                return;
736
            }
737
            
738
            synchronized (proxy()) {
739
                CoaleasingListener ca = (CoaleasingListener) listeners;
740
                if (ca.changeUsage(-1)) {
741
                    listeners = l.delegate;
742
                }
743
            }
744
            l.deliver();
745
        }
746
        
703
    }
747
    }
748
    private static final class CoaleasingListener extends EventListenerList 
749
    implements LookupListener {
750
        final EventListenerList delegate;
751
        private volatile LookupEvent toDeliver;
752
        private int usageCount;
753
754
        public CoaleasingListener(EventListenerList delegate) {
755
            this.delegate = delegate;
756
            this.usageCount = 1;
757
        }
758
        
759
        final boolean changeUsage(int delta) {
760
            usageCount += delta;
761
            return usageCount == 0;
762
        }
763
764
        @Override
765
        public Object[] getListenerList() {
766
            return new Object[] { LookupListener.class, this };
767
        }
768
769
        @Override
770
        public <T extends EventListener> T[] getListeners(Class<T> t) {
771
            int n = LookupListener.class == t ? 1 : 0;
772
            T[] result = (T[])Array.newInstance(t, n); 
773
            if (n > 0) {
774
                result[0] = (T) this;
775
            }
776
            return result;
777
        }
778
779
        @Override
780
        public int getListenerCount() {
781
            return 1;
782
        }
783
784
        @Override
785
        public int getListenerCount(Class<?> t) {
786
            return LookupListener.class == t ? 1 : 0;
787
        }
788
789
        @Override
790
        public <T extends EventListener> void add(Class<T> t, T l) {
791
            delegate.add(t, l);
792
        }
793
794
        @Override
795
        public <T extends EventListener> void remove(Class<T> t, T l) {
796
            delegate.remove(t, l);
797
        }
798
799
        @Override
800
        public void resultChanged(LookupEvent ev) {
801
            if (toDeliver == null) {
802
                toDeliver = ev;
803
            }
804
            assert toDeliver.getSource() == ev.getSource();
805
        }
806
        
807
        final void deliver() {
808
            LookupEvent ev = toDeliver;
809
            if (ev != null) {
810
                for (LookupListener l : delegate.getListeners(LookupListener.class)) {
811
                    l.resultChanged(ev);
812
                }
813
            }
814
        }
815
    }
816
    
704
    private static final class WeakRef<T> extends WeakReference<R> implements Runnable {
817
    private static final class WeakRef<T> extends WeakReference<R> implements Runnable {
705
        final WeakResult<T> result;
818
        final WeakResult<T> result;
706
        final ProxyLookup proxy;
819
        final ProxyLookup proxy;
Lines 1124-1130 Link Here
1124
1237
1125
        @Override
1238
        @Override
1126
        public boolean isEmpty() {
1239
        public boolean isEmpty() {
1127
            return delegate().isEmpty();
1240
            return !iterator().hasNext();
1128
        }
1241
        }
1129
1242
1130
        @Override
1243
        @Override
(-)ae63769675a7 (+124 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
package org.openide.util.lookup;
43
44
import java.util.Collections;
45
import java.util.concurrent.atomic.AtomicInteger;
46
import java.util.regex.Matcher;
47
import java.util.regex.Pattern;
48
import org.netbeans.junit.NbTestCase;
49
import org.openide.util.Lookup;
50
import org.openide.util.Lookup.Result;
51
import org.openide.util.LookupEvent;
52
import org.openide.util.LookupListener;
53
54
/**
55
 *
56
 * @author Jaroslav Tulach <jtulach@netbeans.org>
57
 */
58
public class DeepProxyTest extends NbTestCase implements LookupListener {
59
    private ProxyLookup proxy;
60
    private int cnt;
61
    private int size;
62
    private AtomicInteger share;
63
64
    public DeepProxyTest(String name) {
65
        super(name);
66
    }
67
68
    @Override
69
    protected void setUp() throws Exception {
70
        Matcher m = Pattern.compile("[0-9]+").matcher(getName());
71
        assertTrue("There is a number in " + getName(), m.find());
72
        size = Integer.parseInt(m.group(0));
73
        assertTrue("Found", size > 0);
74
        share = new AtomicInteger(0);
75
        
76
        Lookup[] arr = new Lookup[size];
77
        for (int i = 0; i < size; i++) {
78
            arr[i] = new AddingLkp(share);
79
        }
80
        
81
        proxy = new ProxyLookup(arr);
82
    }
83
    
84
    
85
    
86
    public void testDeep1000() {
87
        Result<Number> res = proxy.lookupResult(Number.class);
88
        res.addLookupListener(this);
89
        assertEquals("Empty now", 0, res.allInstances().size());
90
        share.set(1);
91
        assertEquals("Right size", size, res.allInstances().size());
92
        assertEquals("one change is enough", 1, cnt);
93
    }
94
95
    @Override
96
    public void resultChanged(LookupEvent ev) {
97
        cnt++;
98
        if (new Exception().getStackTrace().length > 100) {
99
            fail("Too deep recursion!");
100
        }
101
    }
102
    
103
    private static final class AddingLkp extends AbstractLookup {
104
        private final AtomicInteger number;
105
        private final InstanceContent ic;
106
107
        public AddingLkp(AtomicInteger number) {
108
            this(number, new InstanceContent());
109
        }
110
        
111
        private AddingLkp(AtomicInteger number, InstanceContent ic) {
112
            super(ic);
113
            this.number = number;
114
            this.ic = ic;
115
        }
116
        
117
        @Override
118
        protected void beforeLookup(Template<?> template) {
119
            if (number.get() != 0 && template.getType() == Number.class) {
120
                ic.set(Collections.singleton(number), null);
121
            }
122
        }
123
    }
124
}

Return to bug 204645